import { useEffect, useState, type ReactNode } from "react";
import { Pressable, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import * as Clipboard from "expo-clipboard";

import { Container } from "@/components/Container";
import { SafeAreaScrollView } from "@/components/safe-area-scroll-view";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import { Ble } from "@aris/ble";
import { useBleStore } from "@/store/ble";
import { cn } from "@/lib/utils";
import { Ionicons } from "@expo/vector-icons";

const formatTime = (timestamp: number | null) => {
	if (!timestamp) {
		return "Never";
	}
	return new Date(timestamp).toLocaleTimeString();
};

export default function BleScreen() {
	const initialize = useBleStore((state) => state.initialize);
	const isSupported = useBleStore((state) => state.isSupported);
	const insets = useSafeAreaInsets();

	useEffect(() => {
		initialize();
	}, [initialize]);

	if (!isSupported) {
		return (
			<View className="flex flex-1 bg-white">
				<Container className="px-8">
					<View className="gap-1">
						<Text variant="h3">BLE</Text>
						<Text className="text-sm text-muted-foreground">
							Bluetooth peripheral status and controls.
						</Text>
					</View>
					<View className="mt-4 rounded-xl border border-muted bg-muted/20 px-4 py-3">
						<Text className="text-sm font-medium">BLE Unavailable</Text>
						<Text className="text-sm text-muted-foreground">
							This page is currently supported on iOS only.
						</Text>
					</View>
				</Container>
			</View>
		);
	}

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

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

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

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

						<View className="w-full h-px bg-muted" />
						<UuidsSection />
					</View>
				</SafeAreaScrollView>
			</View>
		</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 BleStatusSection() {
	const bluetoothState = useBleStore((state) => state.bluetoothState);
	const isSubscribed = useBleStore((state) => state.isSubscribed);
	const subscribedCount = useBleStore((state) => state.subscribedCount);
	const connectionLabel = isSubscribed ? "Connected" : "Not Connected";

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Status
			</Text>
			<View className="gap-1">
				<ValueRow label="State" value={connectionLabel} />
				<ValueRow label="Bluetooth" value={bluetoothState} />
				<ValueRow label="Subscribers" value={subscribedCount} />
			</View>
		</View>
	);
}

function ControlPanel() {
	const advertisingEnabled = useBleStore((state) => state.advertisingEnabled);
	const setAdvertisingEnabled = useBleStore(
		(state) => state.setAdvertisingEnabled,
	);
	const wifiRequested = useBleStore((state) => state.wifiRequested);
	const setWifiRequested = useBleStore((state) => state.setWifiRequested);
	const sendFixtureFeedNow = useBleStore((state) => state.sendFixtureFeedNow);
	const handleCopyUUIDs = async () => {
		const uuids = Ble.getUuids();
		const text = [
			`SERVICE_UUID=${uuids.serviceUUID}`,
			`FEED_TX_UUID=${uuids.feedTxUUID}`,
			`CONTROL_RX_UUID=${uuids.controlRxUUID}`,
			`WIFI_REQUEST_TX_UUID=${uuids.wifiRequestTxUUID}`,
		].join("\n");
		await Clipboard.setStringAsync(text);
	};

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-3 font-medium">
				Control Panel
			</Text>

			<View className="flex-row gap-3 w-full mb-3">
				<ControlTile
					icon={<Ionicons name="radio-outline" size={20} />}
					label="Advertising"
					checked={advertisingEnabled}
					onCheckChange={setAdvertisingEnabled}
				/>
				<ControlTile
					icon={<Ionicons name="wifi-outline" size={20} />}
					label="WiFi"
					checked={wifiRequested}
					onCheckChange={setWifiRequested}
				/>
			</View>

			<View className="gap-2">
				<Button onPress={sendFixtureFeedNow} variant="outline">
					<Text>Send Fixture Feed Now</Text>
				</Button>
				<Button onPress={handleCopyUUIDs} variant="outline">
					<Text>Copy UUIDs</Text>
				</Button>
			</View>
		</View>
	);
}

function ControlTile({
	icon,
	label,
	checked,
	onCheckChange,
}: {
	icon: ReactNode;
	label: ReactNode;
	checked: boolean;
	onCheckChange: (checked: boolean) => void;
}) {
	const [isPressed, setIsPressed] = useState(false);
	return (
		<Pressable
			onPressIn={() => {
				setIsPressed(true);
			}}
			onPressOut={() => {
				setIsPressed(false);
			}}
			onPress={() => {
				onCheckChange(!checked);
			}}
			className={cn(
				"flex-1 items-start justify-center rounded-md px-3 py-2 gap-1",
				checked ? "border-2 border-primary" : "border border-border",
				{ "bg-accent": isPressed },
			)}
		>
			{icon}
			<Text className={cn({ "font-bold": checked })}>{label}</Text>
		</Pressable>
	);
}

function TelemetrySection() {
	const lastMsgIdSent = useBleStore((state) => state.lastMsgIdSent);
	const lastPingAt = useBleStore((state) => state.lastPingAt);
	const lastDataAt = useBleStore((state) => state.lastDataAt);
	const lastNotifyAt = useBleStore((state) => state.lastNotifyAt);
	const notifyQueueDepth = useBleStore((state) => state.notifyQueueDepth);
	const droppedNotifyPackets = useBleStore(
		(state) => state.droppedNotifyPackets,
	);
	const lastCommand = useBleStore((state) => state.lastCommand);

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				Telemetry
			</Text>
			<View className="gap-1">
				<ValueRow label="Last msgId" value={lastMsgIdSent} />
				<ValueRow label="Last ping" value={formatTime(lastPingAt)} />
				<ValueRow label="Last data" value={formatTime(lastDataAt)} />
				<ValueRow label="Notify queue" value={notifyQueueDepth} />
				{droppedNotifyPackets > 0 ? (
					<ValueRow
						label="Dropped notify packets"
						value={droppedNotifyPackets}
					/>
				) : null}
				<ValueRow label="Last notify" value={formatTime(lastNotifyAt)} />
				{lastCommand ? (
					<ValueRow label="Last control" value={lastCommand} />
				) : null}
			</View>
		</View>
	);
}

function UuidsSection() {
	const uuids = Ble.getUuids();

	return (
		<View className="px-8">
			<Text variant="h4" className="mb-2 font-medium">
				UUIDs
			</Text>
			<Text selectable className="text-xs text-muted-foreground">
				{`SERVICE_UUID=${uuids.serviceUUID}\nFEED_TX_UUID=${uuids.feedTxUUID}\nCONTROL_RX_UUID=${uuids.controlRxUUID}\nWIFI_REQUEST_TX_UUID=${uuids.wifiRequestTxUUID}`}
			</Text>
		</View>
	);
}
