import localforage from "localforage"
import type { FileInfo } from '~/types/serverFiles'

export function useFileSync() {
    const fileServer = ref<FileInfo[]>([])
    const fileLocal = ref<{ name: string; blob: Blob; type: string; url: string }[]>([])
    const errorMsg = ref<string | null>(null)
    const isSyncing = ref(false)

    // buat instance localforage langsung di sini
    const localStore = localforage.createInstance({
        name: 'nuxt-offline',
        storeName: 'file-store',
    })


    // cek file server
    const fetchServerFiles = async () => {
        try {
            const { data, error } = await useFetch<FileInfo[]>('/api/serverFile/files')
            if (error.value) throw error.value
            const sortedFiles = data.value?.sort((a, b) => a.name.localeCompare(b.name)) || []
            fileServer.value = sortedFiles

            return fileServer.value
        } catch (err: any) {
            errorMsg.value = err.message || 'Gagal mengambil data file'
            return []
        }
    }

    //cek indexedDB
    const getLocalMeta = async (name: string) => {
        return await localStore.getItem<{ modified: string, size: number }>(`${name}-meta`)
    }


    //Simpan  ke IndexedDB

    const saveToIndexedDB = async (file: FileInfo, blob: Blob) => {
        console.log('Downloaded file to save:', blob);

        await localStore.setItem(file.name, blob)
        await localStore.setItem(`${file.name}-meta`, {
            modified: file.modified,
            size: file.size,
            typeFile: file.ext
        })
    }
    const downloadFile = async (file: FileInfo) => {
        const response = await fetch(`/api/serverFile/${file.name}`)
        if (!response.ok) throw new Error(`Gagal download ${file.name}`)
        const blob = await response.blob()

        // console.log('blob server', blob ,file.name,file.ext)
        await saveToIndexedDB(file, blob)
    }
    const removeFiles = async (prefix: string) => {

        const IndexedDBKeys: string[] = []

        // Ambil semua key dulu
        await localStore.iterate((_value, key) => {
            IndexedDBKeys.push(key)
        })

        // console.log('Removing files with prefix:', IndexedDBKeys)
        for (const key of IndexedDBKeys) {
            const baseName = key.split('-')[0].split('.')[0]
            // console.log('Checking key:', key, 'Base name:', baseName)

            if (baseName.startsWith(prefix)) {
                await localStore.removeItem(key)
                console.log('Removed:', key)
            }
        }
    }

    // Helper MIME
    const mimeFromExt = (ext: string) => {
        const e = ext.replace(/^\./, '').toLowerCase()
        switch (e) {
            case 'png': return 'image/png'
            case 'jpg':
            case 'jpeg': return 'image/jpeg'
            case 'gif': return 'image/gif'
            case 'svg': return 'image/svg+xml'
            case 'mp4': return 'video/mp4'
            case 'mkv': return 'video/x-matroska'
            default: return 'application/octet-stream'
        }
    }

    const syncFiles = async () => {
        isSyncing.value = true
        try {
            const serverFiles = await fetchServerFiles()
            // console.log('file server :', serverFiles)

            for (const dataFileServer of serverFiles) {
                const localMeta = await getLocalMeta(dataFileServer.name)
                // console.log('fileServer', dataFileServer.name ,'local', localMeta)
                // console.log('localMeta', localMeta)
                const mime = mimeFromExt(dataFileServer.ext)
                // Jika ekstensi tidak dalam mimeFromExt
                if (mime !== 'application/octet-stream') {
                    const firstNamePart = dataFileServer.name.split('.')[0]
                    const isNew = !localMeta
                    const isUpdated = localMeta && new Date(dataFileServer.modified) > new Date(localMeta.modified)
                    //jika data baru atau di update
                    if (isNew || isUpdated) {
                        //  console.log('Download file: ', firstNamePart)
                        await removeFiles(firstNamePart)
                        await downloadFile(dataFileServer)

                    }
                }

            }

        } catch (err: any) {
            errorMsg.value = err.message || 'Gagal sinkronisasi file'
        }

    }

    // const tampilFileBrowser = async () => {

    //     await syncFiles();
    //     if (isSyncing.value) {
    //         try {
    //             const localStoreKeys = await localStore.keys()
    //             // console.log('localStore Keys:', localStoreKeys)
    //             const files: { name: string; blob: Blob; type: string; url: string }[] = []

    //             for (const key of localStoreKeys) {
    //                 if (!key.endsWith('-meta')) {
    //                     const fileBlob = await localStore.getItem<Blob>(key)

    //                     if (fileBlob instanceof Blob) {
    //                         const url = URL.createObjectURL(fileBlob)
    //                         files.push({ name: key, blob: fileBlob, type: fileBlob.type, url: url })

    //                     }
    //                 }
    //             }
    //             // console.log('Files in IndexedDB:',fileLocal.value)
    //             return fileLocal.value = files

    //         } catch (err) {
    //             console.error('Gagal memuat file dari IndexedDB:', err)
    //         } finally {
    //             isSyncing.value = false
    //         }


    //     }
    // }

    const tampilFileBrowser = async () => {

        await syncFiles();
        if (isSyncing.value) {
            try {
                const localStoreKeys = await localStore.keys()
                // console.log('localStore Keys:', localStoreKeys)
                const files: { name: string; blob: Blob; type: string; url: string }[] = []

                for (const key of localStoreKeys) {
                    if (!key.endsWith('-meta')) {
                        const fileBlob = await localStore.getItem<Blob>(key)

                        if (fileBlob instanceof Blob) {
                            const url = URL.createObjectURL(fileBlob)
                            files.push({ name: key, blob: fileBlob, type: fileBlob.type, url: url })

                        }
                    }
                }
                // console.log('Files in IndexedDB:',files)
                // console.log('File Server:', fileServer.value)
                const fileTidaksama = files.filter(local => !fileServer.value.some(fs => fs.name === local.name))
                // console.log('File tidak sama dengan server:', fileTidaksama)
                for (const namaFile of fileTidaksama) {
                    const firstNamePart = namaFile.name.split('.')[0];
                    console.log('file lokal yang tidak ada di server:', firstNamePart);
                    await removeFiles(firstNamePart)
                }

                return fileLocal.value = files

            } catch (err) {
                console.error('Gagal memuat file dari IndexedDB:', err)
            } finally {
                isSyncing.value = false
            }


        }
    }
    // Bersihkan object URL biar gak bocor memori
    onBeforeUnmount(() => {
        fileLocal.value.forEach(f => URL.revokeObjectURL(f.url))
    })



    return {
        fileServer,
        errorMsg,
        tampilFileBrowser,
        fileLocal,

    }
}
