/**
 * Stage 1: Landmark Detection
 * Interactive canvas - always editable, draw landmarks from JSON
 * Supports green quadrilateral boxes around vertebrae with corner editing
 */
import { useState, useRef, useEffect, useCallback } from 'react';
import type { LandmarksResult, VertebraeStructure, VertebraData } from '../../api/braceflowApi';

type Props = {
  caseId: string;
  landmarksData: LandmarksResult | null;
  xrayUrl: string | null;
  visualizationUrl: string | null;
  isLoading: boolean;
  onDetect: () => Promise<void>;
  onApprove: (updatedLandmarks?: VertebraeStructure) => Promise<void>;
  onUpdateLandmarks: (landmarks: VertebraeStructure) => Promise<void>;
};

type DragState = {
  type: 'centroid' | 'corner';
  level: string;
  cornerIdx?: number;  // 0-3 for corner drag
  startX: number;
  startY: number;
  originalCorners: [number, number][] | null;
  originalCentroid: [number, number];
};

type CornerHit = {
  level: string;
  cornerIdx: number;
};

export default function LandmarkDetectionStage({
  caseId,
  landmarksData,
  xrayUrl,
  visualizationUrl,
  isLoading,
  onDetect,
  onApprove,
  onUpdateLandmarks,
}: Props) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  
  const [image, setImage] = useState<HTMLImageElement | null>(null);
  const [structure, setStructure] = useState<VertebraeStructure | null>(null);
  const [selectedLevel, setSelectedLevel] = useState<string | null>(null);
  const [hoveredLevel, setHoveredLevel] = useState<string | null>(null);
  const [hoveredCorner, setHoveredCorner] = useState<CornerHit | null>(null);
  const [dragState, setDragState] = useState<DragState | null>(null);
  const [scale, setScale] = useState(1);
  const [hasChanges, setHasChanges] = useState(false);
  const [imageError, setImageError] = useState<string | null>(null);

  // Initialize structure from landmarks data
  useEffect(() => {
    if (landmarksData?.vertebrae_structure) {
      setStructure(JSON.parse(JSON.stringify(landmarksData.vertebrae_structure)));
      setHasChanges(false);
    }
  }, [landmarksData]);

  // Load X-ray image
  useEffect(() => {
    if (!xrayUrl) {
      setImage(null);
      setImageError(null);
      return;
    }
    
    setImageError(null);
    console.log('Loading X-ray from URL:', xrayUrl);
    const img = new Image();
    // Note: crossOrigin removed for local dev - add back for production with proper CORS
    // img.crossOrigin = 'anonymous';
    
    img.onload = () => {
      console.log('X-ray loaded successfully:', img.naturalWidth, 'x', img.naturalHeight);
      setImage(img);
      setImageError(null);
      // Calculate scale to fit container
      if (containerRef.current) {
        const maxWidth = containerRef.current.clientWidth - 40;
        const maxHeight = containerRef.current.clientHeight - 40;
        const scaleX = maxWidth / img.naturalWidth;
        const scaleY = maxHeight / img.naturalHeight;
        setScale(Math.min(scaleX, scaleY, 1));
      }
    };
    
    img.onerror = (e) => {
      setImage(null);
      setImageError('Failed to load X-ray image. Please try refreshing the page.');
      console.error('Failed to load X-ray image:', xrayUrl);
      console.error('Error event:', e);
    };
    
    img.src = xrayUrl;
  }, [xrayUrl]);

  // Get vertebra by level
  const getVertebra = useCallback((level: string): VertebraData | undefined => {
    return structure?.vertebrae.find(v => v.level === level);
  }, [structure]);

  // Calculate centroid from corners
  const calculateCentroid = (corners: [number, number][]): [number, number] => {
    const sumX = corners.reduce((acc, c) => acc + c[0], 0);
    const sumY = corners.reduce((acc, c) => acc + c[1], 0);
    return [sumX / corners.length, sumY / corners.length];
  };

  // Update vertebra with new corners and recalculate centroid
  const updateVertebraCorners = useCallback((level: string, newCorners: [number, number][]) => {
    const newCentroid = calculateCentroid(newCorners);
    
    setStructure(prev => {
      if (!prev) return prev;
      return {
        ...prev,
        vertebrae: prev.vertebrae.map(v => {
          if (v.level !== level) return v;
          return {
            ...v,
            manual_override: {
              ...v.manual_override,
              enabled: true,
              centroid_px: newCentroid,
              corners_px: newCorners,
            },
            final_values: {
              ...v.final_values,
              centroid_px: newCentroid,
              corners_px: newCorners,
              source: 'manual' as const,
            },
          };
        }),
      };
    });
    setHasChanges(true);
  }, []);

  // Update vertebra position (move centroid and all corners together)
  const updateVertebraPosition = useCallback((level: string, newCentroid: [number, number], originalCorners: [number, number][] | null, originalCentroid: [number, number]) => {
    // Calculate delta from original centroid
    const dx = newCentroid[0] - originalCentroid[0];
    const dy = newCentroid[1] - originalCentroid[1];
    
    // Move all corners by same delta
    let newCorners: [number, number][] | null = null;
    if (originalCorners) {
      newCorners = originalCorners.map(c => [c[0] + dx, c[1] + dy] as [number, number]);
    }
    
    setStructure(prev => {
      if (!prev) return prev;
      return {
        ...prev,
        vertebrae: prev.vertebrae.map(v => {
          if (v.level !== level) return v;
          return {
            ...v,
            manual_override: {
              ...v.manual_override,
              enabled: true,
              centroid_px: newCentroid,
              corners_px: newCorners,
            },
            final_values: {
              ...v.final_values,
              centroid_px: newCentroid,
              corners_px: newCorners,
              source: 'manual' as const,
            },
          };
        }),
      };
    });
    setHasChanges(true);
  }, []);

  // Reset vertebra to original
  const resetVertebra = useCallback((level: string) => {
    const original = landmarksData?.vertebrae_structure.vertebrae.find(v => v.level === level);
    if (!original) return;

    setStructure(prev => {
      if (!prev) return prev;
      return {
        ...prev,
        vertebrae: prev.vertebrae.map(v => {
          if (v.level !== level) return v;
          return {
            ...v,
            manual_override: {
              enabled: false,
              centroid_px: null,
              corners_px: null,
              orientation_deg: null,
              confidence: null,
              notes: null,
            },
            final_values: {
              ...original.scoliovis_data,
              source: original.detected ? 'scoliovis' as const : 'undetected' as const,
            },
          };
        }),
      };
    });
    setHasChanges(true);
  }, [landmarksData]);

  // Draw canvas with green boxes and red centroids
  const draw = useCallback(() => {
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext('2d');
    if (!canvas || !ctx || !image) return;

    // Set canvas size
    canvas.width = image.naturalWidth * scale;
    canvas.height = image.naturalHeight * scale;

    // Clear and draw image
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.save();
    ctx.scale(scale, scale);
    ctx.drawImage(image, 0, 0);

    // Draw vertebrae if we have structure
    if (structure) {
      structure.vertebrae.forEach(v => {
        const centroid = v.final_values?.centroid_px;
        if (!centroid) return;

        const [x, y] = centroid;
        const isSelected = selectedLevel === v.level;
        const isHovered = hoveredLevel === v.level;
        const isManual = v.manual_override?.enabled;

        // Draw green X-shape vertebra marker if corners exist
        // Corner order: [top_left, top_right, bottom_left, bottom_right]
        // Drawing 0→1→2→3→0 creates the X pattern that shows endplate orientations
        const corners = v.final_values?.corners_px;
        if (corners && corners.length === 4) {
          // Set line style based on state
          if (isSelected) {
            ctx.strokeStyle = '#00ff00';
            ctx.lineWidth = 2;
          } else if (isManual) {
            ctx.strokeStyle = '#00cc00';
            ctx.lineWidth = 1.5;
          } else {
            ctx.strokeStyle = '#22aa22';
            ctx.lineWidth = 1;
          }
          
          // Draw the X-shape: 0→1, 1→2, 2→3, 3→0
          // This creates: top edge, diagonal, bottom edge, diagonal (X pattern)
          ctx.beginPath();
          for (let i = 0; i < 4; i++) {
            const j = (i + 1) % 4;
            ctx.moveTo(corners[i][0], corners[i][1]);
            ctx.lineTo(corners[j][0], corners[j][1]);
          }
          ctx.stroke();

          // Draw corner handles for selected vertebra
          if (isSelected) {
            corners.forEach((corner, idx) => {
              const isCornerHovered = hoveredCorner?.level === v.level && hoveredCorner?.cornerIdx === idx;
              ctx.beginPath();
              ctx.arc(corner[0], corner[1], isCornerHovered ? 6 : 4, 0, Math.PI * 2);
              ctx.fillStyle = isCornerHovered ? '#ffff00' : '#00ff00';
              ctx.fill();
              ctx.strokeStyle = '#000000';
              ctx.lineWidth = 1;
              ctx.stroke();
            });
          }
        }

        // Determine centroid color
        let fillColor = '#ff3333'; // Detected (red)
        if (isManual) fillColor = '#ff6600'; // Manual (orange-red to distinguish)
        else if (!v.detected) fillColor = '#888888'; // Undetected (gray)

        // Draw centroid circle
        const radius = isSelected || isHovered ? 8 : 5;
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, Math.PI * 2);
        ctx.fillStyle = fillColor;
        ctx.fill();

        // Highlight ring for centroid
        if (isSelected) {
          ctx.strokeStyle = '#ffffff';
          ctx.lineWidth = 2;
          ctx.stroke();
        } else if (isHovered) {
          ctx.strokeStyle = '#ffff00';
          ctx.lineWidth = 2;
          ctx.stroke();
        } else {
          ctx.strokeStyle = '#000000';
          ctx.lineWidth = 1;
          ctx.stroke();
        }

        // Draw label
        ctx.font = 'bold 11px Arial';
        ctx.fillStyle = '#ffffff';
        ctx.strokeStyle = '#000000';
        ctx.lineWidth = 3;
        ctx.strokeText(v.level, x + 12, y + 4);
        ctx.fillText(v.level, x + 12, y + 4);
      });
    }

    ctx.restore();
  }, [image, scale, structure, selectedLevel, hoveredLevel, hoveredCorner]);

  useEffect(() => {
    draw();
  }, [draw]);

  // Convert screen coords to image coords
  const screenToImage = useCallback((clientX: number, clientY: number): [number, number] => {
    const canvas = canvasRef.current;
    if (!canvas) return [0, 0];
    const rect = canvas.getBoundingClientRect();
    const x = (clientX - rect.left) / scale;
    const y = (clientY - rect.top) / scale;
    return [x, y];
  }, [scale]);

  // Find corner point at position
  const findCornerAt = useCallback((x: number, y: number): CornerHit | null => {
    if (!structure) return null;
    const threshold = 15 / scale;

    for (const v of structure.vertebrae) {
      const corners = v.final_values?.corners_px;
      if (!corners) continue;
      
      for (let i = 0; i < 4; i++) {
        const dist = Math.sqrt((x - corners[i][0]) ** 2 + (y - corners[i][1]) ** 2);
        if (dist < threshold) {
          return { level: v.level, cornerIdx: i };
        }
      }
    }
    return null;
  }, [structure, scale]);

  // Find vertebra centroid at position
  const findVertebraAt = useCallback((x: number, y: number): string | null => {
    if (!structure) return null;
    const threshold = 20 / scale;
    let closest: string | null = null;
    let minDist = threshold;

    structure.vertebrae.forEach(v => {
      const centroid = v.final_values?.centroid_px;
      if (!centroid) return;
      const dist = Math.sqrt((x - centroid[0]) ** 2 + (y - centroid[1]) ** 2);
      if (dist < minDist) {
        minDist = dist;
        closest = v.level;
      }
    });

    return closest;
  }, [structure, scale]);

  // Mouse handlers
  const handleMouseDown = (e: React.MouseEvent) => {
    if (!structure) return;
    const [x, y] = screenToImage(e.clientX, e.clientY);
    
    // Check for corner hit first (only on selected vertebra for precision)
    if (selectedLevel) {
      const cornerHit = findCornerAt(x, y);
      if (cornerHit && cornerHit.level === selectedLevel) {
        const v = getVertebra(cornerHit.level);
        if (v?.final_values?.corners_px && v?.final_values?.centroid_px) {
          setDragState({
            type: 'corner',
            level: cornerHit.level,
            cornerIdx: cornerHit.cornerIdx,
            startX: e.clientX,
            startY: e.clientY,
            originalCorners: v.final_values.corners_px.map(c => [...c] as [number, number]),
            originalCentroid: [...v.final_values.centroid_px] as [number, number],
          });
          return;
        }
      }
    }
    
    // Check for centroid hit
    const level = findVertebraAt(x, y);
    if (level) {
      setSelectedLevel(level);
      const v = getVertebra(level);
      if (v?.final_values?.centroid_px) {
        setDragState({
          type: 'centroid',
          level,
          startX: e.clientX,
          startY: e.clientY,
          originalCorners: v.final_values.corners_px 
            ? v.final_values.corners_px.map(c => [...c] as [number, number])
            : null,
          originalCentroid: [...v.final_values.centroid_px] as [number, number],
        });
      }
    } else if (selectedLevel) {
      // Place selected (missing) vertebra at click position
      const v = getVertebra(selectedLevel);
      if (v && (!v.final_values?.centroid_px || !v.detected)) {
        // Create default corners around click position
        const defaultHalfWidth = 15;
        const defaultHalfHeight = 12;
        const defaultCorners: [number, number][] = [
          [x - defaultHalfWidth, y - defaultHalfHeight], // top_left
          [x + defaultHalfWidth, y - defaultHalfHeight], // top_right
          [x - defaultHalfWidth, y + defaultHalfHeight], // bottom_left
          [x + defaultHalfWidth, y + defaultHalfHeight], // bottom_right
        ];
        updateVertebraCorners(selectedLevel, defaultCorners);
      }
    }
  };

  const handleMouseMove = (e: React.MouseEvent) => {
    const [x, y] = screenToImage(e.clientX, e.clientY);
    
    if (dragState) {
      if (dragState.type === 'corner' && dragState.cornerIdx !== undefined && dragState.originalCorners) {
        // Dragging a corner
        const dx = (e.clientX - dragState.startX) / scale;
        const dy = (e.clientY - dragState.startY) / scale;
        
        // Update just the dragged corner
        const newCorners = dragState.originalCorners.map((c, i) => {
          if (i === dragState.cornerIdx) {
            return [c[0] + dx, c[1] + dy] as [number, number];
          }
          return [...c] as [number, number];
        });
        
        updateVertebraCorners(dragState.level, newCorners);
      } else if (dragState.type === 'centroid') {
        // Dragging the centroid (moves entire vertebra)
        const dx = (e.clientX - dragState.startX) / scale;
        const dy = (e.clientY - dragState.startY) / scale;
        const newCentroid: [number, number] = [
          dragState.originalCentroid[0] + dx,
          dragState.originalCentroid[1] + dy,
        ];
        updateVertebraPosition(dragState.level, newCentroid, dragState.originalCorners, dragState.originalCentroid);
      }
    } else {
      // Hovering - check for corner first if a vertebra is selected
      if (selectedLevel) {
        const cornerHit = findCornerAt(x, y);
        if (cornerHit && cornerHit.level === selectedLevel) {
          setHoveredCorner(cornerHit);
          setHoveredLevel(cornerHit.level);
          return;
        }
      }
      setHoveredCorner(null);
      setHoveredLevel(findVertebraAt(x, y));
    }
  };

  const handleMouseUp = () => {
    setDragState(null);
  };

  // Determine cursor style
  const getCursor = () => {
    if (dragState) return 'grabbing';
    if (hoveredCorner) return 'move';
    if (hoveredLevel) return 'grab';
    return 'crosshair';
  };

  // Handle approve
  const handleApprove = async () => {
    if (structure && hasChanges) {
      await onUpdateLandmarks(structure);
    }
    await onApprove(structure || undefined);
  };

  // Stats
  const detectedCount = structure?.vertebrae.filter(v => v.detected).length || 0;
  const manualCount = structure?.vertebrae.filter(v => v.manual_override?.enabled).length || 0;
  const placedCount = structure?.vertebrae.filter(v => v.final_values?.centroid_px).length || 0;

  return (
    <div className="pipeline-stage landmark-stage">
      <div className="stage-header">
        <h2>Stage 1: Vertebrae Detection</h2>
        <div className="stage-status">
          {isLoading ? (
            <span className="status-badge status-processing">Processing...</span>
          ) : landmarksData ? (
            <span className="status-badge status-complete">
              {hasChanges ? 'Modified' : 'Detected'}
            </span>
          ) : (
            <span className="status-badge status-pending">Pending</span>
          )}
        </div>
      </div>

      <div className="stage-content landmark-interactive">
        {/* Canvas area */}
        <div className="landmark-canvas-area" ref={containerRef}>
          {!landmarksData && !isLoading && (
            <div className="landmark-empty">
              {xrayUrl ? (
                <>
                  <img src={xrayUrl} alt="X-ray" className="xray-preview" />
                  <p>X-ray uploaded. Click to detect landmarks.</p>
                  <button className="btn primary" onClick={onDetect}>
                    Detect Landmarks
                  </button>
                </>
              ) : (
                <p>Please upload an X-ray image first.</p>
              )}
            </div>
          )}

          {isLoading && (
            <div className="landmark-loading">
              <div className="spinner"></div>
              <p>Detecting vertebrae landmarks...</p>
            </div>
          )}

          {/* Error state when image fails to load */}
          {imageError && (
            <div className="landmark-error">
              <p>{imageError}</p>
              {xrayUrl && (
                <button className="btn secondary" onClick={() => {
                  setImageError(null);
                  const img = new Image();
                  img.crossOrigin = 'anonymous';
                  img.onload = () => setImage(img);
                  img.onerror = () => setImageError('Failed to load image');
                  img.src = xrayUrl;
                }}>
                  Retry Loading
                </button>
              )}
            </div>
          )}

          {/* Loading state while image is being fetched */}
          {landmarksData && !image && !imageError && xrayUrl && (
            <div className="landmark-loading">
              <div className="spinner"></div>
              <p>Loading X-ray image...</p>
            </div>
          )}

          {landmarksData && image && (
            <>
              <canvas
                ref={canvasRef}
                className="landmark-canvas-interactive"
                onMouseDown={handleMouseDown}
                onMouseMove={handleMouseMove}
                onMouseUp={handleMouseUp}
                onMouseLeave={handleMouseUp}
                style={{ cursor: getCursor() }}
              />
              <div className="canvas-hint">
                {selectedLevel && !getVertebra(selectedLevel)?.final_values?.centroid_px ? (
                  <span>Click on image to place <strong>{selectedLevel}</strong></span>
                ) : selectedLevel ? (
                  <span>Drag corners to adjust box shape • Drag center to move • Click another to select</span>
                ) : (
                  <span>Click a vertebra to select and edit • Drag center to move</span>
                )}
              </div>
            </>
          )}
        </div>

        {/* Vertebrae panel */}
        {landmarksData && structure && (
          <div className="vertebrae-panel-inline">
            <div className="panel-header">
              <h3>Vertebrae</h3>
              <div className="panel-stats">
                <span className="stat-pill detected">{detectedCount} detected</span>
                {manualCount > 0 && <span className="stat-pill manual">{manualCount} edited</span>}
              </div>
            </div>

            <div className="vertebrae-scroll">
              {structure.vertebrae.map(v => {
                const hasCentroid = !!v.final_values?.centroid_px;
                const hasCorners = !!v.final_values?.corners_px;
                const isSelected = selectedLevel === v.level;
                const isManual = v.manual_override?.enabled;

                return (
                  <div
                    key={v.level}
                    className={`vert-row ${isSelected ? 'selected' : ''} ${isManual ? 'manual' : ''} ${!hasCentroid ? 'missing' : ''}`}
                    onClick={() => setSelectedLevel(v.level)}
                  >
                    <span className="vert-level">{v.level}</span>
                    <span className="vert-info">
                      {isManual ? (
                        <span className="info-manual">Manual</span>
                      ) : v.detected ? (
                        <span className="info-conf">
                          {((v.scoliovis_data?.confidence || 0) * 100).toFixed(0)}%
                          {hasCorners && <span className="has-corners" title="Has box corners"> ◻</span>}
                        </span>
                      ) : hasCentroid ? (
                        <span className="info-placed">Placed</span>
                      ) : (
                        <span className="info-missing">Click to place</span>
                      )}
                    </span>
                    {isManual && (
                      <button
                        className="vert-reset"
                        onClick={(e) => { e.stopPropagation(); resetVertebra(v.level); }}
                        title="Reset to original"
                      >
                        ↩
                      </button>
                    )}
                  </div>
                );
              })}
            </div>

            {/* Legend */}
            <div className="panel-legend">
              <span><i className="dot red"></i>Detected</span>
              <span><i className="dot green"></i>Manual</span>
              <span><i className="dot gray"></i>Missing</span>
            </div>

            {/* Quick analysis preview */}
            {landmarksData.cobb_angles && (
              <div className="quick-analysis">
                <div className="qa-row">
                  <span>PT</span>
                  <span>{(landmarksData.cobb_angles.PT || 0).toFixed(1)}°</span>
                </div>
                <div className="qa-row">
                  <span>MT</span>
                  <span>{(landmarksData.cobb_angles.MT || 0).toFixed(1)}°</span>
                </div>
                <div className="qa-row">
                  <span>TL</span>
                  <span>{(landmarksData.cobb_angles.TL || 0).toFixed(1)}°</span>
                </div>
                <div className="qa-rigo">
                  <span className="rigo-tag">{landmarksData.rigo_classification?.type || 'N/A'}</span>
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      {/* Actions */}
      {landmarksData && (
        <div className="stage-actions">
          {hasChanges && (
            <span className="changes-indicator">Unsaved changes</span>
          )}
          <button
            className="btn primary"
            onClick={handleApprove}
            disabled={isLoading}
          >
            {hasChanges ? 'Save & Continue' : 'Approve & Continue'}
          </button>
        </div>
      )}
    </div>
  );
}
