import axios from "axios";
import { format } from "date-fns-tz";
import Constants from "expo-constants";
import { Redirect, useFocusEffect, useRouter } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import { Alert, Button, Text, View } from "react-native";
import { useAppStore } from "../hooks/useAppStore";
import { useMobileAuthStore } from "../hooks/useMobileAuth";
import { useScannerStore } from "../hooks/useScannerStore";
import { scannerFeedback } from "../lib/feedbackScan";
import { sendTcpMessage } from "../lib/tcpScan";
import { versionCheck } from "../lib/versionValidation";
import { type ZebraScanResult, zebraScanner } from "../lib/ZebraScanner";
import { ScannedLabelBox } from "./ScannedLabels";
import { GlobalFooter } from "./UpdateFooter";
import { Separator } from "./ui/separator";

const STX = "\x02";
const ETX = "\x03";

const formatName = (name?: string) =>
	name ? name.charAt(0).toUpperCase() + name.slice(1).toLowerCase() : "";

export default function LSTScanner() {
	const user = useMobileAuthStore((s) => s.user);
	const logout = useMobileAuthStore((s) => s.logout);
	const router = useRouter();

	// TODO : move to off tcp stuff after od
	const lastScan = useScannerStore((s) => s.lastScan);
	const setLastScan = useScannerStore((s) => s.setLastScan);
	const [tagScans, setTagScans] = useState<any>([]);
	const serverIp = useAppStore((s) => s.serverIp);
	const [bgColor, setBGColor] = useState<string | null>(null);
	const build = Constants.expoConfig?.android?.versionCode ?? 1;

	const handleScan = useCallback(
		async (scan: ZebraScanResult) => {
			await scannerFeedback({
				type: "scan",
				sound: true,
				vibrate: true,
				led: true,
			});

			const isAlphaStart = /^[a-zA-Z]/.test(scan.data);
			const isExcluded = (user?.excludedCommand ?? []).some((cmd) =>
				scan.data.toLowerCase().includes(cmd.toLowerCase()),
			);

			console.log(user?.excludedCommand);

			if (isAlphaStart && isExcluded) {
				Alert.alert(
					"Command not allowed",
					`Command: ${scan.data}\n\nPlease contact logistics if this is an error`,
				);

				return;
			}

			let commandToSend = `${STX}${user?.scannerId}@${scan.data}${ETX}`;

			// if we are sscc we need to scan like this .... <STX>98@]C100090087710038712256<ETX>
			if (scan.data.startsWith("000")) {
				commandToSend = `${STX}${user?.scannerId}@]C1${scan.data}${ETX}`;
				setTagScans((prev: any) => [
					{
						label: parseInt(scan.data.slice(10, -1) || "000", 10).toString(),
						date: format(new Date(Date.now()), "HH:mm"),
					},
					...prev,
				]);
			}

			const scanned = (await sendTcpMessage(
				commandToSend,
				serverIp,
				50004,
			)) as any;

			// send the logs to lst but allow it to time out if it dose not exist just bc.

			try {
				await axios.post(`http://${serverIp.trim()}:3000/lst/api/mobile/logs`, {
					scannerId: user?.scannerId ?? "0",
					message: scanned.data.message,
					prompt: scanned.data.prompt,
					commandDescription: scanned.data.commandDescription,
					status: scanned.data.status,
					lines: scanned.data.lines,
					user: user?.name ?? "prodScan",
					runningNumber: scan.data.startsWith("000")
						? parseInt(scan.data.slice(10, -1) || "000", 10).toString()
						: scan.data.startsWith("loc")
							? scan.data
							: "0",
					scannerVersion: build,
				});
			} catch (error) {
				console.log(error);
			}
			// const response = await sendTcpMessage(tcpMessage);
			console.log(scanned.data);
			if (scanned.data.status !== "error") {
				await scannerFeedback({
					type: "good",
					sound: true,
					vibrate: true,
					led: true,
				});

				setBGColor("bg-green-500");

				// version check
				versionCheck();

				// auth update
				useMobileAuthStore.getState().updateLastScan();

				setTimeout(() => {
					setBGColor(null);
				}, 1 * 1000);
			}

			if (scanned.data.status === "error") {
				await scannerFeedback({
					type: scanned.data.status === "error" ? "bad" : "good",
					sound: true,
					vibrate: true,
					led: true,
				});
				setBGColor("bg-red-500");
				setTimeout(() => {
					setBGColor(null);
				}, 1 * 1000);
			}
			setLastScan(scanned.data);

			// if we change commands we want to zero out the last scanned labels
			if (isAlphaStart) {
				setTagScans([]);
			}
		},
		[
			serverIp,
			setLastScan,
			user?.scannerId,
			user?.name,
			user?.excludedCommand?.some,
			user?.excludedCommand,
			build,
		],
	);

	const clearScans = () => {
		setTagScans([]);
	};

	const logoutScanner = () => {
		setTagScans([]);
		setLastScan(null);
		logout();
		router.replace("/");
	};

	//console.log(lastScan);

	useFocusEffect(
		useCallback(() => {
			zebraScanner.startListening();

			const sub = zebraScanner.addScanListener((scan) => {
				//console.log("SCAN:", scan);
				handleScan(scan);
			});

			return () => {
				sub.remove();
				zebraScanner.stopListening();
			};
		}, [handleScan]),
	);
	return (
		<View className={`${bgColor ?? ""} flex-1 w-full`}>
			<View className="flex gap-2 items-center">
				<View className="flex flex-col gap-2 items-center">
					<Text style={{ fontSize: 14, fontWeight: "600" }}>
						Lst user: {formatName(user?.name ?? "")}
					</Text>
					{/* <Text style={{ fontSize: 14, fontWeight: "600" }}>
						LST Scanner id: {user?.scannerId}
					</Text> */}
				</View>

				<View
					style={{
						marginTop: 5,
						alignItems: "center",
					}}
				>
					{!lastScan ? (
						<View style={{ marginTop: 2, alignItems: "center" }}>
							<Text className="text-lg font-bold">Ready to scan</Text>
							<Text>Please Scan a command to start scanning...</Text>
							<Text className="text-sm">
								Scanning a label could cause errors due to incorrect previous
								command scanned
							</Text>
						</View>
					) : (
						<View
							style={{
								marginTop: 2,
								alignItems: "center",
							}}
						>
							{lastScan.lines
								?.filter((line) => !/^\d+@$/.test(line))
								.map((i) => {
									return (
										<View
											style={{ marginTop: 2, alignItems: "center" }}
											key={i}
										>
											<Text style={{ fontSize: 12, fontWeight: "600" }}>
												{i}
											</Text>
										</View>
									);
								})}
						</View>
					)}
				</View>
			</View>
			<Separator className="m-2" />
			<View className="flex-1 w-full px-4">
				<ScannedLabelBox
					labels={tagScans}
					color={bgColor}
					clearScan={clearScans}
				/>
				<GlobalFooter />
			</View>

			{/* <View className="m-2">
				{user && (
					<View className="items-center">
						<Button title="Logout" onPress={logoutScanner} />
					</View>
				)}
			</View> */}
			{/* <View style={{ maxHeight: 75 }} className="flex-1 bg-slate-500"></View> */}
		</View>
	);
}
