import { useState, useCallback } from "react";
import { useParams, Link } from "react-router-dom";
import UploadPanel from "../components/rigo/UploadPanel";
import BraceViewer from "../components/rigo/BraceViewer";
import {
  analyzeXray,
  getBraceOutputs,
  type GenerateBraceResponse,
  type BraceOutput,
  type CobbAngles,
  type RigoClassification,
} from "../api/braceflowApi";

// Helper to format file size
function formatBytes(bytes: number): string {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}

// Helper to get severity level
function getSeverity(cobbAngles: CobbAngles | undefined): { level: string; class: string; angle: number } {
  const maxAngle = Math.max(cobbAngles?.PT ?? 0, cobbAngles?.MT ?? 0, cobbAngles?.TL ?? 0);
  if (maxAngle < 10) return { level: "Normal", class: "success", angle: maxAngle };
  if (maxAngle < 25) return { level: "Mild", class: "success", angle: maxAngle };
  if (maxAngle < 40) return { level: "Moderate", class: "highlight", angle: maxAngle };
  return { level: "Severe", class: "warning", angle: maxAngle };
}

// Metric Card component
function MetricCard({
  label,
  value,
  description,
  highlight,
}: {
  label: string;
  value: string | number;
  description?: string;
  highlight?: "success" | "highlight" | "warning";
}) {
  return (
    <div className="rigo-analysis-card">
      <div className="rigo-analysis-label">{label}</div>
      <div className={`rigo-analysis-value ${highlight || ""}`}>{value}</div>
      {description && <div className="rigo-analysis-description">{description}</div>}
    </div>
  );
}

// Download button for outputs
function DownloadButton({ output }: { output: BraceOutput }) {
  const getIcon = (type: string) => {
    switch (type) {
      case "stl":
      case "ply":
      case "obj":
        return (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
            <polyline points="3.27 6.96 12 12.01 20.73 6.96" />
            <line x1="12" y1="22.08" x2="12" y2="12" />
          </svg>
        );
      case "image":
        return (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
            <circle cx="8.5" cy="8.5" r="1.5" />
            <polyline points="21 15 16 10 5 21" />
          </svg>
        );
      case "json":
        return (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
            <polyline points="14 2 14 8 20 8" />
            <line x1="16" y1="13" x2="8" y2="13" />
            <line x1="16" y1="17" x2="8" y2="17" />
          </svg>
        );
      default:
        return (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
            <polyline points="7 10 12 15 17 10" />
            <line x1="12" y1="15" x2="12" y2="3" />
          </svg>
        );
    }
  };

  return (
    <a
      href={output.url}
      download={output.filename}
      className="rigo-btn rigo-btn-secondary"
      style={{ display: "flex", alignItems: "center", gap: 8, textDecoration: "none" }}
    >
      {getIcon(output.type)}
      <span style={{ flex: 1, textAlign: "left" }}>
        {output.filename}
        <span style={{ color: "#64748b", fontSize: "0.75rem", marginLeft: 8 }}>
          ({formatBytes(output.size)})
        </span>
      </span>
    </a>
  );
}

// Cobb Angles Display
function CobbAnglesDisplay({ angles }: { angles: CobbAngles | undefined }) {
  if (!angles) return null;

  const entries = [
    { label: "Proximal Thoracic (PT)", value: angles.PT },
    { label: "Main Thoracic (MT)", value: angles.MT },
    { label: "Thoracolumbar (TL)", value: angles.TL },
  ].filter((e) => e.value !== undefined && e.value !== null);

  if (entries.length === 0) return null;

  return (
    <div className="rigo-analysis-grid" style={{ gridTemplateColumns: `repeat(${entries.length}, 1fr)` }}>
      {entries.map((entry) => (
        <MetricCard
          key={entry.label}
          label={entry.label}
          value={`${entry.value?.toFixed(1)}°`}
          highlight={entry.value && entry.value > 25 ? (entry.value > 40 ? "warning" : "highlight") : "success"}
        />
      ))}
    </div>
  );
}

// Rigo Classification Display
function RigoDisplay({ classification }: { classification: RigoClassification | undefined }) {
  if (!classification) return null;

  return (
    <div
      className="rigo-analysis-card"
      style={{ background: "rgba(59, 130, 246, 0.1)", borderColor: "#2563eb" }}
    >
      <div className="rigo-analysis-label" style={{ color: "#60a5fa" }}>
        Rigo-Chêneau Classification
      </div>
      <div className="rigo-analysis-value highlight">{classification.type}</div>
      <div className="rigo-analysis-description">{classification.description}</div>
      {classification.curve_pattern && (
        <div style={{ marginTop: 8, fontSize: "0.875rem", color: "#94a3b8" }}>
          Curve Pattern: <strong style={{ color: "#f1f5f9" }}>{classification.curve_pattern}</strong>
        </div>
      )}
    </div>
  );
}

export default function BraceAnalysisPage() {
  const { caseId: routeCaseId } = useParams<{ caseId?: string }>();

  const [caseId, setCaseId] = useState<string | null>(routeCaseId || null);
  const [isAnalyzing, setIsAnalyzing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [result, setResult] = useState<GenerateBraceResponse | null>(null);
  const [outputs, setOutputs] = useState<BraceOutput[]>([]);
  const [modelUrl, setModelUrl] = useState<string | null>(null);

  // Handle file upload and analysis
  const handleUpload = useCallback(async (file: File) => {
    setIsAnalyzing(true);
    setError(null);
    setResult(null);
    setOutputs([]);
    setModelUrl(null);

    try {
      // Run the full workflow
      const { caseId: newCaseId, result: analysisResult } = await analyzeXray(file);
      setCaseId(newCaseId);
      setResult(analysisResult);

      // Find the GLB or STL model URL for 3D viewer
      const modelOutput =
        analysisResult.outputs?.["glb"] ||
        analysisResult.outputs?.["ply"] ||
        analysisResult.outputs?.["stl"];

      if (modelOutput?.url) {
        setModelUrl(modelOutput.url);
      }

      // Get all outputs with presigned URLs
      const outputsResponse = await getBraceOutputs(newCaseId);
      setOutputs(outputsResponse.outputs);
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : "Analysis failed. Please try again.";
      setError(message);
      console.error("Analysis error:", err);
    } finally {
      setIsAnalyzing(false);
    }
  }, []);

  // Reset state
  const handleReset = useCallback(() => {
    setCaseId(null);
    setResult(null);
    setOutputs([]);
    setModelUrl(null);
    setError(null);
  }, []);

  const severity = getSeverity(result?.cobb_angles);

  return (
    <div className="bf-page bf-page--wide">
      {/* Header */}
      <div className="bf-page-header">
        <div>
          <h1 className="bf-page-title">Brace Analysis</h1>
          <p className="bf-page-subtitle">
            Upload an X-ray image to analyze spinal curvature and generate a custom brace design.
          </p>
        </div>
        {caseId && (
          <Link to={`/cases/${caseId}/status`} className="rigo-btn rigo-btn-secondary">
            View Case Details
          </Link>
        )}
      </div>

      {/* Main Content - Three Column Layout */}
      <div className="rigo-shell-page" style={{ gridTemplateColumns: "320px 1fr 380px", gap: 24 }}>
        {/* Left Panel - Upload */}
        <aside className="rigo-panel">
          <div className="rigo-panel-header">
            <h2 className="rigo-panel-title">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                <polyline points="17 8 12 3 7 8" />
                <line x1="12" y1="3" x2="12" y2="15" />
              </svg>
              Upload X-Ray
            </h2>
          </div>
          <div className="rigo-panel-content">
            <UploadPanel
              onUpload={handleUpload}
              isAnalyzing={isAnalyzing}
              onReset={handleReset}
              hasResults={!!result}
            />

            {caseId && (
              <div
                style={{
                  marginTop: 16,
                  padding: 12,
                  background: "rgba(59, 130, 246, 0.1)",
                  borderRadius: 8,
                  fontSize: "0.875rem",
                }}
              >
                <div style={{ color: "#60a5fa", marginBottom: 4 }}>Case ID</div>
                <code style={{ color: "#f1f5f9", fontSize: "0.75rem" }}>{caseId}</code>
              </div>
            )}

            {error && (
              <div
                className="rigo-error-message"
                style={{
                  marginTop: 16,
                  padding: 12,
                  background: "rgba(255,0,0,0.1)",
                  borderRadius: 8,
                  color: "#f87171",
                }}
              >
                {error}
              </div>
            )}
          </div>
        </aside>

        {/* Center - 3D Viewer */}
        <main className="rigo-viewer-container">
          <BraceViewer modelUrl={modelUrl} isLoading={isAnalyzing} />

          {/* Processing Info */}
          {result && (
            <div
              style={{
                position: "absolute",
                bottom: 16,
                left: 16,
                right: 16,
                display: "flex",
                justifyContent: "space-between",
                background: "rgba(0,0,0,0.7)",
                padding: "8px 12px",
                borderRadius: 8,
                fontSize: "0.75rem",
                color: "#94a3b8",
              }}
            >
              <span>Model: {result.model}</span>
              <span>Experiment: {result.experiment}</span>
              <span>Processing: {result.processing_time_ms}ms</span>
            </div>
          )}
        </main>

        {/* Right Panel - Analysis Results */}
        <aside className="rigo-panel" style={{ overflow: "auto", maxHeight: "calc(100vh - 200px)" }}>
          <div className="rigo-panel-header">
            <h2 className="rigo-panel-title">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                <polyline points="14 2 14 8 20 8" />
                <line x1="16" y1="13" x2="8" y2="13" />
                <line x1="16" y1="17" x2="8" y2="17" />
              </svg>
              Analysis Results
            </h2>
          </div>

          <div className="rigo-panel-content">
            {isAnalyzing ? (
              <div className="rigo-analysis-loading">
                <div className="rigo-analysis-card">
                  <div
                    className="rigo-loading-skeleton"
                    style={{ height: "20px", marginBottom: "8px", width: "40%" }}
                  ></div>
                  <div className="rigo-loading-skeleton" style={{ height: "36px", width: "60%" }}></div>
                </div>
                <p
                  style={{
                    textAlign: "center",
                    color: "#64748b",
                    marginTop: "24px",
                    fontSize: "0.875rem",
                  }}
                >
                  <span
                    className="rigo-spinner"
                    style={{ display: "inline-block", marginRight: "8px", verticalAlign: "middle" }}
                  ></span>
                  Analyzing X-ray...
                </p>
              </div>
            ) : result ? (
              <div className="rigo-analysis-results">
                {/* Severity Summary */}
                <MetricCard
                  label="Overall Assessment"
                  value={`${severity.level} Scoliosis`}
                  description={`Max Cobb angle: ${severity.angle.toFixed(1)}°`}
                  highlight={severity.class as "success" | "highlight" | "warning"}
                />

                {/* Curve Type */}
                <div className="rigo-analysis-grid">
                  <MetricCard label="Curve Type" value={result.curve_type || "—"} />
                  <MetricCard label="Vertebrae Detected" value={result.vertebrae_detected || "—"} />
                </div>

                {/* Cobb Angles */}
                <div style={{ marginTop: 16 }}>
                  <h3
                    style={{
                      fontSize: "0.875rem",
                      color: "#64748b",
                      marginBottom: 8,
                      textTransform: "uppercase",
                      letterSpacing: "0.05em",
                    }}
                  >
                    Cobb Angles
                  </h3>
                  <CobbAnglesDisplay angles={result.cobb_angles} />
                </div>

                {/* Rigo Classification */}
                <div style={{ marginTop: 16 }}>
                  <RigoDisplay classification={result.rigo_classification} />
                </div>

                {/* Mesh Info */}
                {result.mesh && (
                  <div className="rigo-analysis-grid" style={{ marginTop: 16 }}>
                    <MetricCard
                      label="Mesh Vertices"
                      value={result.mesh.vertices?.toLocaleString() || "—"}
                    />
                    <MetricCard
                      label="Mesh Faces"
                      value={result.mesh.faces?.toLocaleString() || "—"}
                    />
                  </div>
                )}

                {/* Download Section */}
                {outputs.length > 0 && (
                  <div style={{ marginTop: 24 }}>
                    <h3
                      style={{
                        fontSize: "0.875rem",
                        color: "#64748b",
                        marginBottom: 12,
                        textTransform: "uppercase",
                        letterSpacing: "0.05em",
                      }}
                    >
                      Downloads
                    </h3>
                    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                      {outputs
                        .sort((a, b) => {
                          // Sort: STL first, then PLY, then images, then JSON
                          const order: Record<string, number> = {
                            stl: 0,
                            ply: 1,
                            obj: 2,
                            image: 3,
                            json: 4,
                            other: 5,
                          };
                          return (order[a.type] ?? 5) - (order[b.type] ?? 5);
                        })
                        .map((output) => (
                          <DownloadButton key={output.s3Key} output={output} />
                        ))}
                    </div>
                  </div>
                )}
              </div>
            ) : (
              <div className="rigo-analysis-empty">
                <div style={{ textAlign: "center", padding: "32px", color: "#64748b" }}>
                  <svg
                    width="64"
                    height="64"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="1"
                    style={{ margin: "0 auto 16px", opacity: 0.3 }}
                  >
                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                    <polyline points="14 2 14 8 20 8" />
                    <line x1="16" y1="13" x2="8" y2="13" />
                    <line x1="16" y1="17" x2="8" y2="17" />
                  </svg>
                  <p>Upload an X-ray to see analysis results.</p>
                  <p style={{ fontSize: "0.75rem", marginTop: 8 }}>
                    Supported formats: JPEG, PNG, WebP, BMP
                  </p>
                </div>
              </div>
            )}
          </div>
        </aside>
      </div>
    </div>
  );
}
