"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/ui/Icon";
import { DatePicker } from "@/components/ui/DatePicker";
import { TimePicker } from "@/components/ui/TimePicker";
import { alertDialog } from "@/components/ui/Dialog";
import { startTimerAction, stopTimerAction, addManualEntryAction } from "@/lib/time/actions";
import type { TimeEntryDTO, YearStats, DayInfo } from "@/lib/time/queries";
import type { AbsenceTypeDef } from "@/lib/settings";

function pad(n: number) {
  return String(n).padStart(2, "0");
}
function fmtClock(sec: number): string {
  const h = Math.floor(sec / 3600);
  const m = Math.floor((sec % 3600) / 60);
  const s = sec % 60;
  return h > 0 ? `${h}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`;
}
function fmtHM(sec: number): string {
  const h = Math.floor(sec / 3600);
  const m = Math.round((sec % 3600) / 60);
  return h > 0 ? `${h} Std. ${m} Min.` : `${m} Min.`;
}
function fmtTime(iso: string): string {
  return new Date(iso).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
}

const MONTHS = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];

export function TimeTracker({
  running,
  weekSeconds,
  submitted,
  stats,
  year,
  absenceTypes,
}: {
  running: TimeEntryDTO | null;
  weekSeconds: number;
  submitted: TimeEntryDTO[];
  stats: YearStats;
  year: number;
  absenceTypes: AbsenceTypeDef[];
}) {
  const router = useRouter();
  const [tab, setTab] = useState<"track" | "requests" | "overview">("track");
  const [note, setNote] = useState("");
  const [busy, setBusy] = useState(false);
  const [now, setNow] = useState(() => Date.now());

  const today = new Date().toISOString().slice(0, 10);
  const [mDate, setMDate] = useState(today);
  const [mStart, setMStart] = useState("09:00");
  const [mEnd, setMEnd] = useState("17:00");
  const [mNote, setMNote] = useState("");
  const [mError, setMError] = useState<string | null>(null);
  const [mOk, setMOk] = useState(false);

  useEffect(() => {
    if (!running) return;
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, [running]);

  const elapsed = running ? Math.max(0, Math.floor((now - new Date(running.startedAt).getTime()) / 1000)) : 0;

  const start = async () => {
    setBusy(true);
    const res = await startTimerAction(null, note);
    setBusy(false);
    if (res.error) return alertDialog({ title: "Fehler", message: res.error, danger: true });
    setNote("");
    router.refresh();
  };
  const stop = async () => {
    setBusy(true);
    const res = await stopTimerAction();
    setBusy(false);
    if (res.error) return alertDialog({ title: "Fehler", message: res.error, danger: true });
    router.refresh();
  };
  const addManual = async () => {
    setBusy(true);
    setMError(null);
    setMOk(false);
    const res = await addManualEntryAction({ date: mDate, start: mStart, end: mEnd, note: mNote });
    setBusy(false);
    if (res.error) return setMError(res.error);
    setMNote("");
    setMOk(true);
    router.refresh();
  };

  return (
    <div className="flex flex-col gap-5">
      <div className="seg" style={{ alignSelf: "flex-start" }}>
        <button className="seg-btn" data-active={tab === "track"} onClick={() => setTab("track")}>
          <Icon name="time" size={15} /> Eintragen
        </button>
        <button className="seg-btn" data-active={tab === "requests"} onClick={() => setTab("requests")}>
          <Icon name="mail" size={15} /> Offene Anfragen{submitted.length ? ` · ${submitted.length}` : ""}
        </button>
        <button className="seg-btn" data-active={tab === "overview"} onClick={() => setTab("overview")}>
          <Icon name="dashboard" size={15} /> Übersicht
        </button>
      </div>

      {tab === "track" ? (
        <>
          <section className="card stempeluhr">
            <div className="stempel-main">
              <span className={`stempel-orb ${running ? "is-running" : ""}`}>
                <Icon name={running ? "stop" : "play"} size={26} />
              </span>
              <div className="min-w-0 flex-1">
                <div className="stempel-time">{running ? fmtClock(elapsed) : "00:00:00"}</div>
                <div className="text-muted text-sm">{running ? `Läuft seit ${fmtTime(running.startedAt)}` : "Bereit zum Starten"}</div>
              </div>
              {running ? (
                <button className="btn btn-danger stempel-btn" onClick={stop} disabled={busy}><Icon name="stop" size={18} /> Stoppen</button>
              ) : (
                <button className="btn btn-primary stempel-btn" onClick={start} disabled={busy}><Icon name="play" size={18} /> Einstempeln</button>
              )}
            </div>
            {!running ? (
              <div className="mt-4 border-t pt-4" style={{ borderColor: "var(--line)" }}>
                <input className="input" placeholder="Woran arbeitest du? (optional)" value={note} onChange={(e) => setNote(e.target.value)} />
              </div>
            ) : null}
            <div className="stempel-stats">
              <div><span className="stempel-stat-value">{fmtHM(weekSeconds + elapsed)}</span><span className="stempel-stat-label">Diese Woche</span></div>
              <div><span className="stempel-stat-value">{fmtHM(stats.month)}</span><span className="stempel-stat-label">Dieser Monat</span></div>
              <div><span className="stempel-stat-value">{fmtHM(stats.year)}</span><span className="stempel-stat-label">{year}</span></div>
            </div>
          </section>

          <section className="card">
            <h2 className="mb-1">Manuell erfassen</h2>
            <p className="text-muted mb-3 text-sm">Manuelle Einträge gehen zur Freigabe an deine zuständige Person.</p>
            {mError ? <p className="field-error mb-2">{mError}</p> : null}
            {mOk ? <p className="mb-2 text-sm" style={{ color: "#7ee787" }}>Eingereicht — wartet auf Freigabe.</p> : null}
            <div className="flex flex-wrap items-end gap-3">
              <div className="field" style={{ width: 190 }}><label className="label">Datum</label><DatePicker value={mDate} onChange={setMDate} /></div>
              <div className="field" style={{ width: 130 }}><label className="label">Von</label><TimePicker value={mStart} onChange={setMStart} /></div>
              <div className="field" style={{ width: 130 }}><label className="label">Bis</label><TimePicker value={mEnd} onChange={setMEnd} /></div>
              <div className="field" style={{ minWidth: 180, flex: 1 }}><label className="label">Notiz</label><input className="input" value={mNote} onChange={(e) => setMNote(e.target.value)} placeholder="Optional" /></div>
              <button className="btn btn-ghost" onClick={addManual} disabled={busy}><Icon name="plus" size={15} /> Einreichen</button>
            </div>
          </section>
        </>
      ) : null}

      {tab === "requests" ? (
        <section className="card">
          <div className="mb-4 flex items-center justify-between">
            <div>
              <h2>Offene Anfragen</h2>
              <p className="text-muted text-xs mt-0.5">Eingereichte Zeiten warten auf Freigabe deiner zuständigen Person.</p>
            </div>
            <span className="badge">{submitted.length}</span>
          </div>
          {submitted.length === 0 ? (
            <div className="empty-hint">
              <span className="empty-hint-icon"><Icon name="mail" size={22} /></span>
              <div>
                <div className="font-bold">Alles freigegeben</div>
                <div className="text-muted text-sm">Manuell erfasste Zeiten erscheinen hier, bis sie freigegeben werden.</div>
              </div>
            </div>
          ) : (
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              {submitted.map((e) => (
                <div key={e.id} className="request-card">
                  <div className="request-dur">
                    <span className="request-dur-val">{fmtClock(e.durationSeconds)}</span>
                    <span className="request-dur-lbl">Stunden</span>
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="font-bold">{new Date(e.startedAt).toLocaleDateString("de-DE", { weekday: "short", day: "2-digit", month: "long" })}</div>
                    <div className="text-muted text-xs">{fmtTime(e.startedAt)}{e.endedAt ? `–${fmtTime(e.endedAt)}` : ""}{e.note ? ` · ${e.note}` : ""}</div>
                    <span className="status-badge mt-2" data-status="INVITED"><span className="status-badge-dot" /> Wartet auf Freigabe</span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </section>
      ) : null}

      {tab === "overview" ? (
        <section className="card">
          <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
            <h2>Jahresübersicht {year}</h2>
            <div className="flex gap-4 text-sm">
              <span><span className="font-bold">{fmtHM(stats.week)}</span> <span className="text-muted">Woche</span></span>
              <span><span className="font-bold">{fmtHM(stats.month)}</span> <span className="text-muted">Monat</span></span>
              <span><span className="font-bold">{fmtHM(stats.year)}</span> <span className="text-muted">Jahr</span></span>
            </div>
          </div>
          <Heatmap perDay={stats.perDay} year={year} absenceTypes={absenceTypes} />
        </section>
      ) : null}
    </div>
  );
}

// ── Jahres-Heatmap: nach Monaten getrennt, mit Custom-Hover-Box ─────────────
function Heatmap({
  perDay,
  year,
  absenceTypes,
}: {
  perDay: Record<string, DayInfo>;
  year: number;
  absenceTypes: AbsenceTypeDef[];
}) {
  const [hover, setHover] = useState<{ x: number; y: number; key: string } | null>(null);
  const typeMeta = (k: string) => absenceTypes.find((t) => t.key === k) ?? { key: k, label: k, color: "#8aa0c8" };

  const workLevel = (sec: number) => {
    const h = sec / 3600;
    if (h <= 0) return 0;
    if (h < 2) return 1;
    if (h < 5) return 2;
    if (h < 8) return 3;
    return 4;
  };
  const keyOf = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;

  const info = hover ? perDay[hover.key] : undefined;

  return (
    <div className="heatmap2-wrap" onMouseLeave={() => setHover(null)}>
      <div className="heatmap2-months">
        {Array.from({ length: 12 }, (_, m) => {
          const first = new Date(year, m, 1);
          const offset = (first.getDay() + 6) % 7;
          const daysInMonth = new Date(year, m + 1, 0).getDate();
          const cells = offset + daysInMonth;
          const cols = Math.ceil(cells / 7);
          return (
            <div key={m} className="heatmap2-month">
              <div className="heatmap2-month-label">{MONTHS[m].slice(0, 3)}</div>
              <div className="heatmap2-grid" style={{ gridTemplateColumns: `repeat(${cols}, 13px)`, gridTemplateRows: "repeat(7, 13px)", gridAutoFlow: "column" }}>
                {Array.from({ length: cols * 7 }, (_, i) => {
                  const dayNum = i - offset + 1;
                  if (dayNum < 1 || dayNum > daysInMonth) return <span key={i} className="heatmap2-cell" data-empty />;
                  const d = new Date(year, m, dayNum);
                  const key = keyOf(d);
                  const di = perDay[key];
                  const abs = di?.absence;
                  const work = (di?.timer ?? 0) + (di?.manual ?? 0);
                  const style: React.CSSProperties = abs
                    ? { background: typeMeta(abs).color }
                    : {};
                  return (
                    <span
                      key={i}
                      className="heatmap2-cell"
                      data-level={abs ? undefined : workLevel(work)}
                      data-absence={abs ? "" : undefined}
                      style={style}
                      onMouseEnter={(e) => {
                        const r = (e.currentTarget as HTMLElement).getBoundingClientRect();
                        const wrap = (e.currentTarget.closest(".heatmap2-wrap") as HTMLElement).getBoundingClientRect();
                        setHover({ x: r.left - wrap.left + r.width / 2, y: r.top - wrap.top, key });
                      }}
                    />
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>

      {hover ? (
        <div className="heatmap2-tip" style={{ left: hover.x, top: hover.y }}>
          <div className="font-bold">{new Date(`${hover.key}T12:00`).toLocaleDateString("de-DE", { weekday: "long", day: "2-digit", month: "long" })}</div>
          {info?.absence ? (
            <div className="mt-1 flex items-center gap-1.5">
              <span className="status-badge-dot" style={{ background: typeMeta(info.absence).color }} />
              {typeMeta(info.absence).label}
            </div>
          ) : info && info.timer + info.manual > 0 ? (
            <div className="mt-1 flex flex-col gap-0.5 text-xs">
              <span><span className="text-muted">Stempelzeit:</span> {fmtHM(info.timer)}</span>
              <span><span className="text-muted">Manuell:</span> {fmtHM(info.manual)}</span>
              <span className="font-bold">Gesamt: {fmtHM(info.timer + info.manual)}</span>
            </div>
          ) : (
            <div className="text-muted mt-1 text-xs">Keine Zeit erfasst</div>
          )}
        </div>
      ) : null}

      <div className="heatmap2-legend">
        <span className="text-muted text-xs">Arbeitszeit</span>
        {[0, 1, 2, 3, 4].map((l) => (<span key={l} className="heatmap2-cell heatmap2-cell-static" data-level={l} />))}
        <span className="text-muted text-xs">mehr</span>
        <span className="heatmap2-legend-sep" />
        {absenceTypes.slice(0, 6).map((t) => (
          <span key={t.key} className="inline-flex items-center gap-1.5 text-xs text-muted">
            <span className="heatmap2-cell heatmap2-cell-static" style={{ background: t.color }} />
            {t.label}
          </span>
        ))}
      </div>
    </div>
  );
}
