import Ionicons from "@expo/vector-icons/Ionicons";
import { AsyncContent, BadgeTimer, Text } from "ayasofyazilim-mobile-ui";
import {
  CameraCapturedPicture,
  CameraView,
  useCameraPermissions,
} from "expo-camera";
import { parse, ParseResult } from "mrz";
import React, { useRef, useState } from "react";
import { TouchableOpacity, View } from "react-native";
import MlkitOcr, { MlkitOcrResult } from "react-native-mlkit-ocr";
import { AskCameraPermission } from "./components/AskCameraPermission";
import { cropImage } from "./lib/camera";

export function PassportScanner({
  handlePassportScanned,
  isProcessingPassport,
  alignMrzText,
  analyzingText,
  tryAgainText,
}: {
  handlePassportScanned: (mrzResult: ParseResult) => void;
  isProcessingPassport: boolean;
  alignMrzText: string;
  analyzingText: string;
  tryAgainText: string;
}) {
  const cameraRef = useRef<CameraView>(null);
  const [isImageCaptured, setIsImageCaptured] = useState(false);
  const [permission, requestPermission] = useCameraPermissions();
  const [image, setImage] = useState("");
  const [ocrFailed, setOcrFailed] = useState(false);

  function takeAPicture() {
    if (!cameraRef.current || isImageCaptured || isProcessingPassport)
      return;

    cameraRef.current
      .takePictureAsync({ shutterSound: false })
      .then((data) => {
        setIsImageCaptured(true);
        setOcrFailed(false);
        handlePicture(data);
      });
  }
  function prepareText(ocrResult: MlkitOcrResult) {
    function checkIdCard(lines: string[]) {
      while (lines.length > 0) {
        if (!lines[0].startsWith("I<")) {
          lines.shift();
          continue;
        }
        break;
      }
      if (lines.length >= 3) {
        return lines[0] + "\n" + lines[1] + "\n" + lines[2];
      }
      return null;
    }
    function checkPassport(lines: string[]) {
      while (lines.length > 0) {
        if (!lines[0].startsWith("P<")) {
          lines.shift();
          continue;
        }
        break;
      }
      if (lines.length >= 2) {
        return lines[0] + "\n" + lines[1];
      }
      return null;
    }
    const fullText = ocrResult
      .map((t) => t.text)
      .join("\n")
      .toUpperCase()
      .replaceAll(" ", "")
      .replaceAll("«", "<");
    const lines = fullText.split(/\r?\n/);

    const passport = checkPassport([...lines]);
    if (passport) return passport;

    const id = checkIdCard(lines);
    if (id) return id;

    return null;
  }
  function handleNoResult() {
    setIsImageCaptured(false);
    setImage("");
    setOcrFailed(true);
  }
  async function handlePicture(data: CameraCapturedPicture) {
    try {
      const croppedImageUri = await cropImage(data);
      const ocrResult = await MlkitOcr.detectFromUri(croppedImageUri);
      const recognizedText = prepareText(ocrResult);

      console.log(recognizedText);
      if (!recognizedText) {
        handleNoResult();
        console.log("no recognized text");
        return;
      }
      const result = parse(recognizedText, { autocorrect: true });
      handlePassportScanned(result);
      setImage(croppedImageUri);
    } catch (error) {
      console.error(error);
      handleNoResult();
    }
  }

  if (!permission) {
    return <View />;
  }

  if (!permission?.granted) {
    return <AskCameraPermission requestPermission={requestPermission} />;
  }

  if (isImageCaptured) {
    return (
      <View className="flex-1 items-center justify-center">
        <AsyncContent
          loadingIcon="scan-outline"
          isLoading={!image}
          loadingText={analyzingText}
        />
      </View>
    );
  }

  return (
    <View className="flex-1">
      <View className="flex-1 overflow-hidden">
        <View className="flex-1 p-2">
          <CameraView
            ref={cameraRef}
            style={{ flex: 1, borderRadius: 8 }}
            facing={"back"}
            autofocus="on"
          >
            {/* Camera overlay with guidelines */}
            <View className="flex-1 justify-center items-center px-4">
              <View className="border-2 border-white border-dashed w-84 h-48 rounded-lg w-full">
                <View className="flex-1 justify-center items-center">
                  <Text className="text-white text-center text-sm bg-black bg-opacity-50 p-2 rounded">
                    {alignMrzText}
                  </Text>
                </View>
              </View>

              {ocrFailed && (
                <View className="absolute bottom-4">
                  <BadgeTimer duration={5000} text={tryAgainText} />
                </View>
              )}
            </View>
          </CameraView>
        </View>

        {/* Camera controls - Web-like design */}
        <View className="flex-row items-center justify-center p-2">
          {/* Left: Captured image preview */}

          {/* Center: Capture button */}
          <View className="items-center justify-center">
            <TouchableOpacity
              onPress={takeAPicture}
              disabled={isImageCaptured || isProcessingPassport}
              className="rounded-full bg-white items-center justify-center"
            >
              <Ionicons name="radio-button-off-outline" size={64} />
            </TouchableOpacity>
          </View>
        </View>
      </View>
    </View>
  );
}
