/**
 * Stage 3: Body Scan Upload
 * Allows uploading a 3D body scan (STL/OBJ/PLY) for patient-specific fitting
 */
import { useState, useRef, useCallback } from 'react';
import type { BodyScanMetadata, BodyScanResponse } from '../../api/braceflowApi';
import BodyScanViewer from '../three/BodyScanViewer';

type Props = {
  caseId: string;
  bodyScanData: BodyScanResponse | null;
  isLoading: boolean;
  onUpload: (file: File) => Promise<void>;
  onSkip: () => Promise<void>;
  onContinue: () => void;
  onDelete: () => Promise<void>;
};

export default function BodyScanUploadStage({
  caseId,
  bodyScanData,
  isLoading,
  onUpload,
  onSkip,
  onContinue,
  onDelete,
}: Props) {
  const [dragActive, setDragActive] = useState(false);
  const [uploadProgress, setUploadProgress] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const viewerRef = useRef<HTMLDivElement>(null);

  const hasBodyScan = bodyScanData?.has_body_scan && bodyScanData.body_scan;
  const metadata = bodyScanData?.body_scan?.metadata;

  // Handle drag events
  const handleDrag = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === 'dragenter' || e.type === 'dragover') {
      setDragActive(true);
    } else if (e.type === 'dragleave') {
      setDragActive(false);
    }
  }, []);

  // Handle file drop
  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);

    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
      await handleFile(files[0]);
    }
  }, []);

  // Handle file selection
  const handleFileSelect = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      await handleFile(files[0]);
    }
  }, []);

  // Process uploaded file
  const handleFile = async (file: File) => {
    // Validate file type
    const allowedTypes = ['.stl', '.obj', '.ply', '.glb', '.gltf'];
    const ext = file.name.toLowerCase().substring(file.name.lastIndexOf('.'));
    
    if (!allowedTypes.includes(ext)) {
      setError(`Invalid file type. Allowed: ${allowedTypes.join(', ')}`);
      return;
    }

    setError(null);
    setUploadProgress('Uploading...');

    try {
      await onUpload(file);
      setUploadProgress(null);
    } catch (e: any) {
      setError(e?.message || 'Upload failed');
      setUploadProgress(null);
    }
  };

  // Format measurement
  const formatMeasurement = (value: number | undefined, unit = 'mm') => {
    if (value === undefined || value === null) return 'N/A';
    return `${value.toFixed(1)} ${unit}`;
  };

  // Render loading state
  if (isLoading) {
    return (
      <div className="pipeline-stage body-scan-stage">
        <div className="stage-header">
          <h2>Stage 3: Body Scan Upload</h2>
          <div className="stage-status">
            <span className="status-badge status-processing">Processing...</span>
          </div>
        </div>
        <div className="stage-content">
          <div className="body-scan-loading">
            <div className="spinner large"></div>
            <p>Processing body scan...</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="pipeline-stage body-scan-stage">
      <div className="stage-header">
        <h2>Stage 3: Body Scan Upload</h2>
        <div className="stage-status">
          {hasBodyScan ? (
            <span className="status-badge status-complete">Uploaded</span>
          ) : (
            <span className="status-badge status-pending">Optional</span>
          )}
        </div>
      </div>

      <div className="stage-content body-scan-content">
        {/* Upload Area / Preview */}
        <div className="body-scan-main">
          {!hasBodyScan ? (
            <div
              className={`upload-dropzone ${dragActive ? 'drag-active' : ''}`}
              onDragEnter={handleDrag}
              onDragLeave={handleDrag}
              onDragOver={handleDrag}
              onDrop={handleDrop}
              onClick={() => fileInputRef.current?.click()}
            >
              <input
                ref={fileInputRef}
                type="file"
                accept=".stl,.obj,.ply,.glb,.gltf"
                onChange={handleFileSelect}
                style={{ display: 'none' }}
              />
              <div className="dropzone-content">
                <div className="dropzone-icon">📦</div>
                <h3>Upload 3D Body Scan</h3>
                <p>Drag and drop or click to select</p>
                <p className="file-types">STL, OBJ, PLY, GLB supported</p>
                {uploadProgress && <p className="upload-progress">{uploadProgress}</p>}
                {error && <p className="upload-error">{error}</p>}
              </div>
            </div>
          ) : (
          <div className="body-scan-preview body-scan-preview-3d" ref={viewerRef}>
            {/* 3D Spinning Preview - fills container, slow lazy susan rotation */}
            <BodyScanViewer 
              scanUrl={bodyScanData?.body_scan?.url || null}
              autoRotate={true}
              rotationSpeed={0.005}
            />
            
            {/* File info overlay */}
            <div className="preview-info-overlay">
              <span className="filename">{metadata?.filename || 'body_scan.stl'}</span>
              {metadata?.vertex_count && (
                <span className="vertex-count">{metadata.vertex_count.toLocaleString()} vertices</span>
              )}
            </div>
            
            <button className="btn-remove" onClick={onDelete}>
              Remove Scan
            </button>
          </div>
          )}
        </div>

        {/* Info Panel */}
        <div className="body-scan-sidebar">
          <div className="info-panel">
            <h3>Why Upload a Body Scan?</h3>
            <p>
              A 3D body scan allows us to generate a perfectly fitted brace 
              that matches your exact body measurements.
            </p>
            <ul className="benefits-list">
              <li>Precise fit based on body shape</li>
              <li>Automatic clearance calculation</li>
              <li>Better pressure zone placement</li>
              <li>3D printable shell output</li>
            </ul>
            <p className="optional-note">
              <strong>Optional:</strong> You can skip this step to generate 
              a standard-sized brace based on X-ray analysis only.
            </p>
          </div>

          {/* Body Measurements */}
          {hasBodyScan && metadata && (
            <div className="measurements-panel">
              <h3>Body Measurements</h3>
              <div className="measurements-grid">
                {metadata.total_height_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Total Height</span>
                    <span className="value">{formatMeasurement(metadata.total_height_mm)}</span>
                  </div>
                )}
                {metadata.shoulder_width_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Shoulder Width</span>
                    <span className="value">{formatMeasurement(metadata.shoulder_width_mm)}</span>
                  </div>
                )}
                {metadata.chest_width_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Chest Width</span>
                    <span className="value">{formatMeasurement(metadata.chest_width_mm)}</span>
                  </div>
                )}
                {metadata.chest_depth_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Chest Depth</span>
                    <span className="value">{formatMeasurement(metadata.chest_depth_mm)}</span>
                  </div>
                )}
                {metadata.waist_width_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Waist Width</span>
                    <span className="value">{formatMeasurement(metadata.waist_width_mm)}</span>
                  </div>
                )}
                {metadata.hip_width_mm !== undefined && (
                  <div className="measurement-item">
                    <span className="label">Hip Width</span>
                    <span className="value">{formatMeasurement(metadata.hip_width_mm)}</span>
                  </div>
                )}
                {metadata.total_height_mm !== undefined && (
                  <div className="measurement-item highlight">
                    <span className="label">Brace Coverage (65%)</span>
                    <span className="value">{formatMeasurement(metadata.total_height_mm * 0.65)}</span>
                  </div>
                )}
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Actions */}
      <div className="stage-actions">
        {!hasBodyScan ? (
          <>
            <button className="btn secondary" onClick={onSkip}>
              Skip (Use X-ray Only)
            </button>
            <button
              className="btn primary"
              onClick={() => fileInputRef.current?.click()}
            >
              Upload Body Scan
            </button>
          </>
        ) : (
          <>
            <button className="btn secondary" onClick={onDelete}>
              Remove & Skip
            </button>
            <button className="btn primary" onClick={onContinue}>
              Continue to Brace Generation
            </button>
          </>
        )}
      </div>
    </div>
  );
}
