import type { ReactNode } from "react";
import { View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";

import { SafeAreaScrollView } from "@/components/safe-area-scroll-view";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { Text } from "@/components/ui/text";
import { cn } from "@/lib/utils";

const fixture = {
	location: {
		authorization: "When In Use",
		lastLocation: {
			latitude: 37.33182,
			longitude: -122.03118,
			accuracyMeters: 12.4,
			speedMps: 0.4,
		},
	},
	recompute: {
		lastReason: "manual",
		lastTime: new Date("2024-05-21T09:32:00Z"),
		elapsedMs: 482,
		fetchFailed: false,
		error: null as string | null,
	},
	winner: {
		title: "Glass Now online",
		subtitle: "Connected to iPhone",
		type: "INFO",
		bucket: "RIGHT_NOW",
		priority: 0.8,
		ttlSec: 86400,
		poiType: "CAFE",
		startsAt: 1767717000,
		id: "demo:welcome",
	},
	feed: [
		{
			id: "demo:welcome",
			title: "Glass Now online",
			subtitle: "Connected to iPhone",
			type: "INFO",
			bucket: "RIGHT_NOW",
			priority: 0.8,
			ttlSec: 86400,
		},
		{
			id: "cal:demo:1767717000",
			title: "Team Sync",
			subtitle: "",
			type: "CALENDAR_EVENT",
			bucket: "FYI",
			priority: 0.7,
			ttlSec: 5400,
		},
		{
			id: "demo:next",
			title: "Next: Calendar",
			subtitle: "Then Weather + POI",
			type: "INFO",
			bucket: "FYI",
			priority: 0.4,
			ttlSec: 86400,
		},
		{
			id: "music:now:demo",
			title: "Midnight City",
			subtitle: "M83 - Hurry Up, We're Dreaming",
			type: "NOW_PLAYING",
			bucket: "FYI",
			priority: 0.35,
			ttlSec: 30,
		},
	],
	nowPlaying: {
		auth: "Authorized",
		title: "Midnight City",
		artist: "M83",
		album: "Hurry Up, We're Dreaming",
		playbackStatus: "playing",
	},
	weatherDiagnostics: {
		provider: "WeatherKit",
		last_fetch: "2024-05-21 09:30:14",
		alerts: "0",
		conditions: "mostly_clear_day",
	},
	calendarDiagnostics: {
		events_upcoming: "3",
		next_event: "Team Sync - 10:30",
	},
	test: {
		note: "Test actions are not available in the React Native client.",
	},
};

const formatTime = (date: Date | null) => {
	if (!date) {
		return "--";
	}
	return date.toLocaleTimeString();
};

const formatSpeed = (speedMps: number) => {
	if (speedMps < 0) {
		return "--";
	}
	return `${speedMps.toFixed(1)} m/s`;
};

const formatLatLon = (value: number) => value.toFixed(5);

const formatPriority = (value: number) => value.toFixed(2);

export default function OrchestratorScreen() {
	const insets = useSafeAreaInsets();

	return (
		<View className="flex flex-1 bg-white">
			<SafeAreaScrollView>
				<View className="gap-4" style={{ paddingBottom: insets.bottom + 24 }}>
					<View className="gap-1 px-8">
						<Text variant="h3">Orchestrator</Text>
						<Text className="text-sm text-muted-foreground">
							Context engine status and diagnostics.
						</Text>
					</View>

					<View className="w-full h-px bg-muted" />
					<LocationSection />

					<View className="w-full h-px bg-muted" />
					<RecomputeSection />

					<View className="w-full h-px bg-muted" />
					<WinnerSection />

					<View className="w-full h-px bg-muted" />
					<FeedSection />

					<View className="w-full h-px bg-muted" />
					<NowPlayingSection />

					<View className="w-full h-px bg-muted" />
					<DiagnosticsSection
						title="Weather Diagnostics"
						entries={fixture.weatherDiagnostics}
					/>

					<View className="w-full h-px bg-muted" />
					<DiagnosticsSection
						title="Calendar Diagnostics"
						entries={fixture.calendarDiagnostics}
					/>

					<View className="w-full h-px bg-muted" />
					<TestSection />
				</View>
			</SafeAreaScrollView>
		</View>
	);
}

function ValueRow({ label, value }: { label: ReactNode; value: ReactNode }) {
	return (
		<View className="flex flex-row items-center justify-between">
			{typeof label === "string" ? (
				<Text className="text-sm text-muted-foreground">{label}</Text>
			) : (
				label
			)}
			{typeof value === "string" || typeof value === "number" ? (
				<Text className="text-sm">{value}</Text>
			) : (
				value
			)}
		</View>
	);
}

function LocationSection() {
	const { authorization, lastLocation } = fixture.location;

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Location
			</Text>
			<View className="gap-1">
				<ValueRow label="Auth" value={authorization} />
				{lastLocation ? (
					<>
						<ValueRow
							label="Lat/Lon"
							value={
								<Text selectable className="text-sm">
									{`${formatLatLon(lastLocation.latitude)}, ${formatLatLon(lastLocation.longitude)}`}
								</Text>
							}
						/>
						<ValueRow
							label="Accuracy"
							value={`${Math.round(lastLocation.accuracyMeters)} m`}
						/>
						<ValueRow
							label="Speed"
							value={formatSpeed(lastLocation.speedMps)}
						/>
					</>
				) : (
					<Text className="text-sm text-muted-foreground">No location yet</Text>
				)}
			</View>
		</View>
	);
}

function RecomputeSection() {
	const { lastReason, lastTime, elapsedMs, fetchFailed, error } =
		fixture.recompute;

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Recompute
			</Text>
			<View className="gap-1">
				<ValueRow label="Last reason" value={lastReason || "--"} />
				<ValueRow label="Last time" value={formatTime(lastTime)} />
				<ValueRow label="Elapsed" value={`${elapsedMs} ms`} />
				<ValueRow label="Fetch failed" value={fetchFailed ? "Yes" : "No"} />
				{error ? (
					<Text className="text-xs text-muted-foreground">{error}</Text>
				) : null}
			</View>
			<Button onPress={() => {}} variant="outline" className="mt-3">
				<Text>Recompute Now</Text>
			</Button>
		</View>
	);
}

function WinnerSection() {
	const winner = fixture.winner;

	return (
		<View>
			<Text variant="h4" className="mb-2 font-medium px-8">
				Winner
			</Text>
			{winner ? (
				<Card className="mx-4 gap-2 pb-2">
					<CardHeader className="gap-0 border-b border-border pb-2 flex-row items-start justify-between">
						<View className="gap-1.5">
							<CardTitle className="flex-1">{winner.title}</CardTitle>
							<CardDescription>
								{winner.subtitle ?? "No description"}
							</CardDescription>
						</View>
						<Badge variant="default">
							<Text>{winner.type}</Text>
						</Badge>
					</CardHeader>
					<CardContent className="gap-1">
						<ValueRow label="Bucket" value={winner.bucket} />
						<ValueRow
							label="Priority"
							value={formatPriority(winner.priority)}
						/>
						<ValueRow label="TTL" value={`${winner.ttlSec}s`} />
						{winner.poiType ? (
							<ValueRow label="POI type" value={winner.poiType} />
						) : null}
						{winner.startsAt ? (
							<ValueRow label="Starts at" value={`${winner.startsAt}`} />
						) : null}
						<ValueRow
							label="ID"
							value={
								<Text selectable className="text-xs text-muted-foreground">
									{winner.id}
								</Text>
							}
						/>
					</CardContent>
				</Card>
			) : (
				<Text className="text-sm text-muted-foreground">No winner yet</Text>
			)}
		</View>
	);
}

function FeedSection() {
	const feed = fixture.feed;

	return (
		<View>
			<Text variant="h4" className="mb-2 font-medium px-8">
				Feed
			</Text>
			{feed.length === 0 ? (
				<Text className="text-sm text-muted-foreground">No feed items yet</Text>
			) : (
				<View className="px-4">
					{feed.map((item, i) => (
						<View
							key={item.id}
							className={cn("px-4 py-2 gap-1 border border-b-0 border-border", {
								"rounded-t-lg": i === 0,
								"rounded-b-lg border-b": i === feed.length - 1,
							})}
						>
							<View className="flex-row items-center justify-between gap-2">
								<View className="gap-1">
									<Text
										className="text-sm font-semibold flex-1"
										numberOfLines={1}
									>
										{item.title}
									</Text>
									<Text
										className="text-xs text-muted-foreground"
										numberOfLines={1}
									>
										{item.subtitle || "No description"}
									</Text>
									<Text className="text-xs text-muted-foreground">
										{`bucket ${item.bucket} | prio ${formatPriority(item.priority)} | ttl ${item.ttlSec}s`}
									</Text>
								</View>
								<Badge variant="secondary">
									<Text>{item.type}</Text>
								</Badge>
							</View>
						</View>
					))}
				</View>
			)}
		</View>
	);
}

function NowPlayingSection() {
	const { auth, title, artist, album, playbackStatus } = fixture.nowPlaying;
	const subtitle = [artist, album].filter(Boolean).join(" | ") || "Apple Music";

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Now Playing
			</Text>
			<View className="gap-1">
				<ValueRow label="Music auth" value={auth} />
				{title ? (
					<>
						<Text className="text-sm font-semibold" numberOfLines={1}>
							{title}
						</Text>
						<Text className="text-xs text-muted-foreground" numberOfLines={1}>
							{subtitle}
						</Text>
						<Text className="text-xs text-muted-foreground">
							{playbackStatus}
						</Text>
					</>
				) : (
					<Text className="text-sm text-muted-foreground">
						{auth === "Authorized" ? "Nothing playing" : "Not authorized"}
					</Text>
				)}
			</View>
		</View>
	);
}

function DiagnosticsSection({
	title,
	entries,
}: {
	title: string;
	entries: Record<string, string>;
}) {
	const keys = Object.keys(entries).sort();

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				{title}
			</Text>
			<View className="gap-1">
				{keys.map((key) => (
					<ValueRow
						key={key}
						label={key}
						value={
							<Text selectable className="text-xs text-muted-foreground">
								{entries[key]}
							</Text>
						}
					/>
				))}
			</View>
		</View>
	);
}

function TestSection() {
	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Test
			</Text>
			<Text className="text-sm text-muted-foreground">{fixture.test.note}</Text>
		</View>
	);
}
