import { Button } from "@/shared/components/ui/button"
import { Card, CardContent } from "@/shared/components/ui/card"
import { Switch } from "@/shared/components/ui/switch"
import { useDb } from "@/shared/db/provider"
import { useDeviceId } from "@/shared/hooks/use-device-id"
import { useFollows } from "@/shared/hooks/use-follows"
import { usePush } from "@/shared/hooks/use-push"
import { usePwaUpdate } from "@/shared/hooks/use-pwa-update"
import { fetchTopics } from "@/shared/lib/aw-api"
import { BACKEND_URL, VAPID_PUBLIC_KEY } from "@/shared/lib/constants"
import { useCallback, useEffect, useState } from "react"
import { type GeoResult, clearGeoCache, detectFromCoords, loadCachedResult } from "../../location/lib/geo"
import { NotificationGuide } from "./notification-guide"

function isStandalone(): boolean {
	if (typeof window === "undefined") return false
	return (
		window.matchMedia("(display-mode: standalone)").matches ||
		("standalone" in navigator && (navigator as { standalone?: boolean }).standalone === true)
	)
}

export function SettingsPage() {
	const db = useDb()
	const deviceId = useDeviceId()
	const { needRefresh, checkForUpdate, applyUpdate } = usePwaUpdate()
	const push = usePush()
	const { follow } = useFollows()
	const [checking, setChecking] = useState(false)
	const [loading, setLoading] = useState(false)
	const [result, setResult] = useState<GeoResult | null>(null)
	const [errorMsg, setErrorMsg] = useState<string | null>(null)
	const [showGuide, setShowGuide] = useState(false)
	const [devHealth, setDevHealth] = useState<string | null>(null)
	const [devPush, setDevPush] = useState<string | null>(null)
	const [devTopics, setDevTopics] = useState<string | null>(null)
	const [devPoliticians, setDevPoliticians] = useState<string | null>(null)

	useEffect(() => {
		loadCachedResult(db).then((cached) => {
			if (cached) setResult(cached)
		})
	}, [db])

	const detect = useCallback(
		(skipCache: boolean) => {
			if (!navigator.geolocation) {
				setErrorMsg("Standortbestimmung wird nicht unterstützt")
				return
			}
			setLoading(true)
			setErrorMsg(null)
			navigator.geolocation.getCurrentPosition(
				async (pos) => {
					try {
						const r = await detectFromCoords(db, pos.coords.latitude, pos.coords.longitude, skipCache)
						setResult(r)
					} catch (e) {
						setErrorMsg(String(e))
					} finally {
						setLoading(false)
					}
				},
				(err) => {
					setErrorMsg(err.message)
					setLoading(false)
				},
			)
		},
		[db],
	)

	function handleClearCache() {
		clearGeoCache(db)
		setResult(null)
	}

	async function handleCheckUpdate() {
		setChecking(true)
		try {
			await checkForUpdate()
		} finally {
			setChecking(false)
		}
	}

	const hasLocation = result && result.mandates.length > 0
	const standalone = isStandalone()

	if (showGuide) {
		return <NotificationGuide onBack={() => setShowGuide(false)} />
	}

	return (
		<div className="px-4 py-4 space-y-6 pb-4">
			{/* --- Notifications --- */}
			{VAPID_PUBLIC_KEY && (
				<section>
					<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">
						Benachrichtigungen
					</h2>
					<Card className="py-0 gap-0">
						<CardContent className="p-0 divide-y divide-border">
							{push.permission === "denied" ? (
								<div className="px-4 py-3">
									<span className="text-destructive text-sm">
										Benachrichtigungen sind blockiert. Bitte in den Systemeinstellungen aktivieren.
									</span>
								</div>
							) : (
								<div className="flex items-center justify-between px-4 py-3">
									<span className="text-sm" id="push-label">
										Push-Benachrichtigungen
									</span>
									<Switch
										checked={push.subscribed}
										disabled={push.loading}
										aria-labelledby="push-label"
										onCheckedChange={() => {
											if (push.subscribed) push.unsubscribe()
											else push.subscribe()
										}}
									/>
								</div>
							)}
							{!standalone && (
								<button
									type="button"
									className="w-full flex items-center justify-between px-4 py-3 text-sm hover:bg-muted transition-colors"
									onClick={() => setShowGuide(true)}
								>
									Einrichtung auf dem iPhone
									<svg
										xmlns="http://www.w3.org/2000/svg"
										className="w-4 h-4 text-muted-foreground"
										fill="none"
										viewBox="0 0 24 24"
										stroke="currentColor"
										strokeWidth={2}
										aria-hidden="true"
									>
										<path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
									</svg>
								</button>
							)}
						</CardContent>
					</Card>
				</section>
			)}

			{/* --- Location --- */}
			<section>
				<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">Standort</h2>

				{loading && (
					<div className="flex items-center justify-center h-16 mb-3">
						<div className="w-6 h-6 border-3 border-primary border-t-transparent rounded-full animate-spin" />
						<span className="ml-3 text-sm text-muted-foreground">{hasLocation ? "Aktualisiere…" : "Erkenne…"}</span>
					</div>
				)}

				{errorMsg && (
					<div className="mb-3 p-3 bg-destructive/10 rounded-lg text-destructive text-sm" role="alert">
						{errorMsg}
					</div>
				)}

				<div className="flex flex-col gap-2">
					{!hasLocation && !loading && (
						<Button size="lg" onClick={() => detect(false)}>
							Standort erkennen
						</Button>
					)}
					{hasLocation && (
						<>
							<Button size="sm" variant="outline" onClick={() => detect(true)} disabled={loading}>
								Abgeordnete neu laden
							</Button>
							<Button size="sm" variant="outline" onClick={handleClearCache} disabled={loading}>
								Cache löschen
							</Button>
						</>
					)}
				</div>
			</section>

			{/* --- App Update --- */}
			<section>
				<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">App-Update</h2>
				<Card className="py-0 gap-0">
					<CardContent className="p-0">
						{needRefresh ? (
							<div className="flex items-center justify-between px-4 py-3">
								<span className="text-sm">Neue Version verfügbar</span>
								<Button size="sm" onClick={applyUpdate}>
									Jetzt aktualisieren
								</Button>
							</div>
						) : (
							<div className="flex items-center justify-between px-4 py-3">
								<span className="text-sm">App ist aktuell</span>
								<Button size="sm" variant="outline" onClick={handleCheckUpdate} disabled={checking}>
									{checking ? "Prüfe…" : "Prüfen"}
								</Button>
							</div>
						)}
					</CardContent>
				</Card>
			</section>

			{/* --- About --- */}
			<section>
				<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">Info</h2>
				<Card className="py-0 gap-0">
					<CardContent className="p-0 divide-y divide-border">
						<div className="flex justify-between px-4 py-3">
							<span className="text-sm">Datenquelle</span>
							<a
								href="https://www.abgeordnetenwatch.de"
								target="_blank"
								rel="noopener noreferrer"
								className="text-sm text-primary"
							>
								abgeordnetenwatch.de
							</a>
						</div>
						<div className="flex justify-between px-4 py-3">
							<span className="text-sm">Geräte-ID</span>
							<span className="font-mono text-xs max-w-[50%] truncate">{deviceId}</span>
						</div>
					</CardContent>
				</Card>
			</section>

			{/* --- Developer --- */}
			<section>
				<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">Entwickler</h2>
				<Card className="py-0 gap-0">
					<CardContent className="p-0 divide-y divide-border">
						<div className="flex items-center justify-between px-4 py-3">
							<span className="text-sm">Backend Health</span>
							<div className="flex items-center gap-2">
								{devHealth && (
									<span className={`text-xs ${devHealth === "ok" ? "text-green-600" : "text-destructive"}`}>
										{devHealth}
									</span>
								)}
								<Button
									size="sm"
									variant="outline"
									onClick={async () => {
										setDevHealth(null)
										try {
											const res = await fetch(`${BACKEND_URL}/health`)
											setDevHealth(res.ok ? "ok" : `${res.status}`)
										} catch (e) {
											setDevHealth(String(e))
										}
									}}
								>
									Prüfen
								</Button>
							</div>
						</div>
						<div className="flex items-center justify-between px-4 py-3">
							<span className="text-sm">Test-Push</span>
							<div className="flex items-center gap-2">
								{devPush && (
									<span className={`text-xs ${devPush === "ok" ? "text-green-600" : "text-destructive"}`}>
										{devPush}
									</span>
								)}
								<Button
									size="sm"
									variant="outline"
									onClick={async () => {
										setDevPush(null)
										try {
											const res = await fetch(`${BACKEND_URL}/push/test`, {
												method: "POST",
												headers: { "Content-Type": "application/json" },
												body: JSON.stringify({ device_id: deviceId }),
											})
											setDevPush(res.ok ? "ok" : `${res.status}`)
										} catch (e) {
											setDevPush(String(e))
										}
									}}
								>
									Senden
								</Button>
							</div>
						</div>
						<div className="flex items-center justify-between px-4 py-3">
							<span className="text-sm">Alle Themen folgen</span>
							<div className="flex items-center gap-2">
								{devTopics && <span className="text-xs text-green-600">{devTopics}</span>}
								<Button
									size="sm"
									variant="outline"
									onClick={async () => {
										setDevTopics(null)
										try {
											const topics = await fetchTopics()
											for (const t of topics) follow("topic", t.id, t.label)
											setDevTopics(`${topics.length}`)
										} catch (e) {
											setDevTopics(String(e))
										}
									}}
								>
									Folgen
								</Button>
							</div>
						</div>
						<div className="flex items-center justify-between px-4 py-3">
							<span className="text-sm">Alle Abgeordnete folgen</span>
							<div className="flex items-center gap-2">
								{devPoliticians && <span className="text-xs text-green-600">{devPoliticians}</span>}
								<Button
									size="sm"
									variant="outline"
									onClick={async () => {
										setDevPoliticians(null)
										const cached = await loadCachedResult(db)
										if (!cached || cached.mandates.length === 0) {
											setDevPoliticians("Kein Standort-Cache")
											return
										}
										for (const m of cached.mandates) {
											follow("politician", m.politician.id, m.politician.label)
										}
										setDevPoliticians(`${cached.mandates.length}`)
									}}
								>
									Folgen
								</Button>
							</div>
						</div>
					</CardContent>
				</Card>
			</section>
		</div>
	)
}
