import React, { useState, useCallback, useEffect } from "react";
import { useDropzone } from "react-dropzone";
import {
  apiClient,
  SpectrumData,
  ComparisonResult,
  ModelInfo,
  PredictionResult,
} from "../apiClient";
import SpectrumChart from "./SpectrumChart";
import ResultsDisplay from "./ResultsDisplay"; // We'll reuse parts of this component's display logic
import "../static/style.css";

interface ModelComparisonProps {
  modality: "raman" | "ftir";
}

const ModelComparison: React.FC<ModelComparisonProps> = ({ modality }) => {
  const [spectrum, setSpectrum] = useState<SpectrumData | null>(null);
  const [comparisonResult, setComparisonResult] =
    useState<ComparisonResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [availableModels, setAvailableModels] = useState<ModelInfo[]>([]);
  const [selectedModels, setSelectedModels] = useState<string[]>([]);

  useEffect(() => {
    const fetchModels = async () => {
      try {
        const models = await apiClient.getModels();
        const available = models.filter((m) => m.available);
        setAvailableModels(available);
        // Default to selecting the first two models for comparison
        setSelectedModels(available.slice(0, 2).map((m) => m.name));
      } catch (err) {
        setError("Failed to fetch available models.");
      }
    };
    fetchModels();
  }, []);

  const onDrop = useCallback(async (acceptedFiles: File[]) => {
    if (acceptedFiles.length === 0) return;
    const file = acceptedFiles[0];
    setError(null);
    setLoading(true);
    try {
      const uploadedSpectrum = await apiClient.uploadSpectrum(file);
      setSpectrum(uploadedSpectrum);
      setComparisonResult(null); // Clear previous results on new upload
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to upload file");
    } finally {
      setLoading(false);
    }
  }, []);

  const handleToggleModel = (modelName: string) => {
    setSelectedModels((prev) =>
      prev.includes(modelName)
        ? prev.filter((m) => m !== modelName)
        : [...prev, modelName]
    );
  };

  const handleCompare = async () => {
    if (!spectrum) {
      setError("Please upload a spectrum file first.");
      return;
    }
    if (selectedModels.length < 2) {
      setError("Please select at least two models to compare.");
      return;
    }
    setError(null);
    setLoading(true);
    try {
      const result = await apiClient.compareModels({
        spectrum: spectrum,
        modality: modality,
        model_names: selectedModels,
        include_provenance: true, // Add this property
      });
      setComparisonResult(result);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Comparison analysis failed."
      );
    } finally {
      setLoading(false);
    }
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div className="analysis-layout">
      {/* --- LEFT COLUMN (CONTROLS) --- */}
      <div className="analysis-column">
        <div className="card">
          <h3 className="card__title">1. Upload Spectrum</h3>
          <div
            {...getRootProps()}
            className={`dropzone ${isDragActive ? "dropzone--active" : ""}`}
          >
            <input {...getInputProps()} />
            <div className="dropzone-content">
              <span className="dropzone-icon">📤</span>
              <p className="dropzone__text">
                {isDragActive
                  ? "Drop file to upload"
                  : "Drag & drop, or click to select"}
              </p>
            </div>
          </div>
          {spectrum && (
            <div className="spectrum-info">
              <p>
                <strong>Loaded:</strong> {spectrum.filename || "Unknown"}
              </p>
            </div>
          )}
        </div>

        <div className="card">
          <h3 className="card__title">2. Select Models to Compare</h3>
          <div className="checkbox-grid">
            {availableModels.map((model) => (
              <label key={model.name} className="checkbox-label">
                <input
                  type="checkbox"
                  checked={selectedModels.includes(model.name)}
                  onChange={() => handleToggleModel(model.name)}
                />
                <span className="checkbox-custom"></span>
                {model.display_name || model.name}
              </label>
            ))}
          </div>
        </div>

        <div className="card">
          <h3 className="card__title">3. Run Comparison</h3>
          <div className="button-group">
            <button
              onClick={handleCompare}
              disabled={loading || !spectrum || selectedModels.length < 2}
              className="btn btn--primary"
            >
              {loading ? "Comparing..." : "Compare Models"}
            </button>
          </div>
          {error && (
            <div className="error-message" style={{ marginTop: "1rem" }}>
              {error}
            </div>
          )}
        </div>
      </div>

      {/* --- RIGHT COLUMN (RESULTS) --- */}
      <div className="analysis-column">
        <div className="card">
          <h3 className="card__title">Comparison Results</h3>
          {loading && (
            <div className="loading-indicator">
              <div className="spinner"></div>
              <span>Running comparison analysis...</span>
            </div>
          )}
          {comparisonResult ? (
            <div className="comparison-results-container">
              <div className="comparison-summary">
                <h4>Best Performing Model</h4>
                {comparisonResult.model_results && (
                  <p>
                    <strong>
                      {
                        Object.entries(comparisonResult.model_results).reduce(
                          (best, [modelName, res]) =>
                            res.confidence > best.confidence
                              ? { modelName, confidence: res.confidence }
                              : best,
                          { modelName: "Unknown", confidence: 0 }
                        ).modelName
                      }
                    </strong>{" "}
                    with a confidence of{" "}
                    <strong>
                      {(
                        Object.entries(comparisonResult.model_results).reduce(
                          (best, [_, res]) =>
                            res.confidence > best ? res.confidence : best,
                          0
                        ) * 100
                      ).toFixed(1)}
                      %
                    </strong>
                    .
                  </p>
                )}
              </div>
              <div className="comparison-grid">
                {comparisonResult.model_results &&
                  Object.entries(comparisonResult.model_results).map(
                    ([modelName, res]) => (
                      <div key={modelName} className="comparison-card">
                        <div className="results-wrapper">
                          <header className="results-header">
                            <div className="confidence-display">
                              <span className="confidence-display__label">
                                {modelName}
                              </span>
                              <span className="confidence-display__value">
                                {(res.confidence * 100).toFixed(1)}%
                              </span>
                            </div>
                            <div className="confidence-bar">
                              <div
                                className="confidence-bar__fill"
                                style={{
                                  width: `${(res.confidence * 100).toFixed(1)}%`,
                                }}
                              />
                            </div>
                          </header>
                        </div>
                      </div>
                    )
                  )}
              </div>
            </div>
          ) : (
            !loading && (
              <div className="placeholder">
                <p>
                  Upload a spectrum and select models to see comparison results.
                </p>
              </div>
            )
          )}
        </div>
      </div>
    </div>
  );
};

export default ModelComparison;
