"use client";

import { Download, Save, Trash2 } from "lucide-react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
import { deleteReport, saveReport } from "@/actions/reports";
import { useToast } from "@/components/ui/Toast";
import { fmtDate } from "@/lib/format";
import {
  AVERAGE_MEASURES,
  DATE_SCOPED_MEASURES,
  GROUP_LABELS,
  MEASURE_LABELS,
  REPORT_PRESETS,
  type GroupDimension,
  type Measure,
  type ReportRow,
} from "@/lib/reports";

const SPLIT_COLORS = ["bg-brand-500", "bg-info-text", "bg-purple-text", "bg-warning-text", "bg-success-text", "bg-danger-solid"];

type SavedReport = { id: string; name: string; config: Record<string, unknown> };

type ReportsPageClientProps = {
  measure: Measure;
  group: GroupDimension;
  split: GroupDimension | "";
  filters: { division: string; location: string; status: string; employment: string; from: string; to: string };
  rows: ReportRow[];
  total: number;
  recordCount: number;
  divisions: { id: string; name: string }[];
  locations: { id: string; name: string }[];
  savedReports: SavedReport[];
};

function formatValue(measure: Measure, value: number): string {
  if (["headcount", "hires", "exits"].includes(measure)) return String(Math.round(value));
  if (measure === "fte") return value.toFixed(1);
  if (measure === "avg_salary") return new Intl.NumberFormat("de-AT", { style: "currency", currency: "EUR" }).format(value);
  if (measure === "parttime_rate" || measure === "female_share") return `${value.toFixed(1)}%`;
  if (measure === "avg_age" || measure === "avg_tenure") return `${value.toFixed(1)} Jahre`;
  return value.toFixed(1);
}

export function ReportsPageClient(props: ReportsPageClientProps) {
  const { measure, group, split, filters, rows, total, recordCount, divisions, locations, savedReports } = props;
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const { showToast } = useToast();
  const [expandedKey, setExpandedKey] = useState<string | null>(null);

  function updateParams(patch: Record<string, string | undefined>) {
    const sp = new URLSearchParams(searchParams.toString());
    for (const [k, v] of Object.entries(patch)) {
      if (v) sp.set(k, v);
      else sp.delete(k);
    }
    router.push(`${pathname}?${sp.toString()}`);
  }

  function applyPreset(preset: (typeof REPORT_PRESETS)[number]) {
    router.push(`${pathname}?measure=${preset.measure}&group=${preset.group}${preset.split ? `&split=${preset.split}` : ""}`);
  }

  function applySavedReport(config: Record<string, unknown>) {
    const sp = new URLSearchParams();
    for (const [k, v] of Object.entries(config)) {
      if (typeof v === "string" && v) sp.set(k, v);
    }
    router.push(`${pathname}?${sp.toString()}`);
  }

  async function handleSaveReport() {
    const name = window.prompt("Name für diesen Bericht:");
    if (!name) return;
    const result = await saveReport({ name, config: { measure, group, split, ...filters } });
    if (result.success) {
      showToast("Bericht gespeichert.");
      router.refresh();
    } else {
      showToast(result.error ?? "Fehler beim Speichern.", "error");
    }
  }

  async function handleDeleteReport(id: string) {
    const result = await deleteReport(id);
    if (result.success) {
      showToast("Bericht gelöscht.");
      router.refresh();
    } else {
      showToast(result.error ?? "Fehler beim Löschen.", "error");
    }
  }

  function handleExportCsv() {
    const header = [GROUP_LABELS[group], MEASURE_LABELS[measure], "Anzahl", "Anteil (%)"];
    const lines = [header.join(";")];
    for (const row of rows) {
      const share = total > 0 ? ((row.value / total) * 100).toFixed(1) : "0";
      lines.push([row.key, formatValue(measure, row.value), String(row.count), share].join(";"));
    }
    const blob = new Blob([lines.join("\n")], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `bericht-${measure}-${group}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  }

  const isAverage = AVERAGE_MEASURES.includes(measure);
  const isDateScoped = DATE_SCOPED_MEASURES.includes(measure);
  const maxValue = Math.max(1, ...rows.map((r) => r.value));

  return (
    <div className="grid grid-cols-1 gap-4 lg:grid-cols-[320px_1fr]">
      <div className="flex flex-col gap-4">
        <div className="rounded border border-border bg-white p-4">
          <div className="flex flex-col gap-3">
            <div>
              <label className="mb-1 block text-xs font-semibold uppercase tracking-wide text-ink-muted">Kennzahl</label>
              <select
                value={measure}
                onChange={(e) => updateParams({ measure: e.target.value, split: AVERAGE_MEASURES.includes(e.target.value as Measure) ? undefined : split })}
                className="w-full rounded border border-border px-3 py-2 text-sm"
              >
                {(Object.keys(MEASURE_LABELS) as Measure[]).map((m) => (
                  <option key={m} value={m}>
                    {MEASURE_LABELS[m]}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="mb-1 block text-xs font-semibold uppercase tracking-wide text-ink-muted">Gruppieren nach</label>
              <select value={group} onChange={(e) => updateParams({ group: e.target.value })} className="w-full rounded border border-border px-3 py-2 text-sm">
                {(Object.keys(GROUP_LABELS) as GroupDimension[]).map((g) => (
                  <option key={g} value={g}>
                    {GROUP_LABELS[g]}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="mb-1 block text-xs font-semibold uppercase tracking-wide text-ink-muted">Aufteilen nach</label>
              <select
                value={split}
                disabled={isAverage}
                onChange={(e) => updateParams({ split: e.target.value || undefined })}
                className="w-full rounded border border-border px-3 py-2 text-sm disabled:bg-surface disabled:text-ink-muted"
              >
                <option value="">Keine Aufteilung</option>
                {(Object.keys(GROUP_LABELS) as GroupDimension[])
                  .filter((g) => g !== group)
                  .map((g) => (
                    <option key={g} value={g}>
                      {GROUP_LABELS[g]}
                    </option>
                  ))}
              </select>
            </div>
          </div>
        </div>

        <div className="rounded border border-border bg-white p-4">
          <h3 className="mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted">Filter</h3>
          <div className="flex flex-col gap-2">
            <select value={filters.division} onChange={(e) => updateParams({ division: e.target.value })} className="w-full rounded border border-border px-3 py-2 text-sm">
              <option value="">Alle Bereiche</option>
              {divisions.map((d) => (
                <option key={d.id} value={d.id}>
                  {d.name}
                </option>
              ))}
            </select>
            <select value={filters.location} onChange={(e) => updateParams({ location: e.target.value })} className="w-full rounded border border-border px-3 py-2 text-sm">
              <option value="">Alle Standorte</option>
              {locations.map((l) => (
                <option key={l.id} value={l.id}>
                  {l.name}
                </option>
              ))}
            </select>
            <select value={filters.status} onChange={(e) => updateParams({ status: e.target.value })} className="w-full rounded border border-border px-3 py-2 text-sm">
              <option value="">Alle Status</option>
              <option value="Aktiv">Aktiv</option>
              <option value="Karenz">Karenz</option>
              <option value="Geplant">Geplant</option>
              <option value="Ausgetreten">Ausgetreten</option>
            </select>
            <select
              value={filters.employment}
              onChange={(e) => updateParams({ employment: e.target.value })}
              className="w-full rounded border border-border px-3 py-2 text-sm"
            >
              <option value="">Alle Beschäftigungsarten</option>
              <option value="Vollzeit">Vollzeit</option>
              <option value="Teilzeit">Teilzeit</option>
            </select>
            {isDateScoped && (
              <div className="grid grid-cols-2 gap-2">
                <input
                  type="date"
                  value={filters.from}
                  onChange={(e) => updateParams({ from: e.target.value })}
                  className="w-full rounded border border-border px-2 py-2 text-xs"
                />
                <input
                  type="date"
                  value={filters.to}
                  onChange={(e) => updateParams({ to: e.target.value })}
                  className="w-full rounded border border-border px-2 py-2 text-xs"
                />
              </div>
            )}
          </div>
        </div>

        <div className="rounded border border-border bg-white p-4">
          <h3 className="mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted">Vorlagen</h3>
          <div className="flex flex-wrap gap-1.5">
            {REPORT_PRESETS.map((preset) => (
              <button
                key={preset.name}
                type="button"
                onClick={() => applyPreset(preset)}
                className="rounded-full border border-border px-2.5 py-1 text-xs font-semibold text-ink-body hover:bg-surface"
              >
                {preset.name}
              </button>
            ))}
          </div>
        </div>

        {savedReports.length > 0 && (
          <div className="rounded border border-border bg-white p-4">
            <h3 className="mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted">Gespeicherte Berichte</h3>
            <ul className="flex flex-col divide-y divide-border">
              {savedReports.map((r) => (
                <li key={r.id} className="flex items-center justify-between py-1.5 text-sm">
                  <button type="button" onClick={() => applySavedReport(r.config)} className="text-left text-ink-body hover:text-brand-700 hover:underline">
                    {r.name}
                  </button>
                  <button type="button" onClick={() => handleDeleteReport(r.id)} aria-label="Löschen" className="text-ink-muted hover:text-danger-solid">
                    <Trash2 className="h-3.5 w-3.5" />
                  </button>
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>

      <div className="rounded border border-border bg-white p-4">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
          <div>
            <h2 className="text-base font-bold text-ink">
              {MEASURE_LABELS[measure]} nach {GROUP_LABELS[group]}
            </h2>
            <p className="text-xs text-ink-muted">{recordCount} Datensätze</p>
          </div>
          <div className="flex gap-2">
            <button
              type="button"
              onClick={handleExportCsv}
              className="flex items-center gap-1.5 rounded border border-border px-3 py-1.5 text-sm font-semibold text-ink-body hover:bg-surface"
            >
              <Download className="h-4 w-4" />
              CSV exportieren
            </button>
            <button
              type="button"
              onClick={handleSaveReport}
              className="flex items-center gap-1.5 rounded border border-border px-3 py-1.5 text-sm font-semibold text-ink-body hover:bg-surface"
            >
              <Save className="h-4 w-4" />
              Bericht speichern
            </button>
          </div>
        </div>

        <p className="mb-4 text-2xl font-extrabold text-ink">{formatValue(measure, total)}</p>

        {split && (
          <div className="mb-3 flex flex-wrap gap-3">
            {Array.from(new Set(rows.flatMap((r) => r.split?.map((s) => s.key) ?? []))).map((key, i) => (
              <span key={key} className="flex items-center gap-1.5 text-xs text-ink-body">
                <span className={`h-2.5 w-2.5 rounded-full ${SPLIT_COLORS[i % SPLIT_COLORS.length]}`} />
                {key}
              </span>
            ))}
          </div>
        )}

        <div className="flex flex-col gap-3">
          {rows.map((row) => {
            const share = total > 0 ? (row.value / total) * 100 : 0;
            const isExpanded = expandedKey === row.key;
            return (
              <div key={row.key}>
                <button
                  type="button"
                  onClick={() => setExpandedKey(isExpanded ? null : row.key)}
                  className="w-full text-left"
                >
                  <div className="mb-1 flex items-center justify-between text-sm">
                    <span className="font-semibold text-ink">{row.key}</span>
                    <span className="text-ink-body">
                      {formatValue(measure, row.value)} <span className="text-xs text-ink-muted">({share.toFixed(1)}%)</span>
                    </span>
                  </div>
                  <div className="flex h-2.5 overflow-hidden rounded bg-surface">
                    {row.split ? (
                      row.split.map((s, i) => (
                        <div
                          key={s.key}
                          className={SPLIT_COLORS[i % SPLIT_COLORS.length]}
                          style={{ width: `${maxValue > 0 ? (s.value / maxValue) * 100 : 0}%` }}
                        />
                      ))
                    ) : (
                      <div className="bg-brand-500" style={{ width: `${(row.value / maxValue) * 100}%` }} />
                    )}
                  </div>
                </button>
                {isExpanded && (
                  <div className="mt-2 rounded border border-border bg-surface p-3">
                    <ul className="flex flex-col divide-y divide-border">
                      {row.people.slice(0, 12).map((p) => (
                        <li key={p.id} className="flex items-center justify-between py-1.5 text-sm">
                          <Link href={`/employees/${p.id}`} className="font-semibold text-ink hover:text-brand-700 hover:underline">
                            {p.name}
                          </Link>
                          <span className="text-xs text-ink-muted">
                            {p.title} · {p.team} · {fmtDate(p.entry_date)}
                          </span>
                        </li>
                      ))}
                    </ul>
                    {row.people.length > 12 && <p className="mt-2 text-xs text-ink-muted">+{row.people.length - 12} weitere</p>}
                  </div>
                )}
              </div>
            );
          })}
          {rows.length === 0 && <p className="text-sm text-ink-muted">Keine Daten für diese Auswahl.</p>}
        </div>
      </div>
    </div>
  );
}
