import * as React from 'react';
import classNames from 'classnames';

interface QRScannerProps {
  onScan: (result: string) => void;
  onError?: (error: Error) => void;
  onClose?: () => void;
  className?: string;
}

export function QRScanner({ onScan, onError, onClose, className }: QRScannerProps) {
  const videoRef = React.useRef<HTMLVideoElement>(null);
  const canvasRef = React.useRef<HTMLCanvasElement>(null);
  const [isScanning, setIsScanning] = React.useState(false);
  const [hasCamera, setHasCamera] = React.useState(true);
  const [cameraError, setCameraError] = React.useState<string | null>(null);
  const streamRef = React.useRef<MediaStream | null>(null);

  const startCamera = React.useCallback(async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: {
          facingMode: 'environment',
          width: { ideal: 1280 },
          height: { ideal: 720 },
        },
      });

      streamRef.current = stream;

      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        await videoRef.current.play();
        setIsScanning(true);
      }
    } catch (err) {
      const error = err as Error;
      setHasCamera(false);
      setCameraError(error.message);
      onError?.(error);
    }
  }, [onError]);

  const stopCamera = React.useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach((track) => track.stop());
      streamRef.current = null;
    }
    setIsScanning(false);
  }, []);

  React.useEffect(() => {
    startCamera();
    return () => stopCamera();
  }, [startCamera, stopCamera]);

  // Simple QR detection simulation (in production, use a library like jsQR)
  React.useEffect(() => {
    if (!isScanning) return;

    const scanInterval = setInterval(() => {
      if (videoRef.current && canvasRef.current) {
        const canvas = canvasRef.current;
        const video = videoRef.current;
        const ctx = canvas.getContext('2d');

        if (ctx && video.readyState === video.HAVE_ENOUGH_DATA) {
          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;
          ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

          // In production, use jsQR library here:
          // const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          // const code = jsQR(imageData.data, imageData.width, imageData.height);
          // if (code) {
          //   stopCamera();
          //   onScan(code.data);
          // }
        }
      }
    }, 100);

    return () => clearInterval(scanInterval);
  }, [isScanning, onScan, stopCamera]);

  // Demo function to simulate a scan
  const simulateScan = () => {
    stopCamera();
    onScan('plant:abc123-tomato-heirloom');
  };

  if (!hasCamera) {
    return (
      <div className={classNames('flex flex-col items-center justify-center p-8 bg-gray-100 rounded-lg', className)}>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          className="h-16 w-16 text-gray-400 mb-4"
          fill="none"
          viewBox="0 0 24 24"
          stroke="currentColor"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
          />
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
        </svg>
        <p className="text-gray-600 text-center mb-2">Camera access denied</p>
        <p className="text-sm text-gray-500 text-center">{cameraError}</p>
        <button
          onClick={startCamera}
          className="mt-4 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700"
        >
          Try again
        </button>
      </div>
    );
  }

  return (
    <div className={classNames('relative overflow-hidden rounded-lg bg-black', className)}>
      {/* Video feed */}
      <video
        ref={videoRef}
        className="w-full h-full object-cover"
        playsInline
        muted
      />

      {/* Hidden canvas for image processing */}
      <canvas ref={canvasRef} className="hidden" />

      {/* Scanning overlay */}
      <div className="absolute inset-0 flex items-center justify-center">
        {/* Darkened corners */}
        <div className="absolute inset-0 bg-black/50" />

        {/* Transparent scanning area */}
        <div className="relative w-64 h-64">
          {/* Cut out the scanning area */}
          <div className="absolute inset-0 border-2 border-white rounded-lg" />

          {/* Corner markers */}
          <div className="absolute top-0 left-0 w-8 h-8 border-t-4 border-l-4 border-green-500 rounded-tl-lg" />
          <div className="absolute top-0 right-0 w-8 h-8 border-t-4 border-r-4 border-green-500 rounded-tr-lg" />
          <div className="absolute bottom-0 left-0 w-8 h-8 border-b-4 border-l-4 border-green-500 rounded-bl-lg" />
          <div className="absolute bottom-0 right-0 w-8 h-8 border-b-4 border-r-4 border-green-500 rounded-br-lg" />

          {/* Scanning line animation */}
          <div className="absolute top-0 left-0 right-0 h-0.5 bg-green-500 animate-scan-line" />
        </div>
      </div>

      {/* Instructions */}
      <div className="absolute bottom-20 left-0 right-0 text-center">
        <p className="text-white text-sm bg-black/50 inline-block px-4 py-2 rounded-full">
          Point camera at QR code
        </p>
      </div>

      {/* Demo scan button (remove in production) */}
      <button
        onClick={simulateScan}
        className="absolute bottom-4 left-1/2 transform -translate-x-1/2 px-6 py-2 bg-green-600 text-white rounded-full text-sm font-medium shadow-lg"
      >
        Demo: Simulate Scan
      </button>

      {/* Close button */}
      {onClose && (
        <button
          onClick={() => {
            stopCamera();
            onClose();
          }}
          className="absolute top-4 right-4 w-10 h-10 bg-black/50 rounded-full flex items-center justify-center"
          aria-label="Close scanner"
        >
          <svg
            xmlns="http://www.w3.org/2000/svg"
            className="h-6 w-6 text-white"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      )}
    </div>
  );
}

export default QRScanner;
