import Sortable from 'sortablejs'

const SECTION_DEFAULTS = {
    hero:        { title: 'Welcome', subtitle: 'Your subtitle here', button_text: 'Get Started', button_url: '#', image_url: '' },
    text:        { content: 'Your text content here' },
    image:       { src: '', alt: '', caption: '' },
    gallery:     { images: '' },
    columns:     { columns: '2', gap: '6', col_1_content: 'Column 1 text', col_2_content: 'Column 2 text' },
    cta:         { title: 'Call to Action', description: '', button_text: 'Click Here', button_url: '#', background: 'indigo' },
    testimonial: {},
    faq:         {},
}

function parseFaqItems(str) {
    try { return JSON.parse(str || '[]') } catch { return [] }
}

export function pageBuilderComponent(initialSections = []) {
    let _ctr = 0
    const _sections = initialSections.map(s => {
        const section = { ...s, _id: ++_ctr, _open: false, data: s.data ?? {}, full_width: s.full_width ?? false }
        if (s.type === 'faq') section._faqItems = parseFaqItems(s.data?.items)
        if (s.type === 'testimonial') section._testimonialItems = parseFaqItems(s.data?.items)
        if (s.type === 'gallery') {
            section._galleryImages = (s.data?.images || '')
                .split(',').map(u => u.trim()).filter(Boolean).map(url => ({ url, name: '' }))
        }
        return section
    })

    return {
        sections: _sections,
        availableSections: Object.keys(SECTION_DEFAULTS).map(type => ({
            type,
            label: type.charAt(0).toUpperCase() + type.slice(1),
        })),
        _counter: _ctr,

        // --- Picker state ---
        pickerOpen: false,
        pickerMode: 'hero', // 'hero' | 'gallery'
        pickerItems: [],
        pickerLoading: false,
        pickerSearch: '',
        pickerSearchTimer: null,
        pickerUploading: false,
        pickerPage: 1,
        pickerLastPage: 1,
        pickerSelected: null,       // hero mode: single item
        pickerSelectedIds: [],      // gallery mode: array of selected ids
        _pickerSectionIndex: null,
        _pickerField: 'image_url',  // which data field to set on confirm

        init() {
            this.$nextTick(() => {
                const el = this.$refs.sectionsContainer
                if (!el) return
                Sortable.create(el, {
                    handle: '[data-drag-handle]',
                    draggable: '.builder-section',
                    animation: 150,
                    ghostClass: 'opacity-40',
                    onEnd: (evt) => {
                        if (evt.oldIndex === evt.newIndex) return
                        const moved = this.sections.splice(evt.oldIndex, 1)[0]
                        this.sections.splice(evt.newIndex, 0, moved)
                    },
                })
            })
        },

        addSection(type) {
            const section = {
                _id: ++this._counter,
                _open: true,
                type,
                full_width: false,
                data: { ...SECTION_DEFAULTS[type] ?? {} },
            }
            if (type === 'faq') section._faqItems = [{ q: '', a: '' }]
            if (type === 'testimonial') section._testimonialItems = [{ quote: '', author: '', role: '' }]
            if (type === 'gallery') section._galleryImages = []
            this.sections.push(section)
        },

        removeSection(index) {
            this.sections.splice(index, 1)
        },

        toggleSection(index) {
            this.sections[index]._open = !this.sections[index]._open
        },

        addFaqItem(sectionIndex) {
            this.sections[sectionIndex]._faqItems.push({ q: '', a: '' })
        },

        removeFaqItem(sectionIndex, itemIndex) {
            this.sections[sectionIndex]._faqItems.splice(itemIndex, 1)
        },

        addTestimonialItem(sectionIndex) {
            this.sections[sectionIndex]._testimonialItems.push({ quote: '', author: '', role: '' })
        },

        removeTestimonialItem(sectionIndex, itemIndex) {
            this.sections[sectionIndex]._testimonialItems.splice(itemIndex, 1)
        },

        // --- Hero image picker ---
        openHeroPicker(sectionIndex) {
            this._pickerSectionIndex = sectionIndex
            this._pickerField = 'image_url'
            this.pickerMode = 'hero'
            this.pickerSelected = null
            this.pickerSelectedIds = []
            this.pickerSearch = ''
            this.pickerOpen = true
            this.loadPickerMedia(1)
        },

        openImagePicker(sectionIndex) {
            this._pickerSectionIndex = sectionIndex
            this._pickerField = 'src'
            this.pickerMode = 'hero'
            this.pickerSelected = null
            this.pickerSelectedIds = []
            this.pickerSearch = ''
            this.pickerOpen = true
            this.loadPickerMedia(1)
        },

        openGalleryPicker(sectionIndex) {
            this._pickerSectionIndex = sectionIndex
            this.pickerMode = 'gallery'
            this.pickerSelected = null
            this.pickerSelectedIds = []
            this.pickerSearch = ''
            this.pickerOpen = true
            this.loadPickerMedia(1)
        },

        closePicker() {
            this.pickerOpen = false
            this.pickerItems = []
            this.pickerSelected = null
            this.pickerSelectedIds = []
            this._pickerSectionIndex = null
        },

        async loadPickerMedia(page = 1) {
            this.pickerLoading = true
            this.pickerPage = page
            try {
                const params = new URLSearchParams({ type: 'image', page })
                if (this.pickerSearch) params.set('search', this.pickerSearch)
                const res = await fetch(`/admin/media/browse?${params}`)
                const data = await res.json()
                this.pickerItems = page === 1 ? (data.data ?? []) : [...this.pickerItems, ...(data.data ?? [])]
                this.pickerLastPage = data.meta?.last_page ?? data.last_page ?? 1
            } finally {
                this.pickerLoading = false
            }
        },

        onPickerSearch() {
            clearTimeout(this.pickerSearchTimer)
            this.pickerSearchTimer = setTimeout(() => this.loadPickerMedia(1), 300)
        },

        selectPickerItem(item) {
            if (this.pickerMode === 'gallery') {
                const idx = this.pickerSelectedIds.indexOf(item.id)
                if (idx === -1) this.pickerSelectedIds.push(item.id)
                else this.pickerSelectedIds.splice(idx, 1)
            } else {
                this.pickerSelected = item
            }
        },

        isPickerSelected(item) {
            if (this.pickerMode === 'gallery') return this.pickerSelectedIds.includes(item.id)
            return this.pickerSelected?.id === item.id
        },

        confirmPickerSelection() {
            if (this._pickerSectionIndex === null) return
            if (this.pickerMode === 'hero') {
                if (!this.pickerSelected) return
                this.sections[this._pickerSectionIndex].data[this._pickerField] = this.pickerSelected.url
            } else {
                const selected = this.pickerItems.filter(i => this.pickerSelectedIds.includes(i.id))
                const section = this.sections[this._pickerSectionIndex]
                if (!section._galleryImages) section._galleryImages = []
                selected.forEach(img => {
                    if (!section._galleryImages.find(g => g.url === img.url)) {
                        section._galleryImages.push({ url: img.url, name: img.name })
                    }
                })
            }
            this.closePicker()
        },

        removeGalleryImage(sectionIndex, imgIndex) {
            this.sections[sectionIndex]._galleryImages.splice(imgIndex, 1)
        },

        async pickerUpload(event) {
            const file = event.target.files[0]
            if (!file) return
            this.pickerUploading = true
            try {
                const form = new FormData()
                form.append('file', file)
                form.append('_token', document.querySelector('meta[name="csrf-token"]').content)
                await fetch('/admin/media', {
                    method: 'POST',
                    headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content },
                    body: form,
                })
                event.target.value = ''
                await this.loadPickerMedia(1)
            } finally {
                this.pickerUploading = false
            }
        },

        serialize() {
            return JSON.stringify(this.sections.map(s => {
                const fw = s.full_width ?? false
                if (s.type === 'faq') {
                    return { type: s.type, full_width: fw, data: { items: JSON.stringify(s._faqItems ?? []) } }
                }
                if (s.type === 'testimonial') {
                    return { type: s.type, full_width: fw, data: { items: JSON.stringify(s._testimonialItems ?? []) } }
                }
                if (s.type === 'gallery') {
                    return { type: s.type, full_width: fw, data: { images: (s._galleryImages ?? []).map(i => i.url).join(', ') } }
                }
                return { type: s.type, full_width: fw, data: s.data }
            }))
        },
    }
}
