/**
 * Pipeline Case Detail Page
 * 3-stage pipeline: Landmarks → Analysis → Brace
 */
import { useEffect, useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import {
  fetchCase,
  uploadXrayForCase,
  detectLandmarks,
  updateLandmarks,
  approveLandmarks,
  recalculateAnalysis,
  generateBraceFromLandmarks,
  generateBothBraces,
  updateMarkers,
  getCaseAssets,
  uploadBodyScan,
  getBodyScan,
  deleteBodyScan,
  skipBodyScan,
} from '../api/braceflowApi';
import type {
  CaseRecord,
  LandmarksResult,
  RecalculationResult,
  GenerateBraceResponse,
  VertebraeStructure,
  BodyScanResponse,
} from '../api/braceflowApi';

import PipelineSteps, { type PipelineStage } from '../components/pipeline/PipelineSteps';
import LandmarkDetectionStage from '../components/pipeline/LandmarkDetectionStage';
import SpineAnalysisStage from '../components/pipeline/SpineAnalysisStage';
import BodyScanUploadStage from '../components/pipeline/BodyScanUploadStage';
import BraceGenerationStage from '../components/pipeline/BraceGenerationStage';
import BraceFittingStage from '../components/pipeline/BraceFittingStage';

export default function PipelineCaseDetail() {
  const { caseId } = useParams<{ caseId: string }>();
  const nav = useNavigate();

  // Case data
  const [caseData, setCaseData] = useState<CaseRecord | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Stage data
  const [xrayUrl, setXrayUrl] = useState<string | null>(null);
  const [landmarksData, setLandmarksData] = useState<LandmarksResult | null>(null);
  const [analysisData, setAnalysisData] = useState<RecalculationResult | null>(null);
  const [bodyScanData, setBodyScanData] = useState<BodyScanResponse | null>(null);
  const [braceData, setBraceData] = useState<GenerateBraceResponse | null>(null);

  // Current stage and loading states
  const [currentStage, setCurrentStage] = useState<PipelineStage>('upload');
  const [detectingLandmarks, setDetectingLandmarks] = useState(false);
  const [recalculating, setRecalculating] = useState(false);
  const [uploadingBodyScan, setUploadingBodyScan] = useState(false);
  const [generatingBrace, setGeneratingBrace] = useState(false);

  // Load case data
  const loadCase = useCallback(async () => {
    if (!caseId) return;

    setLoading(true);
    setError(null);

    try {
      const data = await fetchCase(caseId);
      setCaseData(data);

      // Load assets
      const assets = await getCaseAssets(caseId).catch((err) => {
        console.error('Failed to get case assets:', err);
        return null;
      });
      console.log('Case assets:', assets);
      const xray = assets?.assets?.uploads?.find((f) =>
        f.filename.match(/\.(jpg|jpeg|png)$/i)
      );
      console.log('Found xray:', xray);
      if (xray) {
        console.log('Setting xrayUrl to:', xray.url);
        setXrayUrl(xray.url);
      }

      // Check existing state from case data
      if (data?.landmarks_data) {
        // Handle both formats - full LandmarksResult or just VertebraeStructure
        const ld = data.landmarks_data as any;
        if (ld.vertebrae_structure) {
          // Full LandmarksResult format
          setLandmarksData(ld as LandmarksResult);
        } else if (ld.vertebrae || ld.all_levels) {
          // Just VertebraeStructure - wrap it
          setLandmarksData({
            case_id: caseId || '',
            status: 'landmarks_detected',
            input: { image_dimensions: { width: 0, height: 0 }, pixel_spacing_mm: null },
            detection_quality: { 
              vertebrae_count: ld.detected_count || ld.vertebrae?.filter((v: any) => v.detected).length || 0, 
              average_confidence: 0 
            },
            cobb_angles: ld.cobb_angles || { PT: 0, MT: 0, TL: 0, max: 0, PT_severity: 'N/A', MT_severity: 'N/A', TL_severity: 'N/A' },
            rigo_classification: ld.rigo_classification || { type: 'Unknown', description: '' },
            curve_type: ld.curve_type || 'Unknown',
            vertebrae_structure: ld as VertebraeStructure,
            processing_time_ms: 0
          } as LandmarksResult);
        }
      }
      
      // Load saved analysis data if available (from previous recalculate)
      if (data?.analysis_data) {
        setAnalysisData(data.analysis_data as RecalculationResult);
      }
      
      // Load body scan data if available
      if (data?.body_scan_path || data?.body_scan_url) {
        setBodyScanData({
          caseId: caseId || '',
          has_body_scan: true,
          body_scan: {
            path: data.body_scan_path || '',
            url: data.body_scan_url || '',
            metadata: data.body_scan_metadata || {}
          }
        });
      }
      
      // Load brace data if available
      let hasBraceData = false;
      if (data?.analysis_result) {
        const analysisResult = data.analysis_result as any;
        // Check for both braces format (regular + vase)
        if (analysisResult.braces) {
          setBraceData({
            rigo_classification: { type: analysisResult.rigoType || 'A1' },
            cobb_angles: analysisResult.cobbAngles,
            braces: analysisResult.braces,
          } as any);
          hasBraceData = true;
        }
        // Check for single brace format (legacy)
        else if (analysisResult.brace) {
          setBraceData(analysisResult.brace as GenerateBraceResponse);
          hasBraceData = true;
        }
      }

      // Determine current stage - prioritize actual data over status
      // This ensures the UI reflects reality even if status is out of sync
      if (hasBraceData) {
        // Brace exists - go straight to brace stage
        setCurrentStage('brace');
      } else {
        // Determine stage from status
        switch (data?.status) {
          case 'created':
            setCurrentStage(xray ? 'landmarks' : 'upload');
            break;
          case 'landmarks_detected':
            // Landmarks detected but not approved - stay on landmarks stage
            setCurrentStage('landmarks');
            break;
          case 'landmarks_approved':
            // Landmarks approved - move to analysis stage
            setCurrentStage('analysis');
            break;
          case 'analysis_complete':
            // Analysis complete - move to body scan stage
            setCurrentStage('bodyscan');
            break;
          case 'body_scan_uploaded':
            // Body scan uploaded - still on body scan stage (need to continue)
            setCurrentStage('bodyscan');
            break;
          case 'processing_brace':
            // Currently generating brace
            setCurrentStage('brace');
            break;
          case 'brace_generated':
          case 'completed':
            // Brace already generated - show brace stage
            setCurrentStage('brace');
            break;
          default:
            setCurrentStage(xray ? 'landmarks' : 'upload');
        }
      }
    } catch (e: any) {
      setError(e?.message || 'Failed to load case');
    } finally {
      setLoading(false);
    }
  }, [caseId]);

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

  // Handle file upload
  const handleUpload = async (file: File) => {
    if (!caseId) return;
    try {
      await uploadXrayForCase(caseId, file);
      // Reload to get new X-ray URL
      await loadCase();
    } catch (e: any) {
      setError(e?.message || 'Upload failed');
    }
  };

  // Stage 1: Detect landmarks
  const handleDetectLandmarks = async () => {
    if (!caseId) return;
    setDetectingLandmarks(true);
    setError(null);
    try {
      const result = await detectLandmarks(caseId);
      setLandmarksData(result);
      setCurrentStage('landmarks');
    } catch (e: any) {
      setError(e?.message || 'Landmark detection failed');
    } finally {
      setDetectingLandmarks(false);
    }
  };

  // Stage 1: Update landmarks
  const handleUpdateLandmarks = async (landmarks: VertebraeStructure) => {
    if (!caseId) return;
    try {
      await updateLandmarks(caseId, landmarks);
      // Update local state
      if (landmarksData) {
        setLandmarksData({
          ...landmarksData,
          vertebrae_structure: landmarks,
        });
      }
    } catch (e: any) {
      setError(e?.message || 'Failed to save landmarks');
    }
  };

  // Stage 1 -> 2: Approve landmarks
  const handleApproveLandmarks = async (updatedLandmarks?: VertebraeStructure) => {
    if (!caseId) return;
    try {
      await approveLandmarks(caseId, updatedLandmarks);
      setCurrentStage('analysis');
    } catch (e: any) {
      setError(e?.message || 'Failed to approve landmarks');
    }
  };

  // Stage 2: Recalculate analysis
  const handleRecalculate = async () => {
    if (!caseId) return;
    setRecalculating(true);
    setError(null);
    try {
      const result = await recalculateAnalysis(caseId);
      setAnalysisData(result);
    } catch (e: any) {
      setError(e?.message || 'Recalculation failed');
    } finally {
      setRecalculating(false);
    }
  };

  // Stage 2 -> 3: Continue to body scan
  const handleContinueToBodyScan = () => {
    setCurrentStage('bodyscan');
  };

  // Stage 3: Upload body scan
  const handleUploadBodyScan = async (file: File) => {
    if (!caseId) return;
    setUploadingBodyScan(true);
    setError(null);
    try {
      const result = await uploadBodyScan(caseId, file);
      setBodyScanData({
        caseId,
        has_body_scan: true,
        body_scan: result.body_scan
      });
    } catch (e: any) {
      setError(e?.message || 'Body scan upload failed');
    } finally {
      setUploadingBodyScan(false);
    }
  };

  // Stage 3: Skip body scan
  const handleSkipBodyScan = async () => {
    if (!caseId) return;
    try {
      await skipBodyScan(caseId);
      setBodyScanData({ caseId, has_body_scan: false, body_scan: null });
      setCurrentStage('brace');
    } catch (e: any) {
      setError(e?.message || 'Failed to skip body scan');
    }
  };

  // Stage 3: Delete body scan
  const handleDeleteBodyScan = async () => {
    if (!caseId) return;
    try {
      await deleteBodyScan(caseId);
      setBodyScanData({ caseId, has_body_scan: false, body_scan: null });
    } catch (e: any) {
      setError(e?.message || 'Failed to delete body scan');
    }
  };

  // Stage 3 -> 4: Continue to brace generation
  const handleContinueToBrace = () => {
    setCurrentStage('brace');
  };

  // Stage 4 -> 5: Continue to fitting inspection
  const handleContinueToFitting = () => {
    setCurrentStage('fitting');
  };

  // Handle clicking on pipeline step to navigate
  const handleStageClick = (stage: PipelineStage) => {
    setCurrentStage(stage);
  };

  // Stage 3: Generate brace (both regular and vase types)
  const handleGenerateBrace = async () => {
    if (!caseId) return;
    setGeneratingBrace(true);
    setError(null);
    
    let standardResult: any = null;
    
    try {
      // First try to generate the standard brace (for backward compatibility)
      try {
        standardResult = await generateBraceFromLandmarks(caseId, {
          experiment: 'experiment_9',
        });
      } catch (stdErr) {
        console.warn('Standard brace generation failed, trying both braces:', stdErr);
      }
      
      // Generate both brace types (regular + vase) with markers
      const bothBraces = await generateBothBraces(caseId, {
        rigoType: standardResult?.rigo_classification?.type,
      });
      
      // Merge both braces data into the result
      setBraceData({
        ...(standardResult || {}),
        rigo_classification: standardResult?.rigo_classification || { type: bothBraces.rigoType },
        cobb_angles: standardResult?.cobb_angles || bothBraces.cobbAngles,
        braces: bothBraces.braces,
      } as any);
      
    } catch (e: any) {
      // If both fail, show error
      if (standardResult) {
        // At least we have the standard result
        setBraceData(standardResult);
      } else {
        setError(e?.message || 'Brace generation failed');
      }
    } finally {
      setGeneratingBrace(false);
    }
  };

  // Stage 3: Update markers
  const handleUpdateMarkers = async (markers: Record<string, unknown>) => {
    if (!caseId) return;
    try {
      await updateMarkers(caseId, markers);
    } catch (e: any) {
      setError(e?.message || 'Failed to save markers');
    }
  };

  // Loading state
  if (loading) {
    return (
      <div className="pipeline-page">
        <div className="pipeline-loading">
          <div className="spinner"></div>
          <p>Loading case...</p>
        </div>
      </div>
    );
  }

  // Error state
  if (error && !caseData) {
    return (
      <div className="pipeline-page">
        <div className="pipeline-error">
          <p className="error">{error}</p>
          <button className="btn secondary" onClick={() => nav('/')}>
            Back to Dashboard
          </button>
        </div>
      </div>
    );
  }

  const visualizationUrl =
    landmarksData?.visualization_url ||
    (landmarksData as any)?.visualization_path?.replace(/^.*[\\\/]/, '/files/outputs/' + caseId + '/');

  return (
    <div className="pipeline-page">
      {/* Header */}
      <header className="pipeline-header">
        <div className="header-left">
          <button 
            className="back-btn" 
            onClick={() => caseData?.patient_id ? nav(`/patients/${caseData.patient_id}`) : nav('/patients')}
          >
            ← Back
          </button>
          <div className="case-header-info">
            {caseData?.patient && (
              <h1 className="patient-name-header">
                {caseData.patient.fullName}
                {caseData.patient.mrn && (
                  <span className="patient-mrn-badge">MRN: {caseData.patient.mrn}</span>
                )}
              </h1>
            )}
            <div className="case-meta-row">
              <span className="case-id-label">{caseId}</span>
              {caseData?.visit_date && (
                <span className="visit-date-label">
                  Visit: {new Date(caseData.visit_date).toLocaleDateString()}
                </span>
              )}
              <span className={`status-badge status-${caseData?.status || 'created'}`}>
                {caseData?.status?.replace(/_/g, ' ') || 'Created'}
              </span>
            </div>
          </div>
        </div>
      </header>

      {/* Pipeline Steps Indicator */}
      <PipelineSteps
        currentStage={currentStage}
        landmarksApproved={
          caseData?.status === 'landmarks_approved' ||
          caseData?.status === 'analysis_complete' ||
          caseData?.status === 'body_scan_uploaded' ||
          caseData?.status === 'brace_generated'
        }
        analysisComplete={
          caseData?.status === 'analysis_complete' ||
          caseData?.status === 'body_scan_uploaded' ||
          caseData?.status === 'brace_generated'
        }
        bodyScanComplete={
          caseData?.status === 'body_scan_uploaded' ||
          caseData?.status === 'brace_generated'
        }
        braceGenerated={caseData?.status === 'brace_generated'}
        onStageClick={handleStageClick}
      />

      {/* Error Banner */}
      {error && (
        <div className="error-banner">
          <span>{error}</span>
          <button onClick={() => setError(null)}>×</button>
        </div>
      )}

      {/* Upload Section (if no X-ray) */}
      {!xrayUrl && currentStage === 'upload' && (
        <div className="upload-section">
          <div className="upload-box">
            <h2>Upload X-ray Image</h2>
            <p>Upload a frontal (AP) X-ray image to begin analysis.</p>
            <input
              type="file"
              accept="image/*"
              onChange={(e) => {
                const file = e.target.files?.[0];
                if (file) handleUpload(file);
              }}
            />
          </div>
        </div>
      )}

      {/* Stage Components */}
      <div className="pipeline-stages">
        {(currentStage === 'landmarks' || xrayUrl) && (
          <LandmarkDetectionStage
            caseId={caseId || ''}
            landmarksData={landmarksData}
            xrayUrl={xrayUrl}
            visualizationUrl={visualizationUrl}
            isLoading={detectingLandmarks}
            onDetect={handleDetectLandmarks}
            onApprove={handleApproveLandmarks}
            onUpdateLandmarks={handleUpdateLandmarks}
          />
        )}

        {(currentStage === 'analysis' || currentStage === 'bodyscan' || currentStage === 'brace') && (
          <SpineAnalysisStage
            landmarksData={landmarksData}
            analysisData={analysisData}
            isLoading={recalculating}
            onRecalculate={handleRecalculate}
            onContinue={handleContinueToBodyScan}
          />
        )}

        {(currentStage === 'bodyscan' || currentStage === 'brace') && (
          <BodyScanUploadStage
            caseId={caseId || ''}
            bodyScanData={bodyScanData}
            isLoading={uploadingBodyScan}
            onUpload={handleUploadBodyScan}
            onSkip={handleSkipBodyScan}
            onContinue={handleContinueToBrace}
            onDelete={handleDeleteBodyScan}
          />
        )}

        {currentStage === 'brace' && (
          <BraceGenerationStage
            caseId={caseId || ''}
            braceData={braceData}
            isLoading={generatingBrace}
            onGenerate={handleGenerateBrace}
            onUpdateMarkers={handleUpdateMarkers}
          />
        )}

        {/* Stage 5: Brace Fitting - shows when brace is generated AND body scan exists */}
        {(currentStage === 'brace' || currentStage === 'fitting') && braceData && bodyScanData?.has_body_scan && (
          <BraceFittingStage
            caseId={caseId || ''}
            bodyScanUrl={bodyScanData?.body_scan?.url || null}
            regularBraceUrl={
              (braceData as any)?.braces?.regular?.outputs?.stl ||
              (braceData as any)?.braces?.regular?.outputs?.glb ||
              braceData?.outputs?.stl ||
              null
            }
            vaseBraceUrl={
              (braceData as any)?.braces?.vase?.outputs?.stl ||
              (braceData as any)?.braces?.vase?.outputs?.glb ||
              null
            }
            braceData={braceData}
          />
        )}
      </div>
    </div>
  );
}
