import axios from 'axios'

export function mediaManager() {
    return {
        dragging: false,
        uploading: false,
        uploadProgress: 0,
        selectedMedia: null,
        previewItem: null,
        previewCaption: '',
        savingCaption: false,
        deletingId: null,
        items: [],
        loading: true,
        search: '',
        type: '',
        meta: { current_page: 1, last_page: 1, total: 0 },
        searchTimer: null,

        async init() {
            await this.fetch(1)
        },

        async fetch(page = 1) {
            this.loading = true
            try {
                const { data } = await axios.get('/admin/media', {
                    params: { search: this.search, type: this.type, page },
                    headers: { Accept: 'application/json' },
                })
                this.items = data.data
                this.meta = data.meta
            } finally {
                this.loading = false
            }
        },

        onSearch() {
            clearTimeout(this.searchTimer)
            this.searchTimer = setTimeout(() => this.fetch(1), 350)
        },

        handleDrop(event) {
            this.dragging = false
            this.uploadFiles(event.dataTransfer.files)
        },

        async uploadFiles(files) {
            if (!files.length) return
            this.uploading = true
            this.uploadProgress = 0

            const total = files.length
            let done = 0

            for (const file of files) {
                const form = new FormData()
                form.append('file', file)
                form.append('_token', document.querySelector('meta[name="csrf-token"]').content)

                try {
                    const { data } = await axios.post('/admin/media', form, {
                        headers: { Accept: 'application/json' },
                    })
                    this.items.unshift(data)
                    this.meta.total++
                } catch (e) {
                    console.error('Upload failed', e)
                }

                done++
                this.uploadProgress = Math.round((done / total) * 100)
            }

            this.uploading = false
        },

        async deleteMedia(id) {
            if (!confirm('Delete this file?')) return
            this.deletingId = id
            try {
                await axios.delete(`/admin/media/${id}`, {
                    headers: {
                        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
                        Accept: 'application/json',
                    },
                })
                this.items = this.items.filter(m => m.id !== id)
                this.meta.total--
                if (this.previewItem?.id === id) this.closePreview()
            } catch (e) {
                alert('Error deleting file.')
            } finally {
                this.deletingId = null
            }
        },

        openPreview(item) {
            this.previewItem = item
            this.previewCaption = item.caption ?? ''
        },

        closePreview() {
            this.previewItem = null
            this.previewCaption = ''
        },

        async saveCaption() {
            if (!this.previewItem) return
            this.savingCaption = true
            try {
                await axios.patch(`/admin/media/${this.previewItem.id}`, {
                    caption: this.previewCaption,
                    _token: document.querySelector('meta[name="csrf-token"]').content,
                }, {
                    headers: { Accept: 'application/json' },
                })
                const item = this.items.find(m => m.id === this.previewItem.id)
                if (item) item.caption = this.previewCaption
                this.previewItem = { ...this.previewItem, caption: this.previewCaption }
            } catch (e) {
                alert('Error saving caption.')
            } finally {
                this.savingCaption = false
            }
        },

        selectMedia(id, url, name) {
            this.selectedMedia = { id, url, name }
            this.$dispatch('media-selected', { id, url, name })
        },

        isImage(mimeType) {
            return mimeType && mimeType.startsWith('image/')
        },

        pages() {
            const pages = []
            for (let i = 1; i <= this.meta.last_page; i++) pages.push(i)
            return pages
        },
    }
}
