import {
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Grid,
  Modal,
  ModalProps,
  Stack,
  SxProps,
  TextField,
  Typography,
} from "@mui/material";
import {
  CameraDevice,
  Html5Qrcode,
  Html5QrcodeCameraScanConfig,
  Html5QrcodeFullConfig,
  Html5QrcodeResult,
  Html5QrcodeScanner,
  Html5QrcodeScannerState,
  QrcodeErrorCallback,
  QrcodeSuccessCallback,
} from "html5-qrcode";
import { Html5QrcodeError } from "html5-qrcode/esm/core";
import { Html5QrcodeScannerConfig } from "html5-qrcode/esm/html5-qrcode-scanner";
import React, {
  RefObject,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useTranslation } from "react-i18next";
import QrCodeScannerIcon from "@mui/icons-material/QrCodeScanner";
import StopCircleOutlinedIcon from "@mui/icons-material/StopCircleOutlined";
import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined";
import { QrCodeInfo } from "@/app/api/qrcode";

const scannerSx: React.CSSProperties = {
  position: "absolute",
  // top: "50%",
  // left: "50%",
  // transform: "translate(-50%, -50%)",
  width: "90%",
  maxHeight: "10%",
  maxWidth: 1400,
};

type QrCodeScannerProps = {
  cameras: CameraDevice[];
  title?: string;
  contents?: string[];
  onScanSuccess: (qrCodeInfo: QrCodeInfo) => void;
  onScanError?: (error: string) => void;
  isOpen: boolean;
  onClose: () => void;
};

const QrCodeScanner: React.FC<QrCodeScannerProps> = ({
  title,
  contents,
  onScanSuccess,
  onScanError,
  isOpen,
  onClose,
}) => {
  const { t } = useTranslation();
  const [isScanned, setIsScanned] = useState<boolean>(false);
  const [scanner, setScanner] = useState<Html5Qrcode | null>(null);
  const [cameraList, setCameraList] = useState<CameraDevice[]>([]);
  const [selectedCameraId, setSelectedCameraId] = useState<string | null>(null);
  const stringList = [
    "ABC: abc",
    "123:123",
    "ABC: abc",
    "123:123",
    "ABC: abc",
    "123:123",
  ];

  const scannerConfig: Html5QrcodeFullConfig = {
    verbose: false,
  };

  const cameraConfig: Html5QrcodeCameraScanConfig = {
    fps: 10,
    qrbox: { width: 250, height: 250 },
    // aspectRatio: cardRef.current ? (cardRef.current.offsetWidth / cardRef.current.offsetHeight) : 1.78,
    aspectRatio: (window.innerWidth / window.innerHeight) * 1.5, // can be better
  };

  // MediaTrackConstraintSet
  const mediaTrackConstraintSet = {
    facingMode: "environment",
  };

  const handleScanStart = useCallback(() => {
    if (scanner && selectedCameraId) {
      if (scanner.getState() === Html5QrcodeScannerState.SCANNING) {
        console.log("first");
        scanner.stop();
      }

      scanner.start(
        selectedCameraId,
        cameraConfig,
        handleScanSuccess,
        handleScanError
      );
    }
  }, [selectedCameraId, scanner]);

  const handleCameraList = useCallback(async () => {
    const cameras = await Html5Qrcode.getCameras();
    setCameraList(cameras);
    if (cameras.length > 0) {
      handleCameraChange(cameras[cameras.length - 1].id);
    }
  }, []);

  const handleCameraChange = useCallback((id: string) => {
    setSelectedCameraId(id);
  }, []);

  const switchScanStatus = useCallback(() => {
    if (scanner) {
      console.log(isScanned);
      switch (isScanned) {
        case true:
          setIsScanned(false);
          scanner.resume();
          break;
        case false:
          setIsScanned(true);
          scanner.pause(true);
          break;
      }
    }
  }, [scanner, isScanned]);

  const handleScanSuccess = useCallback<QrcodeSuccessCallback>(
    (decodedText, result) => {
      if (scanner) {
        console.log(`Decoded text: ${decodedText}`);
        const parseData: QrCodeInfo = JSON.parse(decodedText);
        console.log(parseData);
        // Handle the decoded text as needed
        switchScanStatus();
        onScanSuccess(parseData);
      }
    },
    [scanner, onScanSuccess]
  );

  const handleScanError = useCallback<QrcodeErrorCallback>(
    (errorMessage, error) => {
      // console.log(`Error: ${errorMessage}`);

      if (onScanError) {
        onScanError(errorMessage);
      }
    },
    [scanner, onScanError]
  );

  const handleScanCloseButton = useCallback(async () => {
    if (scanner) {
      console.log("Cleaning up scanner...");
      await scanner.stop();
      scanner.clear();
      onClose();
    }
  }, [scanner]);

  // close modal without using Cancel Button
  const handleScanClose = useCallback(async () => {
    if (scanner && !isOpen) {
      handleScanCloseButton();
    }
  }, [scanner, isOpen, handleScanCloseButton]);

  // -------------------------------------------------------//
  useEffect(() => {
    setScanner(new Html5Qrcode("qr-reader", scannerConfig));

    handleCameraList();
  }, []);

  useEffect(() => {
    handleScanStart();
  }, [scanner, selectedCameraId]);

  useEffect(() => {
    handleScanClose();
  }, [isOpen]);

  return (
    <>
      <Stack spacing={2}>
        {title && (
          <Typography
            variant="overline"
            display="block"
            marginBlockEnd={1}
            paddingLeft={2}
          >
            {"Title"}
          </Typography>
        )}
        <Grid
          container
          alignItems="center"
          justifyContent="center"
          rowSpacing={2}
          columns={{ xs: 6, sm: 12 }}
        >
          <Grid item xs={12}>
            <div
              style={{
                textAlign: "center",
                margin: "auto",
                justifyContent: "center",
              }}
              id="qr-reader"
              hidden={isScanned}
            />
          </Grid>
          {/* {cameraList.length > 0 && <Grid item xs={6} >
                        <Autocomplete
                            disableClearable
                            noOptionsText={t("No Options")}
                            options={cameraList}
                            value={cameraList.find((camera) => camera.id === selectedCameraId)}
                            onChange={((event, value) => {
                                setSelectedCameraId(value.id)
                            })}
                            renderInput={(params) => (
                                <TextField
                                    {...params}
                                    variant="outlined"
                                    label={t("Selected Camera")}
                                />
                            )}
                        />
                    </Grid>} */}
          {contents &&
            contents.map((string) => {
              return (
                <Grid item xs={8}>
                  {string}
                </Grid>
              );
            })}
        </Grid>
        <Stack
          direction="row"
          justifyContent={"flex-end"}
          spacing={2}
          sx={{ margin: 2 }}
        >
          <Button
            size="small"
            onClick={switchScanStatus}
            variant="contained"
            // sx={{ margin: 2 }}
            startIcon={
              isScanned ? <QrCodeScannerIcon /> : <StopCircleOutlinedIcon />
            }
          >
            {isScanned ? t("Start Scanning") : t("Stop Scanning")}
          </Button>
          <Button
            size="small"
            onClick={handleScanCloseButton}
            variant="outlined"
            // color="error"
            // sx={{ margin: 2 }}
            startIcon={<CloseOutlinedIcon />}
          >
            {t("Cancel")}
          </Button>
        </Stack>
      </Stack>
    </>
  );
};

export default QrCodeScanner;
