export const useMediaPrefs = () => {
    // 1. Global State
    // ใช้ useState เพื่อแชร์ค่าเดียวกันทั่วทั้ง App (เช่น เปลี่ยนหน้าแล้วเสียงยังเท่าเดิม)
    const volume = useState<number>('media_prefs_volume', () => 1)
    const muted = useState<boolean>('media_prefs_muted', () => false)
    
    const { user } = useAuth()

    // 2. Storage Key Helper (User Specific)
    const getStorageKey = () => {
        const userId = user.value?.id || 'guest'
        return `media:prefs:v1:${userId}`
    }

    // 3. Save Logic (Throttled)
    let saveTimeout: ReturnType<typeof setTimeout> | null = null
    
    const save = () => {
        if (import.meta.server) return

        if (saveTimeout) clearTimeout(saveTimeout)
        saveTimeout = setTimeout(() => {
            try {
                const key = getStorageKey()
                const data = {
                    volume: volume.value,
                    muted: muted.value,
                    updatedAt: Date.now()
                }
                localStorage.setItem(key, JSON.stringify(data))
            } catch (e) {
                console.error('Failed to save media prefs', e)
            }
        }, 500) // Throttle 500ms
    }

    // 4. Load Logic
    const load = () => {
        if (import.meta.server) return
        
        try {
            const key = getStorageKey()
            const stored = localStorage.getItem(key)
            if (stored) {
                const parsed = JSON.parse(stored)
                if (typeof parsed.volume === 'number') {
                    volume.value = Math.max(0, Math.min(1, parsed.volume))
                }
                if (typeof parsed.muted === 'boolean') {
                    muted.value = parsed.muted
                }
            }
        } catch (e) {
            console.error('Failed to load media prefs', e)
        }
    }

    // 5. Setters (With Logic)
    const setVolume = (val: number) => {
        const clamped = Math.max(0, Math.min(1, val))
        volume.value = clamped
        
        // Auto unmute if volume increased from 0
        if (clamped > 0 && muted.value) {
            muted.value = false
        }
        // Auto mute if volume set to 0
        if (clamped === 0 && !muted.value) {
            muted.value = true
        }
        
        save()
    }

    const setMuted = (val: boolean) => {
        muted.value = val
        
        // Logic: Unmuting should restore volume if it was 0
        if (!val && volume.value === 0) {
            volume.value = 1
        }
        
        save()
    }

    // 6. Apply & Bind to Element (The Magic)
    const applyTo = (el: HTMLMediaElement | null | undefined) => {
        if (!el) return () => {}

        // Initial Apply
        el.volume = volume.value
        el.muted = muted.value

        // A. Watch State -> Update Element
        const stopVolWatch = watch(volume, (v) => {
            if (Math.abs(el.volume - v) > 0.01) el.volume = v
        })
        const stopMutedWatch = watch(muted, (m) => {
            if (el.muted !== m) el.muted = m
        })

        // B. Listen Element -> Update State (e.g. Native Controls)
        const onVolumeChange = () => {
            // Update state only if diff allows (prevent loop)
            if (Math.abs(el.volume - volume.value) > 0.01) {
                volume.value = el.volume
                save()
            }
            if (el.muted !== muted.value) {
                muted.value = el.muted
                save()
            }
        }
        el.addEventListener('volumechange', onVolumeChange)

        // Cleanup function
        return () => {
            stopVolWatch()
            stopMutedWatch()
            el.removeEventListener('volumechange', onVolumeChange)
        }
    }

    // 7. Lifecycle & Sync
    if (import.meta.client) {
        onMounted(() => {
            load()
            // Cross-tab sync
            window.addEventListener('storage', (e) => {
                if (e.key === getStorageKey()) {
                    load()
                }
            })
        })
    }

    return {
        volume,
        muted,
        setVolume,
        setMuted,
        applyTo,
        load
    }
}
