"use client";

import React, { useState, useEffect, useRef } from "react";
import {
  MdQrCodeScanner,
  MdFlashlightOn,
  MdFlashlightOff,
} from "react-icons/md";
import Quagga from "quagga";
import {
  playScannerSound,
  initializeAudioWithUserInteraction,
} from "@/utils/soundUtils";
import { barcodeToastManager } from "@/utils/barcodeToastManager";

interface BarcodeScannerProps {
  onBarcodeDetected: (barcode: string) => void;
  scannerId?: string;
  title?: string;
  manualPlaceholder?: string;
  manualButtonText?: string;
  className?: string;
}

const BarcodeScanner: React.FC<BarcodeScannerProps> = ({
  onBarcodeDetected,
  scannerId = "common-qr-reader",
  title = "Scan The Barcode On Product",
  manualPlaceholder = "Enter Barcode",
  manualButtonText = "Submit Barcode",
  className = "",
}) => {
  const [isScanning, setIsScanning] = useState(false);
  const [cameraError, setCameraError] = useState<string | null>(null);
  const [isTorchOn, setIsTorchOn] = useState(false);
  const [torchSupported, setTorchSupported] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [scanError, setScanError] = useState<string | null>(null);
  const [manualBarcode, setManualBarcode] = useState("");
  const [audioInitialized, setAudioInitialized] = useState(false);
  const scannerRef = useRef<boolean>(false);
  const processingTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // Keep track of last scanned barcode
  const lastScannedCodeRef = useRef<string | null>(null);

  // Handle barcode scan using QuaggaJS
  const handleBarcodeScanned = async (result: any) => {
    if (isProcessing) return; // Prevent multiple scans

    const decodedText = result.codeResult.code;

    // ✅ Skip duplicate scans
    if (decodedText === lastScannedCodeRef.current) {
      return;
    }
    lastScannedCodeRef.current = decodedText;

    setIsProcessing(true);
    setScanError(null);

    try {
      // Play sound immediately when barcode is detected (before processing)
      playScannerSound().catch(() => {
        // Silent fail - sound will not play
      });

      // Pass the barcode to parent component
      onBarcodeDetected(decodedText.trim());
    } catch (error) {
      console.error("Error processing barcode:", error);
      setScanError("Error processing barcode. Please try again.");
    } finally {
      // Add a small delay before enabling processing again to prevent rapid retriggers
      setTimeout(() => {
        setIsProcessing(false);
      }, 500);
    }
  };

  // Initialize audio on first user interaction
  const initializeAudio = async () => {
    if (!audioInitialized) {
      const result = await initializeAudioWithUserInteraction();
      setAudioInitialized(result);
    }
  };

  // Start scanning function
  const startScanning = async () => {
    try {
      // Ensure audio is initialized before scanning
      await initializeAudio();

      setCameraError(null);
      setIsScanning(true);

      // Wait for DOM to update and element to be visible
      await new Promise((resolve) => setTimeout(resolve, 100));

      // Check if the DOM element exists
      const scannerElement = document.getElementById(scannerId);
      if (!scannerElement) {
        throw new Error(`HTML Element with id=${scannerId} not found`);
      }

      // Determine viewport size for responsive settings
      const isMobile = window.innerWidth < 768;

      // Use auto width for better mobile compatibility
      const cameraConstraints = {
        width: { ideal: 1280 },
        height: { ideal: 720 },
        facingMode: "environment", // Use back camera
      };

      // Initialize QuaggaJS
      Quagga.init(
        {
          inputStream: {
            name: "Live",
            type: "LiveStream",
            target: `#${scannerId}`,
            constraints: cameraConstraints,
            area: {
              top: "20%", // Start 20% from top
              bottom: "20%", // End 20% above bottom
              left: "10%", // 10% padding from left
              right: "10%", // 10% padding from right
            },
          } as any,
          locator: {
            patchSize: "medium", // Use medium for better angle detection
            halfSample: false, // Disable half sampling for better angle detection
          },
          numOfWorkers: isMobile ? 1 : 2,
          frequency: isMobile ? 5 : 10,
          decoder: {
            readers: ["code_128_reader"],
          },
          locate: true,
        },
        (err: any) => {
          if (err) {
            console.error("QuaggaJS initialization failed:", err);
            setIsScanning(false);
            setCameraError(`Unable to start camera: ${err.message || err}`);
            return;
          }

          Quagga.start();
          scannerRef.current = true;

          // Set up the detection handler
          Quagga.onDetected(handleBarcodeScanned);

          // Check torch support after camera starts
          checkTorchSupport();
        }
      );
    } catch (error) {
      console.error("Scanner failed:", error);
      setIsScanning(false);

      if (error instanceof Error && error.name === "NotAllowedError") {
        setCameraError(
          "Camera permission denied. Please allow camera access and try again."
        );
      } else if (error instanceof Error && error.name === "NotFoundError") {
        setCameraError(
          "No camera found. Please check your camera and try again."
        );
      } else if (error instanceof Error && error.name === "NotReadableError") {
        setCameraError("Camera is already in use by another application.");
      } else {
        setCameraError(
          `Unable to start camera: ${
            error instanceof Error ? error.message : String(error)
          }`
        );
      }
    }
  };

  // Stop scanning function
  const stopScanning = async () => {
    if (scannerRef.current) {
      try {
        Quagga.stop();
        Quagga.offDetected(handleBarcodeScanned);
        scannerRef.current = false;
        setIsScanning(false);
        setIsTorchOn(false);
        setTorchSupported(false);
        setIsProcessing(false);
        setScanError(null);

        // Clean up video and canvas elements
        const scannerElement = document.getElementById(scannerId);
        if (scannerElement) {
          // Remove all video and canvas elements
          const videoElements = scannerElement.querySelectorAll("video");
          const canvasElements = scannerElement.querySelectorAll("canvas");

          videoElements.forEach((video) => video.remove());
          canvasElements.forEach((canvas) => canvas.remove());

          // Clear the scanner container
          scannerElement.innerHTML = "";
        }

        // Clear any pending processing timeout
        if (processingTimeoutRef.current) {
          clearTimeout(processingTimeoutRef.current);
          processingTimeoutRef.current = null;
        }
      } catch (error) {
        console.error("Error stopping scanner:", error);
      }
    }
  };

  // Toggle torch function
  const toggleTorch = async () => {
    if (!scannerRef.current || !torchSupported) return;

    try {
      // Access video element from QuaggaJS
      const videoElement = document.querySelector(
        `#${scannerId} video`
      ) as HTMLVideoElement;
      if (videoElement && videoElement.srcObject) {
        const stream = videoElement.srcObject as MediaStream;
        const videoTrack = stream.getVideoTracks()[0];
        if (videoTrack) {
          await videoTrack.applyConstraints({
            // @ts-ignore - torch property may not be in TypeScript definitions
            advanced: [{ torch: !isTorchOn }],
          });
          setIsTorchOn(!isTorchOn);
        }
      }
    } catch (error) {
      console.error("Error toggling torch:", error);
    }
  };

  // Check torch support when scanning starts
  const checkTorchSupport = async () => {
    if (!scannerRef.current) return;

    try {
      // Wait a bit for the camera to initialize
      await new Promise((resolve) => setTimeout(resolve, 1000));

      // Get capabilities from video element directly
      const videoElement = document.querySelector(
        `#${scannerId} video`
      ) as HTMLVideoElement;
      if (videoElement && videoElement.srcObject) {
        const stream = videoElement.srcObject as MediaStream;
        const videoTrack = stream.getVideoTracks()[0];
        if (videoTrack && typeof videoTrack.getCapabilities === "function") {
          const capabilities = videoTrack.getCapabilities();
          // @ts-ignore - torch property may not be in TypeScript definitions
          setTorchSupported(capabilities.torch || false);
        }
      }
    } catch (error) {
      console.warn("Could not check torch capabilities:", error);
      setTorchSupported(false);
    }
  };

  // Handle manual barcode submit
  const handleManualSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!manualBarcode.trim()) return;

    // Ensure audio is initialized before playing sound
    await initializeAudio();

    // Play sound immediately for manual submission
    playScannerSound().catch(() => {
      // Silent fail - sound will not play
    });

    // Pass the barcode to parent component
    onBarcodeDetected(manualBarcode.trim());

    // Clear the input after submission
    setManualBarcode("");
  };

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (scannerRef.current) {
        try {
          Quagga.stop();
          Quagga.offDetected(handleBarcodeScanned);

          // Clean up video and canvas elements
          const scannerElement = document.getElementById(scannerId);
          if (scannerElement) {
            const videoElements = scannerElement.querySelectorAll("video");
            const canvasElements = scannerElement.querySelectorAll("canvas");

            videoElements.forEach((video) => video.remove());
            canvasElements.forEach((canvas) => canvas.remove());

            scannerElement.innerHTML = "";
          }
        } catch (error) {
          console.error("Error during cleanup:", error);
        }
      }
      if (processingTimeoutRef.current) {
        clearTimeout(processingTimeoutRef.current);
      }
    };
  }, [scannerId]);

  return (
    <div className={`${className}`}>
      {/* Upper Half - Scanning Section */}
      <div className="flex-1 flex flex-col">
        <h2 className="text-md font-bold mb-4 text-gray-800 text-center">
          {title}
        </h2>

        {/* Scanner Section */}
        <div className="flex-grow flex flex-col items-center justify-center">
          <div className="w-full max-w-md">
            {/* Toggle Scanning Button - Always at top */}
            <div className="flex justify-center gap-3 mb-6">
              <button
                onClick={isScanning ? stopScanning : startScanning}
                className={`flex items-center px-6 py-3 rounded-xl transition-colors font-medium ${
                  isScanning
                    ? "bg-red-500 text-white hover:bg-red-600"
                    : "bg-white border border-gray-500 text-black hover:bg-blue-50"
                }`}
              >
                <MdQrCodeScanner className="h-5 w-5 mr-2" />
                {isScanning ? "Stop Scanning" : "Start Scanning"}
              </button>

              {/* Torch Button - Only show when scanning and torch is supported */}
              {isScanning && torchSupported && (
                <button
                  onClick={toggleTorch}
                  className={`flex items-center px-4 py-3 rounded-xl transition-colors font-medium ${
                    isTorchOn
                      ? "bg-yellow-500 text-white hover:bg-yellow-600"
                      : "bg-gray-100 text-gray-700 hover:bg-gray-200 border border-gray-300"
                  }`}
                  title={
                    isTorchOn ? "Turn off flashlight" : "Turn on flashlight"
                  }
                >
                  {isTorchOn ? (
                    <MdFlashlightOn className="h-5 w-5" />
                  ) : (
                    <MdFlashlightOff className="h-5 w-5" />
                  )}
                </button>
              )}
            </div>

            {/* Content Area */}
            <div className="flex justify-center">
              {isScanning ? (
                /* Scanner Container - Active when scanning */
                <div
                  id={scannerId}
                  className="rounded-lg overflow-hidden w-full"
                  style={{
                    height: "192px", // h-48 = 192px to match QR visual
                    border: "2px solid #3997e0",
                    backgroundColor: "#f8fafc",
                  }}
                ></div>
              ) : (
                /* QR Code Visual - Show when not scanning */
                <div className="w-48 h-48 bg-blue-50 flex items-center justify-center rounded-lg">
                  <MdQrCodeScanner size={100} />
                </div>
              )}
            </div>

            {/* Hidden scanner container for DOM presence */}
            {!isScanning && (
              <div id={scannerId} style={{ display: "none" }}></div>
            )}
          </div>

          {/* Error Display */}
          {cameraError && (
            <div className="mt-4 p-3 bg-red-100 border border-red-400 rounded text-sm text-red-700">
              <p className="font-medium">Error:</p>
              <p>{cameraError}</p>
              <button
                onClick={() => {
                  setCameraError(null);
                  setIsScanning(false);
                }}
                className="mt-2 text-xs underline hover:no-underline"
              >
                Try Again
              </button>
            </div>
          )}

          {/* Scan Error Display */}
          {scanError && (
            <div className="mt-4 p-3 bg-orange-100 border border-orange-400 rounded text-sm text-orange-700">
              <p className="font-medium">Scan Error:</p>
              <p>{scanError}</p>
            </div>
          )}

          {/* Processing Indicator */}
          {isProcessing && (
            <div className="mt-4 p-3 bg-blue-100 border border-blue-400 rounded text-sm text-blue-700">
              <div className="flex items-center">
                <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-700 mr-2"></div>
                <p className="font-medium">Processing barcode...</p>
              </div>
            </div>
          )}
        </div>

        {/* Manual Entry Section */}
        <div className="mt-4">
          <h3 className="text-sm font-semibold mb-3 text-gray-800 text-center">
            Enter Barcode Manually
          </h3>

          <form onSubmit={handleManualSubmit}>
            <div className="relative mb-3">
              <input
                type="text"
                placeholder={manualPlaceholder}
                className="w-full p-3 pl-12 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 text-black bg-white"
                value={manualBarcode}
                onChange={(e) => setManualBarcode(e.target.value)}
              />
              <div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
                <MdQrCodeScanner className="text-gray-400 h-5 w-5" />
              </div>
            </div>
            <button
              type="submit"
              disabled={!manualBarcode.trim()}
              className={`w-full py-2 rounded-md text-sm font-medium transition-colors ${
                manualBarcode.trim()
                  ? "bg-[#3997E0] text-white hover:bg-blue-700"
                  : "bg-gray-300 text-gray-500 cursor-not-allowed"
              }`}
            >
              {manualButtonText}
            </button>
          </form>
        </div>
      </div>

      {/* Simple CSS for QuaggaJS styling */}
      <style jsx global>{`
        #${scannerId} {
          width: 100% !important;
          height: 192px !important;
        }
        #${scannerId} canvas,
        #${scannerId} video {
          width: 100% !important;
          height: 100% !important;
          object-fit: cover;
          border-radius: 8px;
        }

        /* Mobile-specific optimizations */
        @media (max-width: 768px) {
          #${scannerId} {
            height: 160px !important;
          }
          #${scannerId} canvas,
          #${scannerId} video {
            object-fit: cover;
          }
        }
      `}</style>
    </div>
  );
};

export default BarcodeScanner;
