"use client";

import { useQuery, useMutation } from "@tanstack/react-query";
import { api } from "@/lib/api";
import type {
  ProceedingType,
  CalculateResponse,
  CalculatedDeadline,
} from "@/lib/types";
import { format, parseISO, isPast, isThisWeek } from "date-fns";
import { de } from "date-fns/locale";
import {
  Calculator,
  Calendar,
  ArrowRight,
  AlertTriangle,
} from "lucide-react";
import { useState } from "react";

function getTimelineUrgency(dueDate: string): "red" | "amber" | "green" {
  const due = parseISO(dueDate);
  if (isPast(due)) return "red";
  if (isThisWeek(due, { weekStartsOn: 1 })) return "amber";
  return "green";
}

const dotColors = {
  red: "bg-red-500",
  amber: "bg-amber-500",
  green: "bg-green-500",
};

const inputClass =
  "w-full rounded-md border border-neutral-200 bg-white px-3 py-2 text-sm text-neutral-900 outline-none transition-colors focus:border-neutral-400 focus:ring-1 focus:ring-neutral-400";

export function DeadlineCalculator() {
  const [proceedingType, setProceedingType] = useState("");
  const [triggerDate, setTriggerDate] = useState(
    new Date().toISOString().split("T")[0],
  );

  const { data: proceedingTypes, isLoading: typesLoading } = useQuery({
    queryKey: ["proceeding-types"],
    queryFn: () => api.get<ProceedingType[]>("/proceeding-types"),
  });

  const calculateMutation = useMutation({
    mutationFn: (params: {
      proceeding_type: string;
      trigger_event_date: string;
    }) => api.post<CalculateResponse>("/deadlines/calculate", params),
  });

  // Auto-calculate when proceeding type changes (using current trigger date)
  function doCalculate(type: string, date: string) {
    if (!type || !date) return;
    calculateMutation.mutate({
      proceeding_type: type,
      trigger_event_date: date,
    });
  }

  function handleProceedingChange(newType: string) {
    setProceedingType(newType);
    doCalculate(newType, triggerDate);
  }

  function handleDateChange(newDate: string) {
    setTriggerDate(newDate);
    if (proceedingType) doCalculate(proceedingType, newDate);
  }

  function handleCalculate(e: React.FormEvent) {
    e.preventDefault();
    doCalculate(proceedingType, triggerDate);
  }

  const results = calculateMutation.data;

  return (
    <div className="space-y-6">
      {/* Input form */}
      <form
        onSubmit={handleCalculate}
        className="rounded-lg border border-neutral-200 bg-white p-5"
      >
        <div className="flex items-center gap-2 text-sm font-medium text-neutral-900">
          <Calculator className="h-4 w-4" />
          Fristenberechnung
        </div>
        <div className="mt-4 grid gap-4 sm:grid-cols-3">
          <div>
            <label className="mb-1 block text-xs font-medium text-neutral-500">
              Verfahrensart
            </label>
            <select
              value={proceedingType}
              onChange={(e) => handleProceedingChange(e.target.value)}
              disabled={typesLoading}
              className={inputClass}
            >
              <option value="">Bitte wählen...</option>
              {(() => {
                const types = proceedingTypes ?? [];
                const categoryLabels: Record<string, string> = {
                  hauptverfahren: "Hauptverfahren",
                  im_verfahren: "Verfahren im Verfahren",
                  rechtsbehelf: "Rechtsbehelfe",
                };
                const jurisdictionLabels: Record<string, string> = {
                  UPC: "UPC",
                  DE: "Deutsche Patentverfahren",
                };
                // Group by jurisdiction + category
                const groups: { key: string; label: string; items: typeof types }[] = [];
                const seen = new Set<string>();
                for (const pt of types) {
                  const j = pt.jurisdiction ?? "Sonstige";
                  const c = pt.category ?? "hauptverfahren";
                  const key = `${j}::${c}`;
                  if (!seen.has(key)) {
                    seen.add(key);
                    const jLabel = jurisdictionLabels[j] ?? j;
                    const cLabel = categoryLabels[c] ?? c;
                    const label = j === "DE" ? jLabel : `${jLabel} — ${cLabel}`;
                    groups.push({ key, label, items: [] });
                  }
                  groups.find((g) => g.key === key)!.items.push(pt);
                }
                return groups.map((g) => (
                  <optgroup key={g.key} label={g.label}>
                    {g.items.map((pt) => (
                      <option key={pt.id} value={pt.code}>
                        {pt.name}
                      </option>
                    ))}
                  </optgroup>
                ));
              })()}
            </select>
          </div>
          <div>
            <label className="mb-1 block text-xs font-medium text-neutral-500">
              Auslösedatum
            </label>
            <input
              type="date"
              value={triggerDate}
              onChange={(e) => handleDateChange(e.target.value)}
              className={inputClass}
            />
          </div>
          <div className="flex items-end">
            <button
              type="submit"
              disabled={
                !proceedingType ||
                !triggerDate ||
                calculateMutation.isPending
              }
              className="flex w-full items-center justify-center gap-2 rounded-md bg-neutral-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-neutral-800 disabled:cursor-not-allowed disabled:opacity-50"
            >
              {calculateMutation.isPending ? "Berechne..." : "Berechnen"}
              <ArrowRight className="h-3.5 w-3.5" />
            </button>
          </div>
        </div>
      </form>

      {/* Error */}
      {calculateMutation.isError && (
        <div className="flex items-center gap-2 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
          <AlertTriangle className="h-4 w-4 shrink-0" />
          Fehler bei der Berechnung. Bitte Eingaben prüfen.
        </div>
      )}

      {/* Results */}
      {results && results.deadlines && (
        <div className="animate-fade-in space-y-3">
          <div className="flex items-center justify-between">
            <h3 className="text-sm font-medium text-neutral-900">
              Berechnete Fristen
            </h3>
            <span className="text-xs text-neutral-500">
              {results.deadlines.length} Fristen ab{" "}
              {format(parseISO(results.trigger_event_date), "dd. MMM yyyy", {
                locale: de,
              })}
            </span>
          </div>

          {/* Timeline */}
          <div className="relative rounded-lg border border-neutral-200 bg-white">
            {results.deadlines.map((d: CalculatedDeadline, i: number) => {
              const urgency = getTimelineUrgency(d.due_date);
              const isLast = i === results.deadlines.length - 1;

              return (
                <div
                  key={d.rule_id}
                  className={`flex gap-3 px-4 py-3 ${!isLast ? "border-b border-neutral-100" : ""}`}
                >
                  <div className="flex flex-col items-center pt-1">
                    <div
                      className={`h-2.5 w-2.5 shrink-0 rounded-full ${dotColors[urgency]}`}
                    />
                    {!isLast && (
                      <div className="mt-1 w-px flex-1 bg-neutral-200" />
                    )}
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between sm:gap-2">
                      <span className="text-sm font-medium text-neutral-900">
                        {d.title}
                      </span>
                      <span className="shrink-0 text-sm font-medium tabular-nums text-neutral-700">
                        {format(parseISO(d.due_date), "dd.MM.yyyy")}
                      </span>
                    </div>
                    <div className="mt-0.5 flex flex-wrap items-center gap-2 text-xs text-neutral-500">
                      {d.rule_code && <span>{d.rule_code}</span>}
                      {d.was_adjusted && (
                        <>
                          {d.rule_code && <span>·</span>}
                          <span className="text-amber-600">
                            Angepasst (Original:{" "}
                            {format(
                              parseISO(d.original_due_date),
                              "dd.MM.yyyy",
                            )}
                            )
                          </span>
                        </>
                      )}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Empty state */}
      {!results && !calculateMutation.isPending && (
        <div className="flex flex-col items-center rounded-lg border border-dashed border-neutral-300 bg-white px-6 py-12 text-center">
          <div className="rounded-xl bg-neutral-100 p-3">
            <Calendar className="h-6 w-6 text-neutral-400" />
          </div>
          <p className="mt-3 text-sm text-neutral-500">
            Verfahrensart und Auslösedatum wählen, um Fristen zu berechnen
          </p>
        </div>
      )}
    </div>
  );
}
