// src/components/FlyerCorrectionTool.tsx
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { XCircleIcon } from './icons/XCircleIcon';
import { ScissorsIcon } from './icons/ScissorsIcon';
import { RefreshCwIcon } from './icons/RefreshCwIcon';
import * as aiApiClient from '../services/aiApiClient';
import { notifyError, notifySuccess } from '../services/notificationService';
import { logger } from '../services/logger.client';

interface FlyerCorrectionToolProps {
  isOpen: boolean;
  onClose: () => void;
  imageUrl: string;
  onDataExtracted: (type: 'store_name' | 'dates', value: string) => void;
}

type Rect = { x: number; y: number; width: number; height: number };
type ExtractionType = 'store_name' | 'dates';

export const FlyerCorrectionTool: React.FC<FlyerCorrectionToolProps> = ({ isOpen, onClose, imageUrl, onDataExtracted }) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const imageRef = useRef<HTMLImageElement>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [selectionRect, setSelectionRect] = useState<Rect | null>(null);
  const [startPoint, setStartPoint] = useState<{ x: number; y: number } | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [imageFile, setImageFile] = useState<File | null>(null);

  // Fetch the image and store it as a File object for API submission
  useEffect(() => {
    if (isOpen && imageUrl) {
      fetch(imageUrl)
        .then(res => res.blob())
        .then(blob => {
          const file = new File([blob], 'flyer-image.jpg', { type: blob.type });
          setImageFile(file);
        })
        .catch(err => {
          logger.error('Failed to fetch image for correction tool', { err });
          notifyError('Could not load the image for correction.');
        });
    }
  }, [isOpen, imageUrl]);

  const draw = useCallback(() => {
    const canvas = canvasRef.current;
    const image = imageRef.current;
    if (!canvas || !image) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // Set canvas size to match image display size
    canvas.width = image.clientWidth;
    canvas.height = image.clientHeight;

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (selectionRect) {
      ctx.strokeStyle = '#f59e0b'; // amber-500
      ctx.lineWidth = 2;
      ctx.setLineDash([6, 3]);
      ctx.strokeRect(selectionRect.x, selectionRect.y, selectionRect.width, selectionRect.height);
    }
  }, [selectionRect]);

  useEffect(() => {
    draw();
    const handleResize = () => draw();
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, [draw]);

  const getCanvasCoordinates = (e: React.MouseEvent<HTMLCanvasElement>): { x: number; y: number } => {
    const canvas = canvasRef.current;
    if (!canvas) return { x: 0, y: 0 };
    const rect = canvas.getBoundingClientRect();
    return {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top,
    };
  };

  const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {
    setIsDrawing(true);
    setStartPoint(getCanvasCoordinates(e));
    setSelectionRect(null);
  };

  const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (!isDrawing || !startPoint) return;
    const currentPoint = getCanvasCoordinates(e);
    const rect = {
      x: Math.min(startPoint.x, currentPoint.x),
      y: Math.min(startPoint.y, currentPoint.y),
      width: Math.abs(startPoint.x - currentPoint.x),
      height: Math.abs(startPoint.y - currentPoint.y),
    };
    setSelectionRect(rect);
  };

  const handleMouseUp = () => {
    setIsDrawing(false);
    setStartPoint(null);
  };

  const handleRescan = async (type: ExtractionType) => {
    if (!selectionRect || !imageRef.current || !imageFile) {
      notifyError('Please select an area on the image first.');
      return;
    }

    setIsProcessing(true);
    try {
      // Scale selection coordinates to the original image dimensions
      const image = imageRef.current;
      const scaleX = image.naturalWidth / image.clientWidth;
      const scaleY = image.naturalHeight / image.clientHeight;

      const cropArea = {
        x: selectionRect.x * scaleX,
        y: selectionRect.y * scaleY,
        width: selectionRect.width * scaleX,
        height: selectionRect.height * scaleY,
      };

      const response = await aiApiClient.rescanImageArea(imageFile, cropArea, type);
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.message || 'Failed to rescan area.');
      }

      const { text } = await response.json();
      notifySuccess(`Extracted: ${text}`);
      onDataExtracted(type, text);
      onClose(); // Close modal on success
    } catch (err) {
      const msg = err instanceof Error ? err.message : 'An unknown error occurred.';
      notifyError(msg);
      logger.error('Error during rescan:', { err });
    } finally {
      setIsProcessing(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 bg-black bg-opacity-75 z-50 flex justify-center items-center p-4" onClick={onClose}>
      <div role="dialog" className="relative bg-gray-800 rounded-lg shadow-xl w-full max-w-6xl h-[90vh] flex flex-col" onClick={e => e.stopPropagation()}>
        <div className="flex justify-between items-center p-4 border-b border-gray-700">
          <h2 className="text-lg font-semibold text-white flex items-center"><ScissorsIcon className="w-6 h-6 mr-2" /> Flyer Correction Tool</h2>
          <button onClick={onClose} className="text-gray-400 hover:text-white" aria-label="Close correction tool"><XCircleIcon className="w-7 h-7" /></button>
        </div>
        <div className="grow p-4 overflow-auto relative flex justify-center items-center">
          <img ref={imageRef} src={imageUrl} alt="Flyer for correction" className="max-w-full max-h-full object-contain" onLoad={draw} />
          <canvas
            ref={canvasRef}
            className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 cursor-crosshair"
            onMouseDown={handleMouseDown}
            onMouseMove={handleMouseMove}
            onMouseUp={handleMouseUp}
            onMouseLeave={handleMouseUp}
          />
        </div>

        <div className="p-4 border-t border-gray-700 flex items-center justify-center space-x-4">
          {isProcessing ? (
            <div className="flex items-center text-white">
              <RefreshCwIcon className="w-5 h-5 mr-2 animate-spin" />
              <span>Processing...</span>
            </div>
          ) : (
            <>
              <button
                onClick={() => handleRescan('store_name')}
                disabled={!selectionRect || isProcessing}
                className="px-4 py-2 bg-blue-600 text-white rounded-md disabled:bg-gray-500 disabled:cursor-not-allowed hover:bg-blue-700 transition-colors"
              >
                Extract Store Name
              </button>
              <button
                onClick={() => handleRescan('dates')}
                disabled={!selectionRect || isProcessing}
                className="px-4 py-2 bg-green-600 text-white rounded-md disabled:bg-gray-500 disabled:cursor-not-allowed hover:bg-green-700 transition-colors"
              >
                Extract Sale Dates
              </button>
            </>
          )}
        </div>
      </div>
    </div>
  );
};