import axios from "axios";
import { format } from "date-fns-tz";
import Constants from "expo-constants";
import { useFocusEffect } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import { 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";

export default function ProdScanner() {
	const lastScan = useScannerStore((s) => s.lastScan);
	const setLastScan = useScannerStore((s) => s.setLastScan);
	const [tagScans, setTagScans] = useState<any>([]);
	const scannerIdFromStore = useAppStore((s) => s.scannerId);
	const serverIp = useAppStore((s) => s.serverIp);
	const serverPort = useAppStore((s) => s.serverPort);
	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,
			});

			let commandToSend = `${STX}${scannerIdFromStore}@${scan.data}${ETX}`;

			// if we are sscc we need to scan like this .... <STX>98@]C100090087710038712256<ETX>
			if (scan.data.startsWith("000")) {
				commandToSend = `${STX}${scannerIdFromStore}@]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,
				parseInt(serverPort || "0", 10),
			)) as any;
			// send the logs to lst but allow it to time out if it dose not exist just bc.
			const data = {
				...scanned.data,
				runningNumber: scan.data.startsWith("000")
					? parseInt(scan.data.slice(10, -1) || "000", 10).toString()
					: scan.data.startsWith("loc")
						? scan.data
						: "0",
				scannerVersion: build,
			};
			try {
				await axios.post(
					`http://${serverIp.trim()}:3000/lst/api/mobile/logs`,
					data,
				);
			} 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 (/^[a-zA-Z]/.test(scan.data)) {
				setTagScans([]);
			}
		},
		[scannerIdFromStore, serverIp, serverPort, setLastScan, build],
	);

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

	//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-screen`}>
			<View>
				<View style={{ alignItems: "center", margin: 10 }}>
					<Text style={{ fontSize: 15, fontWeight: "600" }}>
						Scanner ID: {parseInt(scannerIdFromStore || "0", 10)}
					</Text>
				</View>
				<Separator />
				{!lastScan ? (
					<View style={{ marginTop: 10, alignItems: "center" }}>
						<Text className="text-xl font-bold">Ready to scan</Text>
						<Text>Waiting for first scan...</Text>
					</View>
				) : (
					<View
						style={{
							marginTop: 10,
							alignItems: "center",
						}}
					>
						{lastScan.lines
							?.filter((line) => !/^\d+@$/.test(line))
							.map((i) => {
								return (
									<View style={{ marginTop: 10, alignItems: "center" }} key={i}>
										<Text style={{ fontSize: 18, fontWeight: "600" }}>{i}</Text>
									</View>
								);
							})}
					</View>
				)}
			</View>
			<Separator className="m-2" />
			<View className="flex-1 w-full px-4">
				<ScannedLabelBox
					labels={tagScans}
					color={bgColor}
					clearScan={clearScans}
				/>
			</View>
			<View>
				<GlobalFooter />
			</View>
		</View>
	);
}
