import { createFileRoute, Link, useParams } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";
import {
  ArrowLeft,
  Download,
  Waves,
  BatteryLow,
  Activity,
  AlertOctagon,
  AlertTriangle,
  CheckCircle2,
  Gauge,
} from "lucide-react";
import { getResult } from "@/lib/history";
import { exportToCsv, type AnalysisResult, type Severity } from "@/lib/electrical";
import { StatCard } from "@/components/stat-card";
import { SeverityBadge } from "@/components/severity-badge";
import { PhaseChart, PhaseLegend } from "@/components/phase-chart";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/analysis/$id")({
  component: AnalysisPage,
});

function AnalysisPage() {
  const { id } = useParams({ from: "/analysis/$id" });
  const [result, setResult] = useState<AnalysisResult | null | undefined>(undefined);

  useEffect(() => {
    setResult(getResult(id));
  }, [id]);

  if (result === undefined) {
    return <p className="py-20 text-center text-muted-foreground">Loading analysis…</p>;
  }

  if (result === null) {
    return (
      <div className="flex flex-col items-center gap-3 py-20 text-center">
        <AlertOctagon className="h-10 w-10 text-muted-foreground" />
        <h1 className="font-display text-xl font-bold text-foreground">Analysis not found</h1>
        <p className="text-sm text-muted-foreground">
          This report isn't on this device. It may have been created elsewhere.
        </p>
        <Link to="/upload" className="mt-2 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground">
          Upload a file
        </Link>
      </div>
    );
  }

  return <AnalysisView result={result} />;
}

const METRIC_TABS = [
  { key: "current" as const, label: "Current" },
  { key: "voltage" as const, label: "Voltage" },
];

const SEVERITY_FILTERS: { key: "anomalies" | Severity; label: string }[] = [
  { key: "anomalies", label: "Anomalies" },
  { key: "critical", label: "Critical" },
  { key: "warning", label: "Warning" },
  { key: "ok", label: "Normal" },
];

function AnalysisView({ result }: { result: AnalysisResult }) {
  const [metric, setMetric] = useState<"current" | "voltage">("current");
  const [filter, setFilter] = useState<"anomalies" | Severity>("anomalies");

  const anomalyPct = result.totalRows
    ? ((result.anomalyCount / result.totalRows) * 100).toFixed(1)
    : "0";

  const filteredRows = useMemo(() => {
    const rows =
      filter === "anomalies"
        ? result.rows.filter((r) => r.severity !== "ok")
        : result.rows.filter((r) => r.severity === filter);
    return rows.slice(0, 300);
  }, [result, filter]);

  const download = () => {
    const csv = exportToCsv(result);
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = result.filename.replace(/\.[^.]+$/, "") + "_anomalies.csv";
    a.click();
    URL.revokeObjectURL(url);
  };

  const num = (n: number | null, d = 2) => (n === null ? "—" : n.toFixed(d));

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div className="min-w-0">
          <Link
            to="/history"
            className="inline-flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
          >
            <ArrowLeft className="h-4 w-4" />
            History
          </Link>
          <h1 className="mt-1 truncate font-display text-2xl font-bold text-foreground sm:text-3xl">
            {result.filename}
          </h1>
          <p className="mt-1 text-sm text-muted-foreground">
            {result.totalRows.toLocaleString()} rows · analyzed{" "}
            {new Date(result.uploadDate).toLocaleString()}
          </p>
        </div>
        <button
          onClick={download}
          className="inline-flex items-center gap-2 rounded-xl bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground shadow-[var(--shadow-glow)] transition-transform hover:scale-[1.02]"
        >
          <Download className="h-4 w-4" />
          Export CSV
        </button>
      </div>

      {/* Overall banner */}
      <OverallBanner result={result} anomalyPct={anomalyPct} />

      {/* Stats */}
      <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard
          label="Anomaly rate"
          value={`${anomalyPct}%`}
          sub={`${result.anomalyCount.toLocaleString()} of ${result.totalRows.toLocaleString()} rows`}
          icon={<Gauge className="h-5 w-5" />}
          tone={Number(anomalyPct) > 5 ? "warning" : "primary"}
        />
        <StatCard
          label="Unbalance current"
          value={result.unbalanceCount.toLocaleString()}
          sub={`≥ ${result.thresholds.unbalanceWarn}% imbalance`}
          icon={<Waves className="h-5 w-5" />}
          tone={result.unbalanceCount > 0 ? "warning" : "default"}
        />
        <StatCard
          label="Under voltage"
          value={result.underVoltageCount.toLocaleString()}
          sub={`ref ${num(result.referenceVoltage, 1)} V`}
          icon={<BatteryLow className="h-5 w-5" />}
          tone={result.underVoltageCount > 0 ? "warning" : "default"}
        />
        <StatCard
          label="Critical events"
          value={result.criticalCount.toLocaleString()}
          sub={`${result.warningCount.toLocaleString()} warnings`}
          icon={<AlertOctagon className="h-5 w-5" />}
          tone={result.criticalCount > 0 ? "critical" : "success"}
        />
      </div>

      {/* Charts */}
      <section className="rounded-xl border border-border bg-card p-4 shadow-[var(--shadow-panel)] sm:p-5">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
          <div className="flex items-center gap-2">
            <Activity className="h-4 w-4 text-primary" />
            <h2 className="font-display text-lg font-semibold text-foreground">Per-phase trend</h2>
          </div>
          <div className="flex rounded-lg border border-border bg-secondary/50 p-0.5">
            {METRIC_TABS.map((t) => (
              <button
                key={t.key}
                onClick={() => setMetric(t.key)}
                className={cn(
                  "rounded-md px-4 py-1.5 text-sm font-medium transition-colors",
                  metric === t.key
                    ? "bg-card text-foreground shadow-sm"
                    : "text-muted-foreground hover:text-foreground",
                )}
              >
                {t.label}
              </button>
            ))}
          </div>
        </div>
        <PhaseChart result={result} metric={metric} />
        <div className="mt-3">
          <PhaseLegend />
        </div>
      </section>

      {/* Anomaly table */}
      <section className="rounded-xl border border-border bg-card shadow-[var(--shadow-panel)]">
        <div className="flex flex-wrap items-center justify-between gap-3 border-b border-border p-4">
          <h2 className="font-display text-lg font-semibold text-foreground">Row details</h2>
          <div className="flex flex-wrap gap-1.5">
            {SEVERITY_FILTERS.map((f) => (
              <button
                key={f.key}
                onClick={() => setFilter(f.key)}
                className={cn(
                  "rounded-full px-3 py-1 text-xs font-semibold transition-colors",
                  filter === f.key
                    ? "bg-primary text-primary-foreground"
                    : "bg-secondary text-secondary-foreground hover:bg-secondary/70",
                )}
              >
                {f.label}
              </button>
            ))}
          </div>
        </div>

        {filteredRows.length === 0 ? (
          <div className="flex flex-col items-center gap-2 p-10 text-center">
            <CheckCircle2 className="h-8 w-8 text-success" />
            <p className="text-sm text-muted-foreground">No rows match this filter.</p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[640px] text-sm">
              <thead>
                <tr className="border-b border-border text-left text-xs uppercase tracking-wide text-muted-foreground">
                  <th className="px-4 py-2.5 font-semibold">#</th>
                  <th className="px-4 py-2.5 font-semibold">Timestamp</th>
                  <th className="px-4 py-2.5 text-right font-semibold">I R/S/T</th>
                  <th className="px-4 py-2.5 text-right font-semibold">Unbal %</th>
                  <th className="px-4 py-2.5 text-right font-semibold">V R/S/T</th>
                  <th className="px-4 py-2.5 font-semibold">Status</th>
                </tr>
              </thead>
              <tbody>
                {filteredRows.map((r) => (
                  <tr
                    key={r.rowNumber}
                    className={cn(
                      "border-b border-border/60 last:border-0",
                      r.severity === "critical" && "bg-destructive/[0.04]",
                      r.severity === "warning" && "bg-warning/[0.05]",
                    )}
                  >
                    <td className="px-4 py-2.5 font-mono text-xs tabular-nums text-muted-foreground">
                      {r.rowNumber}
                    </td>
                    <td className="px-4 py-2.5 text-xs text-muted-foreground">
                      {r.timestamp ? String(r.timestamp).replace(/\.\d+$/, "") : "—"}
                    </td>
                    <td className="px-4 py-2.5 text-right font-mono text-xs tabular-nums">
                      {num(r.currents.R)}/{num(r.currents.S)}/{num(r.currents.T)}
                    </td>
                    <td
                      className={cn(
                        "px-4 py-2.5 text-right font-mono text-xs font-semibold tabular-nums",
                        r.isUnbalance ? "text-destructive" : "text-muted-foreground",
                      )}
                    >
                      {num(r.unbalancePercentage, 1)}
                    </td>
                    <td
                      className={cn(
                        "px-4 py-2.5 text-right font-mono text-xs tabular-nums",
                        r.isUnderVoltage && "font-semibold text-destructive",
                      )}
                    >
                      {num(r.voltages.R)}/{num(r.voltages.S)}/{num(r.voltages.T)}
                    </td>
                    <td className="px-4 py-2.5">
                      <SeverityBadge severity={r.severity} showIcon={false} />
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {(filter === "anomalies"
              ? result.anomalyCount
              : result.rows.filter((r) => r.severity === filter).length) > filteredRows.length && (
              <p className="p-3 text-center text-xs text-muted-foreground">
                Showing first {filteredRows.length} rows. Export CSV for the full dataset.
              </p>
            )}
          </div>
        )}
      </section>
    </div>
  );
}

function OverallBanner({ result, anomalyPct }: { result: AnalysisResult; anomalyPct: string }) {
  const level: Severity =
    result.criticalCount > 0 ? "critical" : result.anomalyCount > 0 ? "warning" : "ok";
  const config = {
    critical: {
      icon: AlertOctagon,
      title: "Critical anomalies detected",
      className: "border-destructive/30 bg-destructive/[0.06]",
      iconClass: "bg-destructive/10 text-destructive",
    },
    warning: {
      icon: AlertTriangle,
      title: "Anomalies need attention",
      className: "border-warning/40 bg-warning/[0.08]",
      iconClass: "bg-warning/20 text-warning-foreground",
    },
    ok: {
      icon: CheckCircle2,
      title: "All readings within limits",
      className: "border-success/30 bg-success/[0.06]",
      iconClass: "bg-success/10 text-success",
    },
  }[level];
  const Icon = config.icon;

  return (
    <div className={cn("flex items-center gap-4 rounded-xl border p-4 sm:p-5", config.className)}>
      <span className={cn("flex h-12 w-12 shrink-0 items-center justify-center rounded-xl", config.iconClass)}>
        <Icon className="h-6 w-6" />
      </span>
      <div>
        <p className="font-display text-lg font-bold text-foreground">{config.title}</p>
        <p className="text-sm text-muted-foreground">
          {result.anomalyCount.toLocaleString()} anomalies across {result.totalRows.toLocaleString()}{" "}
          rows ({anomalyPct}%). {result.unbalanceCount.toLocaleString()} unbalance ·{" "}
          {result.underVoltageCount.toLocaleString()} under-voltage.
        </p>
      </div>
    </div>
  );
}
