"use client"

import { useState, useEffect } from "react"
import { Bell, BellOff, Loader2, AlertTriangle } from "lucide-react"
import { toast } from "sonner"
import { subscribeUser, unsubscribeUser, getVapidPublicKey } from "@/app/actions/subscription"
import { Button } from "@/components/ui/button"

function urlBase64ToUint8Array(base64String: string) {
    try {
        const padding = '='.repeat((4 - base64String.length % 4) % 4)
        const base64 = (base64String + padding)
            .replace(/\-/g, '+')
            .replace(/_/g, '/')

        const rawData = window.atob(base64)
        const outputArray = new Uint8Array(rawData.length)

        for (let i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i)
        }
        return outputArray
    } catch (e) {
        console.error("VAPID Key conversion failed", e)
        throw new Error("Invalid VAPID Key format")
    }
}

export function PushSubscriptionSettings({ planId }: { planId: string }) {
    const [isSupported, setIsSupported] = useState(false)
    const [subscription, setSubscription] = useState<PushSubscription | null>(null)
    const [loading, setLoading] = useState(false)
    const [debugInfo, setDebugInfo] = useState<string | null>(null)
    const [vapidKey, setVapidKey] = useState<string | null>(null)

    useEffect(() => {
        async function checkSupport() {
            const checks = []
            if (!('serviceWorker' in navigator)) checks.push("No Service Worker support")
            if (!('PushManager' in window)) checks.push("No PushManager support")

            try {
                const key = await getVapidPublicKey()
                if (!key) {
                    checks.push("Missing VAPID Key (Server)")
                } else {
                    setVapidKey(key)
                }
            } catch (e) {
                checks.push("Failed to fetch VAPID Key")
            }

            if (checks.length === 0) {
                setIsSupported(true)
                registerServiceWorker()
            } else {
                console.warn("Push not supported:", checks.join(", "))
                setDebugInfo(checks.join(", "))
            }
        }
        checkSupport()
    }, [])

    async function registerServiceWorker() {
        try {
            // Explicitly register the service worker
            const registration = await navigator.serviceWorker.register('/push-sw.js')

            // Wait for it to be ready
            await navigator.serviceWorker.ready

            const sub = await registration.pushManager.getSubscription()
            setSubscription(sub)
        } catch (e: any) {
            console.error("SW registration error", e)
            setDebugInfo(`SW Error: ${e.message}`)
        }
    }

    async function subscribe() {
        if (!vapidKey) {
            toast.error("VAPID Key missing")
            return
        }
        setLoading(true)
        setDebugInfo(null)
        try {
            console.log("Requesting permission...")
            const permission = await Notification.requestPermission()
            console.log("Permission result:", permission)

            if (permission === 'denied') {
                toast.error("Notifications are blocked in your browser settings.")
                setLoading(false)
                return
            }

            if (permission !== 'granted') {
                toast.error("Notifications permission not granted.")
                setLoading(false)
                return
            }

            console.log("Waiting for SW ready...")
            const registration = await navigator.serviceWorker.ready
            console.log("SW Ready. Subscribing...")

            const sub = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: urlBase64ToUint8Array(vapidKey)
            })

            console.log("Subscribed locally:", sub)
            setSubscription(sub)
            await subscribeUser(planId, sub.toJSON())
            toast.success("Push Notifications enabled")
        } catch (error: any) {
            console.error("Subscription failed", error)
            setDebugInfo(`Error: ${error.message || "Unknown error"}`)
            toast.error("Failed to enable notifications. See debug info.")
        } finally {
            setLoading(false)
        }
    }

    async function unsubscribe() {
        setLoading(true)
        try {
            if (subscription) {
                await subscription.unsubscribe()
                await unsubscribeUser(subscription.endpoint)
                setSubscription(null)
                toast.success("Notifications disabled")
            }
        } catch (error) {
            console.error(error)
            toast.error("Failed to disable.")
        } finally {
            setLoading(false)
        }
    }

    if (!isSupported && !debugInfo) return null

    return (
        <div className="flex flex-col gap-2 p-4 border rounded-md mb-4 bg-muted/50">
            <div className="flex items-center justify-between">
                <div className="space-y-0.5">
                    <h3 className="font-medium text-sm">Device Notifications</h3>
                    <p className="text-xs text-muted-foreground">
                        Receive updates on this device
                    </p>
                </div>
                {subscription ? (
                    <Button variant="outline" size="sm" onClick={unsubscribe} disabled={loading}>
                        {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <BellOff className="w-4 h-4 mr-2" />}
                        Disable
                    </Button>
                ) : (
                    <Button size="sm" onClick={subscribe} disabled={loading || !isSupported} variant="secondary">
                        {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Bell className="w-4 h-4 mr-2" />}
                        Enable
                    </Button>
                )}
            </div>
            {debugInfo && (
                <div className="text-xs text-destructive flex items-center gap-1 bg-destructive/10 p-2 rounded">
                    <AlertTriangle className="w-3 h-3" />
                    {debugInfo}
                </div>
            )}
        </div>
    )
}
