import React, { useEffect, useRef, useState, useCallback } from 'react';
import { Stage, Layer, Image as KonvaImage, Circle, Rect, Path, Group } from 'react-konva';
import useImage from 'use-image';
import { useStore } from '../store/useStore';
import { predictMask } from '../lib/api';
import { cn } from '../lib/utils';

interface CanvasAreaProps {
  activeTool: string;
}

export function CanvasArea({ activeTool }: CanvasAreaProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [stageSize, setStageSize] = useState({ width: 800, height: 600 });
  const [scale, setScale] = useState(1);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [points, setPoints] = useState<{ x: number, y: number, type: 'pos'|'neg' }[]>([]);
  const [cursorPos, setCursorPos] = useState({ x: 0, y: 0 });
  const [boxStart, setBoxStart] = useState<{ x: number, y: number } | null>(null);
  const [boxCurrent, setBoxCurrent] = useState<{ x: number, y: number } | null>(null);
  const [isInferencing, setIsInferencing] = useState(false);

  const masks = useStore((state) => state.masks);
  const addMask = useStore((state) => state.addMask);
  const clearMasks = useStore((state) => state.clearMasks);
  const storeActiveTool = useStore((state) => state.activeTool);
  const setActiveTool = useStore((state) => state.setActiveTool);

  const effectiveTool = activeTool || storeActiveTool;

  // We load a mock image representing a frame
  const [image] = useImage('https://images.unsplash.com/photo-1549317661-bd32c8ce0be2?q=80&w=2070&auto=format&fit=crop');

  useEffect(() => {
    const handleResize = () => {
      if (containerRef.current) {
        setStageSize({
          width: containerRef.current.clientWidth,
          height: containerRef.current.clientHeight,
        });
      }
    };
    
    handleResize();
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  const handleWheel = (e: any) => {
    e.evt.preventDefault();
    const scaleBy = 1.1;
    const stage = e.target.getStage();
    const oldScale = stage.scaleX();

    const mousePointTo = {
      x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
      y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale,
    };

    const newScale = e.evt.deltaY < 0 ? oldScale * scaleBy : oldScale / scaleBy;
    setScale(newScale);
    setPosition({
      x: -(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale,
      y: -(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale,
    });
  };

  const handleMouseMove = (e: any) => {
    const stage = e.target.getStage();
    if (!stage) return;
    const pos = stage.getPointerPosition();
    if (pos) {
       const imageX = (pos.x - position.x) / scale;
       const imageY = (pos.y - position.y) / scale;
       setCursorPos({ x: imageX, y: imageY });
    }

    if (boxStart && effectiveTool === 'box_select') {
      const relPos = stage.getRelativePointerPosition();
      if (relPos) {
        setBoxCurrent({ x: relPos.x, y: relPos.y });
      }
    }
  };

  const runInference = useCallback(async (promptPoints?: typeof points, promptBox?: { x1: number, y1: number, x2: number, y2: number }) => {
    setIsInferencing(true);
    try {
      const result = await predictMask({
        imageUrl: 'https://images.unsplash.com/photo-1549317661-bd32c8ce0be2?q=80&w=2070&auto=format&fit=crop',
        points: promptPoints?.map((p) => ({ x: p.x, y: p.y, type: p.type })),
        box: promptBox,
      });

      result.masks.forEach((m) => {
        addMask({
          id: m.id,
          frameId: 'frame-1',
          pathData: m.pathData,
          label: m.label,
          color: m.color,
          segmentation: m.segmentation,
          bbox: m.bbox,
          area: m.area,
        });
      });
    } catch (err) {
      console.error('Inference failed:', err);
    } finally {
      setIsInferencing(false);
    }
  }, [addMask]);

  const handleStageMouseDown = (e: any) => {
    if (effectiveTool === 'box_select') {
      const stage = e.target.getStage();
      const pos = stage.getRelativePointerPosition();
      if (pos) {
        setBoxStart({ x: pos.x, y: pos.y });
        setBoxCurrent({ x: pos.x, y: pos.y });
      }
    }
  };

  const handleStageMouseUp = (e: any) => {
    if (effectiveTool === 'box_select' && boxStart && boxCurrent) {
      const x1 = Math.min(boxStart.x, boxCurrent.x);
      const y1 = Math.min(boxStart.y, boxCurrent.y);
      const x2 = Math.max(boxStart.x, boxCurrent.x);
      const y2 = Math.max(boxStart.y, boxCurrent.y);
      
      if (Math.abs(x2 - x1) > 5 && Math.abs(y2 - y1) > 5) {
        runInference(undefined, { x1, y1, x2, y2 });
      }
      
      setBoxStart(null);
      setBoxCurrent(null);
    }
  };

  const handleStageClick = (e: any) => {
    if (effectiveTool === 'move') return;
    if (effectiveTool === 'box_select') return; // handled by mouseup

    if (effectiveTool === 'point_pos' || effectiveTool === 'point_neg') {
      const stage = e.target.getStage();
      const pos = stage.getRelativePointerPosition();
      if (pos) {
        const newPoints = [...points, { x: pos.x, y: pos.y, type: effectiveTool === 'point_pos' ? 'pos' : 'neg' as 'pos'|'neg' }];
        setPoints(newPoints);
        // Auto-trigger inference after point selection
        runInference(newPoints);
      }
    }
  };

  const boxRect = React.useMemo(() => {
    if (!boxStart || !boxCurrent) return null;
    const x = Math.min(boxStart.x, boxCurrent.x);
    const y = Math.min(boxStart.y, boxCurrent.y);
    const width = Math.abs(boxCurrent.x - boxStart.x);
    const height = Math.abs(boxCurrent.y - boxStart.y);
    return { x, y, width, height };
  }, [boxStart, boxCurrent]);

  return (
    <div ref={containerRef} className="w-full h-full relative cursor-crosshair overflow-hidden rounded-sm">
       {isInferencing && (
         <div className="absolute top-4 right-4 z-20 flex items-center gap-2 bg-[#111] border border-white/10 px-3 py-2 rounded-lg shadow-xl">
           <div className="w-3 h-3 border-2 border-cyan-500 border-t-transparent rounded-full animate-spin" />
           <span className="text-xs text-cyan-400 font-mono">AI 推理中...</span>
         </div>
       )}

       <Stage
        width={stageSize.width}
        height={stageSize.height}
        onWheel={handleWheel}
        onMouseMove={handleMouseMove}
        onMouseDown={handleStageMouseDown}
        onMouseUp={handleStageMouseUp}
        scaleX={scale}
        scaleY={scale}
        x={position.x}
        y={position.y}
        draggable={effectiveTool === 'move'}
        onClick={handleStageClick}
       >
         <Layer>
            {/* Background Image Layer */}
            {image && (
              <KonvaImage 
                image={image} 
                x={0} 
                y={0}
                opacity={0.8}
              />
            )}
            
            {/* AI Returned Masks */}
            {masks.map((mask) => (
              <Group key={mask.id} opacity={0.5}>
                <Path
                  data={mask.pathData}
                  fill={mask.color}
                  stroke={mask.color}
                  strokeWidth={1 / scale}
                />
              </Group>
            ))}

            {/* Box selection preview */}
            {boxRect && effectiveTool === 'box_select' && (
              <Rect
                x={boxRect.x}
                y={boxRect.y}
                width={boxRect.width}
                height={boxRect.height}
                fill="rgba(6, 182, 212, 0.1)"
                stroke="#06b6d4"
                strokeWidth={2 / scale}
                dash={[4 / scale, 4 / scale]}
              />
            )}

            {/* AI Prompts Point Regions */}
            {points.map((p, i) => (
              <Group key={i} x={p.x} y={p.y}>
                 <Circle 
                   radius={6 / scale} 
                   fill={p.type === 'pos' ? '#22c55e' : '#ef4444'}
                   stroke="#ffffff"
                   strokeWidth={2 / scale}
                   shadowColor="black"
                   shadowBlur={4}
                 />
                 <Circle 
                   radius={1.5 / scale} 
                   fill="#ffffff"
                 />
              </Group>
             ))}
         </Layer>
       </Stage>
       
       <div className="absolute bottom-4 left-4 flex gap-4 text-[10px] font-mono text-gray-500 pointer-events-none">
          <span>光标: {cursorPos.x.toFixed(2)}, {cursorPos.y.toFixed(2)}</span>
          <span>当前图层树: OBJECT_VEHICLE_01</span>
          <span>缩放比: {(scale * 100).toFixed(0)}%</span>
          <span>遮罩数: {masks.length}</span>
       </div>

       {masks.length > 0 && (
         <button
           onClick={clearMasks}
           className="absolute bottom-4 right-4 text-xs bg-red-500/10 hover:bg-red-500/20 text-red-400 border border-red-500/20 px-3 py-1.5 rounded transition-colors"
         >
           清空遮罩
         </button>
       )}
    </div>
  );
}
