"use client";

import React, { useState, useRef, useEffect } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { Camera, CameraOff, CheckCircle2, AlertCircle, Scan } from "lucide-react";
import Webcam from "react-webcam";
import { BrowserMultiFormatReader, NotFoundException } from "@zxing/library";

export interface BarcodeScanModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  targetField?: string;
  barcodeFormat?: "all" | "1d" | "2d";
  autoSubmit?: boolean;
  onScanSuccess: (barcode: string) => void;
  userId?: string;
}

export const BarcodeScanModal: React.FC<BarcodeScanModalProps> = ({
  open,
  onOpenChange,
  targetField,
  barcodeFormat = "all",
  autoSubmit = false,
  onScanSuccess,
  userId = "guest",
}) => {
  const [isScanning, setIsScanning] = useState(false);
  const [scannedCode, setScannedCode] = useState<string>("");
  const [error, setError] = useState<string>("");
  const [hasPermission, setHasPermission] = useState<boolean | null>(null);
  const webcamRef = useRef<Webcam>(null);
  const codeReaderRef = useRef<BrowserMultiFormatReader | null>(null);
  const scanIntervalRef = useRef<NodeJS.Timeout | null>(null);

  // 바코드 리더 초기화 + 모달 열릴 때 상태 리셋
  useEffect(() => {
    if (open) {
      setScannedCode("");
      setError("");
      setIsScanning(false);
      codeReaderRef.current = new BrowserMultiFormatReader();
    }

    return () => {
      stopScanning();
      if (codeReaderRef.current) {
        codeReaderRef.current.reset();
      }
    };
  }, [open]);

  // 카메라 권한 요청
  const requestCameraPermission = async () => {
    console.log("🎥 카메라 권한 요청 시작...");
    
    // navigator.mediaDevices 지원 확인
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      console.error("❌ navigator.mediaDevices를 사용할 수 없습니다.");
      console.log("현재 프로토콜:", window.location.protocol);
      console.log("현재 호스트:", window.location.host);
      setHasPermission(false);
      setError(
        "이 브라우저는 카메라 접근을 지원하지 않거나, 보안 컨텍스트(HTTPS 또는 localhost)가 아닙니다. " +
        "현재 프로토콜: " + window.location.protocol
      );
      toast.error("카메라 접근이 불가능합니다. 콘솔을 확인해주세요.");
      return;
    }

    try {
      console.log("🔄 getUserMedia 호출 중...");
      const stream = await navigator.mediaDevices.getUserMedia({ video: true });
      console.log("✅ 카메라 권한 허용됨!");
      setHasPermission(true);
      stream.getTracks().forEach((track) => track.stop()); // 권한 확인 후 스트림 종료
      toast.success("카메라 권한이 허용되었습니다.");
    } catch (err: any) {
      console.error("❌ 카메라 권한 오류:", err);
      console.error("에러 이름:", err.name);
      console.error("에러 메시지:", err.message);
      setHasPermission(false);
      
      // 에러 타입에 따라 다른 메시지 표시
      if (err.name === "NotAllowedError") {
        setError("카메라 접근이 거부되었습니다. 브라우저 설정에서 카메라 권한을 허용해주세요.");
        toast.error("카메라 권한이 거부되었습니다.");
      } else if (err.name === "NotFoundError") {
        setError("카메라를 찾을 수 없습니다. 카메라가 연결되어 있는지 확인해주세요.");
        toast.error("카메라를 찾을 수 없습니다.");
      } else if (err.name === "NotReadableError") {
        setError("카메라가 이미 다른 애플리케이션에서 사용 중입니다.");
        toast.error("카메라가 사용 중입니다.");
      } else if (err.name === "NotSupportedError") {
        setError("보안 컨텍스트(HTTPS 또는 localhost)가 아니어서 카메라를 사용할 수 없습니다.");
        toast.error("HTTPS 환경이 필요합니다.");
      } else {
        setError(`카메라 접근 오류: ${err.name} - ${err.message}`);
        toast.error("카메라 접근 중 오류가 발생했습니다.");
      }
    }
  };

  // 스캔 시작
  const startScanning = () => {
    setIsScanning(true);
    setError("");
    setScannedCode("");

    // 주기적으로 스캔 시도 (500ms마다)
    scanIntervalRef.current = setInterval(() => {
      scanBarcode();
    }, 500);
  };

  // 스캔 중지
  const stopScanning = () => {
    setIsScanning(false);
    if (scanIntervalRef.current) {
      clearInterval(scanIntervalRef.current);
      scanIntervalRef.current = null;
    }
  };

  // 바코드 스캔
  const scanBarcode = async () => {
    if (!webcamRef.current || !codeReaderRef.current) return;

    try {
      const imageSrc = webcamRef.current.getScreenshot();
      if (!imageSrc) return;

      // 이미지를 HTMLImageElement로 변환
      const img = new Image();
      img.src = imageSrc;

      await new Promise((resolve) => {
        img.onload = resolve;
      });

      // 바코드 디코딩
      const result = await codeReaderRef.current.decodeFromImageElement(img);

      if (result) {
        const barcode = result.getText();
        console.log("✅ 바코드 스캔 성공:", barcode);

        setScannedCode(barcode);
        stopScanning();
        toast.success(`바코드 스캔 완료: ${barcode}`);

        // 자동 제출 옵션이 켜져있으면 바로 콜백 실행
        if (autoSubmit) {
          onScanSuccess(barcode);
        }
      }
    } catch (err) {
      // NotFoundException은 정상적인 상황 (바코드가 아직 인식되지 않음)
      if (!(err instanceof NotFoundException)) {
        console.error("바코드 스캔 오류:", err);
      }
    }
  };

  // 수동 확인 버튼
  const handleConfirm = () => {
    if (scannedCode) {
      onScanSuccess(scannedCode);
    } else {
      toast.error("스캔된 바코드가 없습니다.");
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[95vw] sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">바코드 스캔</DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            카메라로 바코드를 스캔합니다.
            {targetField && ` (대상 필드: ${targetField})`}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 카메라 권한 요청 대기 중 */}
          {hasPermission === null && (
            <div className="rounded-md border border-primary bg-primary/10 p-4">
              <div className="flex items-start gap-3">
                <Camera className="mt-0.5 h-5 w-5 flex-shrink-0 text-primary" />
                <div className="flex-1 space-y-3 text-xs sm:text-sm">
                  <div>
                    <p className="font-semibold text-primary">카메라 권한이 필요합니다</p>
                    <p className="mt-1 text-muted-foreground">
                      바코드를 스캔하려면 카메라 접근 권한을 허용해주세요.
                    </p>
                  </div>

                  <div className="rounded-md bg-background/50 p-3">
                    <p className="mb-2 font-medium text-foreground">💡 권한 요청 안내:</p>
                    <ul className="ml-4 list-disc space-y-1 text-muted-foreground">
                      <li>아래 버튼을 클릭하면 브라우저에서 권한 요청 팝업이 표시됩니다</li>
                      <li>팝업에서 <strong>"허용"</strong> 버튼을 클릭해주세요</li>
                      <li>권한은 언제든지 브라우저 설정에서 변경할 수 있습니다</li>
                    </ul>
                  </div>

                  <div className="flex items-center gap-2">
                    <Button
                      onClick={requestCameraPermission}
                      className="h-9 text-xs sm:h-10 sm:text-sm"
                    >
                      <Camera className="mr-2 h-4 w-4" />
                      카메라 권한 요청
                    </Button>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* 카메라 권한 거부됨 */}
          {hasPermission === false && (
            <div className="rounded-md border border-destructive bg-destructive/10 p-4">
              <div className="flex items-start gap-3">
                <AlertCircle className="mt-0.5 h-5 w-5 flex-shrink-0 text-destructive" />
                <div className="flex-1 space-y-3 text-xs sm:text-sm">
                  <div>
                    <p className="font-semibold text-destructive">카메라 접근 권한이 필요합니다</p>
                    <p className="mt-1 text-destructive/80">{error}</p>
                  </div>

                  <div className="rounded-md bg-background/50 p-3">
                    <p className="mb-2 font-medium text-foreground">📱 권한 허용 방법:</p>
                    <ol className="ml-4 list-decimal space-y-1 text-muted-foreground">
                      <li>브라우저 주소창 왼쪽의 <strong>🔒 자물쇠 아이콘</strong>을 클릭하세요</li>
                      <li><strong>"카메라"</strong> 항목을 찾아 <strong>"허용"</strong>으로 변경하세요</li>
                      <li>페이지를 새로고침하거나 다시 스캔을 시도하세요</li>
                    </ol>
                  </div>

                  <div className="flex items-center gap-2">
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={requestCameraPermission}
                      className="h-8 text-xs"
                    >
                      다시 시도
                    </Button>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* 웹캠 뷰 */}
          {hasPermission && (
            <div className="relative aspect-video overflow-hidden rounded-lg border border-border bg-muted">
              <Webcam
                ref={webcamRef}
                audio={false}
                screenshotFormat="image/jpeg"
                videoConstraints={{
                  facingMode: "environment", // 후면 카메라 우선
                }}
                className="h-full w-full object-cover"
              />

              {/* 스캔 가이드 오버레이 */}
              {isScanning && (
                <div className="absolute inset-0 flex items-center justify-center">
                  <div className="h-3/5 w-4/5 rounded-lg border-4 border-primary/70 animate-pulse" />
                  <div className="absolute bottom-4 left-0 right-0 text-center">
                    <div className="inline-flex items-center gap-2 rounded-full bg-background/80 px-4 py-2 text-xs font-medium">
                      <Scan className="h-4 w-4 animate-pulse text-primary" />
                      스캔 중...
                    </div>
                  </div>
                </div>
              )}

              {/* 스캔 완료 오버레이 */}
              {scannedCode && (
                <div className="absolute inset-0 flex items-center justify-center bg-background/80">
                  <div className="text-center">
                    <CheckCircle2 className="mx-auto h-16 w-16 text-success" />
                    <p className="mt-2 text-sm font-medium">스캔 완료!</p>
                    <p className="mt-1 font-mono text-lg font-bold text-primary">{scannedCode}</p>
                  </div>
                </div>
              )}
            </div>
          )}

          {/* 바코드 포맷 정보 */}
          <div className="rounded-md border border-border bg-muted/50 p-3">
            <div className="flex items-start gap-2">
              <AlertCircle className="mt-0.5 h-4 w-4 text-muted-foreground" />
              <div className="text-[10px] text-muted-foreground sm:text-xs">
                <p className="font-medium">지원 포맷</p>
                <p className="mt-1">
                  {barcodeFormat === "all" && "1D/2D 바코드 모두 지원 (Code 128, QR Code 등)"}
                  {barcodeFormat === "1d" && "1D 바코드 (Code 128, Code 39, EAN-13, UPC-A)"}
                  {barcodeFormat === "2d" && "2D 바코드 (QR Code, Data Matrix)"}
                </p>
              </div>
            </div>
          </div>

          {/* 에러 메시지 */}
          {error && (
            <div className="rounded-md border border-destructive bg-destructive/10 p-3">
              <div className="flex items-start gap-2">
                <AlertCircle className="mt-0.5 h-4 w-4 text-destructive" />
                <p className="text-xs text-destructive">{error}</p>
              </div>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>

          {!isScanning && !scannedCode && hasPermission && (
            <Button
              onClick={startScanning}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              <Camera className="mr-2 h-4 w-4" />
              스캔 시작
            </Button>
          )}

          {isScanning && (
            <Button
              variant="destructive"
              onClick={stopScanning}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              <CameraOff className="mr-2 h-4 w-4" />
              스캔 중지
            </Button>
          )}

          {scannedCode && (
            <Button
              variant="outline"
              onClick={() => {
                setScannedCode("");
                startScanning();
              }}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              <Camera className="mr-2 h-4 w-4" />
              다시 스캔
            </Button>
          )}

          {scannedCode && !autoSubmit && (
            <Button
              onClick={handleConfirm}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              <CheckCircle2 className="mr-2 h-4 w-4" />
              확인
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

