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 {
	APP_VERSION,
	BACKEND_URL,
	STORAGE_KEYS,
	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, unfollowAllTopics, unfollowAllPoliticians } = 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)
	const [devUnfollowTopics, setDevUnfollowTopics] = useState<string | null>(
		null,
	)
	const [devUnfollowPoliticians, setDevUnfollowPoliticians] = useState<
		string | null
	>(null)
	const [devReload, setDevReload] = useState<string | null>(null)
	const [devMode, setDevMode] = useState(
		() => localStorage.getItem(STORAGE_KEYS.devMode) === "true",
	)

	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">
			{/* --- Permissions: Push + Location --- */}
			<section>
				<h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2">
					Berechtigungen
				</h2>
				<Card className="py-0 gap-0">
					<CardContent className="p-0 divide-y divide-border">
						{VAPID_PUBLIC_KEY &&
							(push.permission === "denied" ? (
								<div className="px-4 py-3">
									<span className="text-destructive text-sm">
										Push 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>
							))}
						<div className="flex items-center justify-between px-4 py-3">
							<div>
								<span className="text-sm" id="location-label">
									Standort
								</span>
								{loading && (
									<span className="ml-2 text-xs text-muted-foreground">
										{hasLocation ? "Aktualisiere…" : "Erkenne…"}
									</span>
								)}
							</div>
							<Switch
								checked={!!hasLocation}
								disabled={loading}
								aria-labelledby="location-label"
								onCheckedChange={(checked) => {
									if (checked) detect(false)
									else handleClearCache()
								}}
							/>
						</div>
						{errorMsg && (
							<div className="px-4 py-3">
								<span className="text-destructive text-sm">{errorMsg}</span>
							</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>

			{/* --- Info --- */}
			<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">Version</span>
							<div className="flex items-center gap-2">
								<span className="text-sm text-muted-foreground">
									{APP_VERSION}
								</span>
								{needRefresh ? (
									<Button size="sm" onClick={applyUpdate}>
										Aktualisieren
									</Button>
								) : (
									<Button
										size="sm"
										variant="outline"
										onClick={handleCheckUpdate}
										disabled={checking}
									>
										{checking ? "Prüfe…" : "Prüfen"}
									</Button>
								)}
							</div>
						</div>
						<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>
						<div className="flex items-center justify-between px-4 py-3">
							<span className="text-sm" id="dev-mode-label">
								Entwicklermodus
							</span>
							<Switch
								checked={devMode}
								aria-labelledby="dev-mode-label"
								onCheckedChange={async (checked) => {
									setDevMode(checked)
									localStorage.setItem(STORAGE_KEYS.devMode, String(checked))
									try {
										await fetch(`${BACKEND_URL}/legislation/seed-mock`, {
											method: checked ? "POST" : "DELETE",
										})
									} catch {
										// best-effort
									}
								}}
							/>
						</div>
					</CardContent>
				</Card>
			</section>

			{/* --- Developer (visible only in dev mode) --- */}
			{devMode && (
				<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-foreground" : "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-foreground" : "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-muted-foreground">
											{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">Allen Themen entfolgen</span>
								<div className="flex items-center gap-2">
									{devUnfollowTopics && (
										<span className="text-xs text-muted-foreground">
											{devUnfollowTopics}
										</span>
									)}
									<Button
										size="sm"
										variant="outline"
										onClick={async () => {
											setDevUnfollowTopics(null)
											await unfollowAllTopics()
											setDevUnfollowTopics("ok")
										}}
									>
										Entfolgen
									</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-muted-foreground">
											{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>
							<div className="flex items-center justify-between px-4 py-3">
								<span className="text-sm">Allen Abgeordneten entfolgen</span>
								<div className="flex items-center gap-2">
									{devUnfollowPoliticians && (
										<span className="text-xs text-muted-foreground">
											{devUnfollowPoliticians}
										</span>
									)}
									<Button
										size="sm"
										variant="outline"
										onClick={async () => {
											setDevUnfollowPoliticians(null)
											await unfollowAllPoliticians()
											setDevUnfollowPoliticians("ok")
										}}
									>
										Entfolgen
									</Button>
								</div>
							</div>
							<div className="flex items-center justify-between px-4 py-3">
								<span className="text-sm">Abgeordnete neu laden</span>
								<div className="flex items-center gap-2">
									{devReload && (
										<span className="text-xs text-muted-foreground">
											{devReload}
										</span>
									)}
									<Button
										size="sm"
										variant="outline"
										disabled={loading || !hasLocation}
										onClick={() => {
											setDevReload(null)
											detect(true)
											setDevReload("gestartet")
										}}
									>
										Neu laden
									</Button>
								</div>
							</div>
						</CardContent>
					</Card>
				</section>
			)}
		</div>
	)
}
