"use client";
import {
  ReactNode,
  createContext,
  useCallback,
  useContext,
  useEffect,
  useState,
} from "react";

export interface QrCodeScanner {
  values: string[];
  isScanning: boolean;
  startScan: () => void;
  stopScan: () => void;
  resetScan: () => void;
}

interface QrCodeScannerProviderProps {
  children: ReactNode;
}

export const QrCodeScannerContext = createContext<QrCodeScanner | undefined>(
  undefined,
);

const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({
  children,
}) => {
  const [qrCodeScannerValues, setQrCodeScannerValues] = useState<string[]>([]);
  const [isScanning, setIsScanning] = useState<boolean>(false);
  const [keys, setKeys] = useState<string[]>([]);
  const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0);
  const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0);
  const resetQrCodeScanner = useCallback(() => {
    setQrCodeScannerValues(() => []);
  }, []);

  const startQrCodeScanner = useCallback(() => {
    resetQrCodeScanner();
    setIsScanning(() => true);
  }, []);

  const endQrCodeScanner = useCallback(() => {
    setIsScanning(() => false);
  }, []);

  // Check the KeyDown
  useEffect(() => {
    if (isScanning) {
      const handleKeyDown = (event: KeyboardEvent) => {
        if (event.key.length === 1) {
          setKeys((key) => [...key, event.key]);
        }

        if (event.key === "{") {
          setLeftCurlyBraceCount((count) => count + 1);
        } else if (event.key === "}") {
          setRightCurlyBraceCount((count) => count + 1);
        }
      };

      document.addEventListener("keydown", handleKeyDown);

      return () => {
        document.removeEventListener("keydown", handleKeyDown);
      };
    }
  }, [isScanning]);

  // Update Qr Code Scanner Values
  useEffect(() => {
    if (
      leftCurlyBraceCount !== 0 &&
      rightCurlyBraceCount !== 0 &&
      leftCurlyBraceCount === rightCurlyBraceCount
    ) {
      const startBrace = keys.indexOf("{");
      const endBrace = keys.lastIndexOf("}");
      setQrCodeScannerValues((value) => [
        ...value,
        keys.join("").substring(startBrace, endBrace + 1),
      ]);
      console.log(keys);
      console.log("%c QR Scanner Values:", "color:cyan", qrCodeScannerValues);

      // reset
      setKeys(() => []);
      setLeftCurlyBraceCount(() => 0);
      setRightCurlyBraceCount(() => 0);
    }
  }, [keys, leftCurlyBraceCount, rightCurlyBraceCount]);

  return (
    <QrCodeScannerContext.Provider
      value={{
        values: qrCodeScannerValues,
        isScanning: isScanning,
        startScan: startQrCodeScanner,
        stopScan: endQrCodeScanner,
        resetScan: resetQrCodeScanner,
      }}
    >
      {children}
    </QrCodeScannerContext.Provider>
  );
};

export const useQrCodeScannerContext = (): QrCodeScanner => {
  const context = useContext(QrCodeScannerContext);
  if (!context) {
    throw new Error(
      "useQrCodeScanner must be used within a QrCodeScannerProvider",
    );
  }
  return context;
};

export default QrCodeScannerProvider;
