"use client";

import { useState, useCallback } from "react";
import { useRouter } from "next/navigation";
import type { Scenario, ScenarioSummary } from "@/types/api";

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8000";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function pct(v: number) {
  return `${Math.round(v * 100)}%`;
}

const SCENARIO_ACCENT = [
  { border: "border-blue-400", bg: "bg-blue-50", text: "text-blue-700", bar: "bg-blue-400", light: "bg-blue-100" },
  { border: "border-violet-400", bg: "bg-violet-50", text: "text-violet-700", bar: "bg-violet-400", light: "bg-violet-100" },
  { border: "border-amber-400", bg: "bg-amber-50", text: "text-amber-700", bar: "bg-amber-400", light: "bg-amber-100" },
];

// ---------------------------------------------------------------------------
// Scenario Picker
// ---------------------------------------------------------------------------

function Picker({
  summaries,
  selectedIds,
  onToggle,
  onCompare,
  loading,
}: {
  summaries: ScenarioSummary[];
  selectedIds: string[];
  onToggle: (id: string) => void;
  onCompare: () => void;
  loading: boolean;
}) {
  const canCompare = selectedIds.length >= 2;

  if (summaries.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center rounded-2xl border border-dashed border-stone-200 bg-white py-24 text-center">
        <p className="text-sm font-medium text-stone-500">No scenarios found.</p>
        <p className="mt-1 text-xs text-stone-400">Run some simulations first, then come back to compare.</p>
      </div>
    );
  }

  return (
    <div>
      <div className="mb-4 flex items-center justify-between">
        <p className="text-sm text-stone-500">
          {selectedIds.length === 0
            ? "Select 2–3 scenarios to compare."
            : `${selectedIds.length} selected${selectedIds.length === 1 ? " — pick at least one more" : ""}`}
        </p>
        <button
          onClick={onCompare}
          disabled={!canCompare || loading}
          className="flex items-center gap-2 rounded-lg bg-emerald-800 px-4 py-2 text-sm font-semibold text-white transition hover:bg-emerald-700 disabled:opacity-40"
        >
          {loading && (
            <svg className="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
            </svg>
          )}
          Compare
        </button>
      </div>

      <div className="space-y-2">
        {summaries.map((s, i) => {
          const isSelected = selectedIds.includes(s.id);
          const selIdx = selectedIds.indexOf(s.id);
          const accent = selIdx >= 0 ? SCENARIO_ACCENT[selIdx] : null;
          const isMaxed = selectedIds.length >= 3 && !isSelected;

          return (
            <button
              key={s.id}
              onClick={() => !isMaxed && onToggle(s.id)}
              disabled={isMaxed}
              className={`flex w-full items-center gap-4 rounded-xl border-2 bg-white p-4 text-left transition ${
                isSelected
                  ? `${accent!.border} shadow-sm`
                  : isMaxed
                    ? "border-stone-100 opacity-40 cursor-not-allowed"
                    : "border-stone-200 hover:border-stone-300"
              }`}
            >
              {/* Checkbox */}
              <div
                className={`flex h-5 w-5 shrink-0 items-center justify-center rounded border-2 ${
                  isSelected
                    ? `${accent!.border} ${accent!.bg}`
                    : "border-stone-300 bg-white"
                }`}
              >
                {isSelected && (
                  <svg className={`h-3 w-3 ${accent!.text}`} fill="none" viewBox="0 0 24 24" strokeWidth={3} stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" d="m4.5 12.75 6 6 9-13.5" />
                  </svg>
                )}
              </div>

              <div className="flex-1 min-w-0">
                <p className="truncate text-sm font-semibold text-stone-900">{s.name}</p>
                <p className="mt-0.5 text-xs capitalize text-stone-500">
                  {s.season} · {s.duration_days} days ·{" "}
                  {new Date(s.created_at).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" })}
                </p>
              </div>

              <div className="hidden shrink-0 gap-5 sm:flex">
                {s.predicted_yield != null && (
                  <div className="text-right">
                    <p className="text-xs text-stone-400">Yield</p>
                    <p className="text-sm font-semibold text-stone-800">{s.predicted_yield.toFixed(2)} kg</p>
                  </div>
                )}
                {s.survival_probability != null && (
                  <div className="text-right">
                    <p className="text-xs text-stone-400">Survival</p>
                    <p className={`text-sm font-semibold ${s.survival_probability >= 0.75 ? "text-emerald-600" : s.survival_probability >= 0.55 ? "text-amber-500" : "text-red-500"}`}>
                      {pct(s.survival_probability)}
                    </p>
                  </div>
                )}
              </div>

              {isSelected && (
                <span className={`shrink-0 rounded-full px-2 py-0.5 text-xs font-bold ${accent!.light} ${accent!.text}`}>
                  #{selIdx + 1}
                </span>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Metric Bar (normalised across scenarios)
// ---------------------------------------------------------------------------

function MetricBars({
  label,
  values,
  format,
  higherIsBetter = true,
}: {
  label: string;
  values: (number | null)[];
  format: (v: number) => string;
  higherIsBetter?: boolean;
}) {
  const nums = values.filter((v): v is number => v != null);
  const max = Math.max(...nums, 0.001);
  const best = higherIsBetter ? Math.max(...nums) : Math.min(...nums);

  return (
    <div className="py-3">
      <p className="mb-2 text-xs font-semibold text-stone-500">{label}</p>
      <div className="space-y-2">
        {values.map((v, i) => {
          const accent = SCENARIO_ACCENT[i];
          const isBest = v === best && nums.length > 1;
          return (
            <div key={i} className="flex items-center gap-3">
              <span className={`w-4 text-xs font-bold ${accent.text}`}>#{i + 1}</span>
              <div className="flex-1">
                <div className="h-2 rounded-full bg-stone-100">
                  {v != null && (
                    <div
                      className={`h-2 rounded-full ${accent.bar}`}
                      style={{ width: `${(v / max) * 100}%` }}
                    />
                  )}
                </div>
              </div>
              <span className="w-16 text-right text-xs font-semibold text-stone-700">
                {v != null ? format(v) : "—"}
              </span>
              {isBest && (
                <span className="rounded-full bg-emerald-100 px-1.5 py-0.5 text-xs font-semibold text-emerald-700">
                  Best
                </span>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Comparison view
// ---------------------------------------------------------------------------

function CompareView({
  scenarios,
  onReset,
}: {
  scenarios: Scenario[];
  onReset: () => void;
}) {
  const allRisks = Array.from(
    new Set(scenarios.flatMap((s) => s.results?.risk_factors ?? []))
  );

  return (
    <div>
      {/* Change selection */}
      <div className="mb-6 flex items-center justify-between">
        <div className="flex gap-3">
          {scenarios.map((s, i) => {
            const accent = SCENARIO_ACCENT[i];
            return (
              <div key={s.id} className={`flex items-center gap-2 rounded-full border ${accent.border} ${accent.bg} px-3 py-1`}>
                <span className={`text-xs font-bold ${accent.text}`}>#{i + 1}</span>
                <span className="max-w-[140px] truncate text-xs font-medium text-stone-700">{s.name}</span>
              </div>
            );
          })}
        </div>
        <button
          onClick={onReset}
          className="rounded-lg border border-stone-200 bg-white px-3 py-1.5 text-xs font-medium text-stone-600 transition hover:bg-stone-50"
        >
          Change selection
        </button>
      </div>

      <div className="space-y-4">
        {/* ── Outcome Metrics ─────────────────────────────────────────── */}
        <div className="rounded-2xl border border-stone-200 bg-white p-6">
          <h2 className="mb-1 text-sm font-semibold text-stone-900">Outcome Metrics</h2>
          <p className="mb-4 text-xs text-stone-400">AI-predicted results for each scenario</p>
          <div className="divide-y divide-stone-100">
            <MetricBars
              label="Predicted Yield (kg/plant)"
              values={scenarios.map((s) => s.results?.predicted_yield ?? null)}
              format={(v) => `${v.toFixed(2)} kg`}
            />
            <MetricBars
              label="Survival Probability"
              values={scenarios.map((s) => s.results?.survival_probability ?? null)}
              format={pct}
            />
            <MetricBars
              label="AI Confidence Score"
              values={scenarios.map((s) => s.results?.confidence_score ?? null)}
              format={pct}
            />
          </div>
        </div>

        {/* ── Plant Setup ──────────────────────────────────────────────── */}
        <div className="rounded-2xl border border-stone-200 bg-white p-6">
          <h2 className="mb-4 text-sm font-semibold text-stone-900">Plant Setup</h2>
          <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${scenarios.length}, minmax(0,1fr))` }}>
            {scenarios.map((s, i) => {
              const accent = SCENARIO_ACCENT[i];
              const plant = s.plant ?? s.graft_combination?.scion;
              const graft = s.graft_combination;
              return (
                <div key={s.id} className={`rounded-xl border ${accent.border} ${accent.bg} p-4`}>
                  <p className={`mb-2 text-xs font-bold ${accent.text}`}>#{i + 1} {s.name}</p>
                  <div className="space-y-1.5 text-xs">
                    <div>
                      <span className="text-stone-400">Scion</span>
                      <p className="font-medium text-stone-800">{plant?.name ?? "—"}</p>
                    </div>
                    <div>
                      <span className="text-stone-400">Rootstock</span>
                      <p className="font-medium text-stone-800">
                        {graft ? graft.rootstock.name : <span className="text-stone-400">Ungrafted</span>}
                      </p>
                    </div>
                    {graft && (
                      <div>
                        <span className="text-stone-400">Compatibility</span>
                        <p className="font-medium text-emerald-700">{pct(graft.compatibility_score)}</p>
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* ── Soil ─────────────────────────────────────────────────────── */}
        <div className="rounded-2xl border border-stone-200 bg-white p-6">
          <h2 className="mb-4 text-sm font-semibold text-stone-900">Soil Environment</h2>
          <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${scenarios.length}, minmax(0,1fr))` }}>
            {scenarios.map((s, i) => {
              const accent = SCENARIO_ACCENT[i];
              const soil = s.soil_profile;
              return (
                <div key={s.id} className={`rounded-xl border ${accent.border} ${accent.bg} p-4`}>
                  <p className={`mb-2 text-xs font-bold ${accent.text}`}>#{i + 1}</p>
                  <div className="space-y-1.5 text-xs">
                    {[
                      { label: "Profile", value: soil.name },
                      { label: "Type", value: soil.soil_type },
                      { label: "Climate", value: soil.climate_zone },
                      { label: "pH", value: soil.ph_level },
                      { label: "Salinity", value: `${soil.salinity_level} dS/m` },
                    ].map((r) => (
                      <div key={r.label}>
                        <span className="text-stone-400">{r.label}</span>
                        <p className="font-medium capitalize text-stone-800">{r.value}</p>
                      </div>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* ── Care Protocol ─────────────────────────────────────────────── */}
        <div className="rounded-2xl border border-stone-200 bg-white p-6">
          <h2 className="mb-4 text-sm font-semibold text-stone-900">Care Protocol</h2>
          <div className="divide-y divide-stone-100">
            {[
              { label: "Nitrogen", values: scenarios.map((s) => `${s.applied_nitrogen} kg/ha`) },
              { label: "Phosphorus", values: scenarios.map((s) => `${s.applied_phosphorus} kg/ha`) },
              { label: "Potassium", values: scenarios.map((s) => `${s.applied_potassium} kg/ha`) },
              { label: "Irrigation", values: scenarios.map((s) => `${s.irrigation_method} / ${s.irrigation_frequency_days}d`) },
              { label: "Season", values: scenarios.map((s) => s.season) },
              { label: "Duration", values: scenarios.map((s) => `${s.duration_days} days`) },
            ].map((row) => (
              <div key={row.label} className="grid items-center gap-4 py-2.5" style={{ gridTemplateColumns: `100px repeat(${scenarios.length}, minmax(0,1fr))` }}>
                <span className="text-xs text-stone-400">{row.label}</span>
                {row.values.map((v, i) => {
                  const accent = SCENARIO_ACCENT[i];
                  return (
                    <span key={i} className={`rounded-lg ${accent.light} ${accent.text} px-2 py-1 text-xs font-medium capitalize`}>
                      {v}
                    </span>
                  );
                })}
              </div>
            ))}
          </div>
        </div>

        {/* ── Risk Factors ──────────────────────────────────────────────── */}
        {allRisks.length > 0 && (
          <div className="rounded-2xl border border-stone-200 bg-white p-6">
            <h2 className="mb-4 text-sm font-semibold text-stone-900">Risk Factors</h2>
            <div className="space-y-2">
              {allRisks.map((risk) => (
                <div key={risk} className="flex items-start gap-3 rounded-xl bg-stone-50 p-3">
                  <p className="flex-1 text-xs text-stone-700">{risk}</p>
                  <div className="flex shrink-0 gap-1.5">
                    {scenarios.map((s, i) => {
                      const accent = SCENARIO_ACCENT[i];
                      const hasRisk = s.results?.risk_factors.includes(risk);
                      return (
                        <span
                          key={s.id}
                          className={`rounded-full px-2 py-0.5 text-xs font-bold ${
                            hasRisk ? `${accent.light} ${accent.text}` : "bg-stone-100 text-stone-300"
                          }`}
                        >
                          #{i + 1}
                        </span>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main orchestrator
// ---------------------------------------------------------------------------

export default function CompareClient({
  summaries,
  initialFull,
  initialIds,
}: {
  summaries: ScenarioSummary[];
  initialFull: Scenario[];
  initialIds: string[];
}) {
  const router = useRouter();
  const [selectedIds, setSelectedIds] = useState<string[]>(initialIds.slice(0, 3));
  const [scenarios, setScenarios] = useState<Scenario[]>(initialFull);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const showComparison = scenarios.length >= 2;

  const toggle = useCallback((id: string) => {
    setSelectedIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id].slice(0, 3)
    );
  }, []);

  async function handleCompare() {
    setLoading(true);
    setError(null);
    try {
      const results = await Promise.all(
        selectedIds.map((id) =>
          fetch(`${API_BASE}/api/scenarios/${id}`, { cache: "no-store" }).then((r) => {
            if (!r.ok) throw new Error(`Failed to load scenario ${id}`);
            return r.json() as Promise<Scenario>;
          })
        )
      );
      setScenarios(results);
      router.replace(`/scenarios/compare?ids=${selectedIds.join(",")}`);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load scenarios.");
    } finally {
      setLoading(false);
    }
  }

  function handleReset() {
    setScenarios([]);
    setSelectedIds([]);
    router.replace("/scenarios/compare");
  }

  return (
    <div>
      {error && (
        <div className="mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
          {error}
        </div>
      )}

      {showComparison ? (
        <CompareView scenarios={scenarios} onReset={handleReset} />
      ) : (
        <Picker
          summaries={summaries}
          selectedIds={selectedIds}
          onToggle={toggle}
          onCompare={handleCompare}
          loading={loading}
        />
      )}
    </div>
  );
}
