import React, { useEffect, useMemo, useRef, useState } from "react";
import { getAuditLogs, getUsersLite } from "../../api";

/* ----------------------------- kleine Utils ----------------------------- */
function classNames(...xs) { return xs.filter(Boolean).join(" "); }

function euroDelta(newC, oldC) {
  // null/undefined → kein Wert
  if (newC == null || oldC == null) return "—";
  // Strings erlauben
  const n = Number(newC);
  const o = Number(oldC);
  if (!Number.isFinite(n) || !Number.isFinite(o)) return "—";
  const d = (n - o) / 100;
  return (d >= 0 ? "+" : "") + d.toFixed(2) + " €";
}


function fmtDT(v) {
  if (v == null) return "—_-";
  // ganze oder dezimale Zahl-Strings → Zahl
  if (typeof v === "string" && /^\d+(\.\d+)?$/.test(v)) v = Number(v);
  // Sekunden → ms
  if (typeof v === "number" && v < 1e12) v = v * 1000;
  const d = new Date(v);
  return Number.isNaN(d.getTime()) ? "—" : d.toLocaleString();
}

// vereinheitlicht Zeitfelder aus der API
function normalizeLog(e) {
  let t =
    e.timestamp ?? e.ts ?? e.time ??
    e.created_at ?? e.createdAt ?? e.created ??
    e.occurred_at ?? e.date ??
    (e.meta && e.meta.timestamp) ?? null;

  if (t == null) return { ...e, timestamp: null };

  // Zahl-String (Sekunden oder ms, ggf. mit Dezimalen)
  if (typeof t === "string" && /^\d+(\.\d+)?$/.test(t)) {
    const n = Number(t);
    return { ...e, timestamp: n < 1e12 ? n * 1000 : n };
  }

  if (typeof t === "number") {
    return { ...e, timestamp: t < 1e12 ? t * 1000 : t };
  }

  if (typeof t === "string") {
    let s = t.trim();
    s = s.replace(" ", "T");                          // "YYYY-MM-DD HH:MM:SS" → "YYYY-MM-DDTHH:MM:SS"
    s = s.replace(/([+-]\d{2})(\d{2})$/, "$1:$2");    // +0000 → +00:00
    s = s.replace(/([+-]\d{2})$/, "$1:00");           // +00 → +00:00
    s = s.replace(/(\.\d{3})\d+/, "$1");              // Mikrosekunden auf ms kürzen
    if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(s)) s += "Z"; // naive → UTC
    return { ...e, timestamp: s };
  }

  return { ...e, timestamp: null };
}


/* -------------------------- NiceDropdown (inline) ------------------------ */

function NiceDropdown({
  value, onChange, options, placeholder = "Auswählen…",
  className = "", buttonClassName = "", menuClassName = "", minWidth = 160,
}) {
  const [open, setOpen] = useState(false);
  const btnRef = useRef(null);
  const popRef = useRef(null);
  const current = useMemo(
    () => options?.find((o) => String(o.value) === String(value)) ?? null,
    [options, value]
  );

  useEffect(() => {
    function onDoc(e) {
      if (!open) return;
      if (popRef.current?.contains(e.target)) return;
      if (btnRef.current?.contains(e.target)) return;
      setOpen(false);
    }
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  return (
    <div className={classNames("relative", className)} style={{ minWidth }}>
      <button
        type="button"
        ref={btnRef}
        onClick={() => setOpen(o => !o)}
        className={classNames(
          "w-full bg-white/10 text-gray-100 rounded-xl border border-gray-600 px-3 py-2",
          "text-left flex items-center justify-between hover:bg-gray-700",
          buttonClassName
        )}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <span className={current ? "" : "text-white/60"}>
          {current?.label ?? placeholder}
        </span>
        <span className="text-white/60">▾</span>
      </button>

      {open && (
        <div
          ref={popRef}
          className={classNames(
            "absolute z-20 mt-2 w-full rounded-xl border p-1 shadow-2xl",
            "bg-gray-900 border-gray-700",
            menuClassName
          )}
          role="listbox"
        >
          {options.map(opt => {
            const active = String(opt.value) === String(value);
            return (
              <button
                key={String(opt.value)}
                type="button"
                onClick={() => { onChange(opt.value); setOpen(false); }}
                className={classNames(
                  "w-full text-left px-3 py-2 rounded-lg transition",
                  active ? "bg-gray-700 text-white" : "text-gray-200 hover:bg-gray-800"
                )}
                role="option"
                aria-selected={active}
              >
                {opt.label}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

/* ------------------------ UserPicker (Such-Combobox) --------------------- */

function UserPicker({ value, onChange, placeholder = "Alle Nutzer" }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const btnRef = useRef(null);
  const popRef = useRef(null);

  useEffect(() => {
    let alive = true;
    if (!open) return;
    (async () => {
      setLoading(true);
      try {
        const res = await getUsersLite({ limit: 20, offset: 0, q });
        const arr = Array.isArray(res) ? res : (res.items || []);
        if (alive) setItems(arr);
      } finally {
        if (alive) setLoading(false);
      }
    })();
    return () => { alive = false; };
  }, [open, q]);

  useEffect(() => {
    function onDoc(e) {
      if (!open) return;
      if (popRef.current?.contains(e.target)) return;
      if (btnRef.current?.contains(e.target)) return;
      setOpen(false);
    }
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const selected = items.find(u => String(u.id) === String(value));

  return (
    <div className="relative" style={{ minWidth: 220 }}>
      <button
        type="button"
        ref={btnRef}
        onClick={() => setOpen(o => !o)}
        className="w-full bg-white/10- text-gray-100 rounded-xl border border-gray-600 px-3 py-2 flex items-center justify-between hover:bg-gray-700"
      >
        <span className={value ? "" : "text-white/60"}>
          {selected ? (selected.name || selected.alias || selected.email) : placeholder}
        </span>
        <span className="text-white/60">▾</span>
      </button>

      {open && (
        <div
          ref={popRef}
          className="absolute z-20 mt-2 w-[280px] rounded-xl border border-gray-700 bg-gray-900 p-2 shadow-2xl"
        >
          <input
            autoFocus
            className="w-full px-3 py-2 mb-2 rounded-lg bg-white/10 text-gray-100 border border-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-gray-400/40"
            placeholder="Suchen…"
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
          <div className="max-h-64 overflow-auto">
            {loading ? (
              <div className="px-3 py-2 text-white/60 text-sm">Laden…</div>
            ) : (
              <>
                <button
                  className="w-full text-left px-3 py-2 rounded-lg text-gray-200 hover:bg-gray-800"
                  onClick={() => { onChange(""); setOpen(false); }}
                >
                  Alle Nutzer
                </button>
                {items.map(u => (
                  <button
                    key={u.id}
                    className="w-full text-left px-3 py-2 rounded-lg text-gray-200 hover:bg-gray-800"
                    onClick={() => { onChange(u.id); setOpen(false); }}
                  >
                    {(u.name || u.alias || u.email) + (u.alias ? `  ·  ${u.alias}` : "")}
                  </button>
                ))}
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

/* --------------------------------- Page ---------------------------------- */

export default function LogsPage() {
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState(null);
  const [hasMore, setHasMore] = useState(true);

  // Filter-Params
  const [userId, setUserId] = useState("");
  const [action, setAction] = useState("");
  const [range, setRange] = useState("7d"); // 24h, 7d, 30d, all
  const [query, setQuery] = useState("");

  const [offset, setOffset] = useState(0);
  const LIMIT = 100;

  function computeRange(r) {
    if (r === "all") return {};
    const now = new Date();
    let from = new Date(now);
    if (r === "24h") from.setHours(now.getHours() - 24);
    else if (r === "7d") from.setDate(now.getDate() - 7);
    else if (r === "30d") from.setDate(now.getDate() - 30);
    return { date_from: from.toISOString(), date_to: now.toISOString() };
  }

  async function load(reset = false) {
    setLoading(true);
    setErr(null);
    try {
      const pageOffset = reset ? 0 : offset;
      const { date_from, date_to } = computeRange(range);
      const data = await getAuditLogs({
        limit: LIMIT,
        offset: pageOffset,
        user_id: userId || undefined,
        action: action || undefined,
        q: query || undefined,
        date_from,
        date_to,
      });
      const arr = (Array.isArray(data) ? data : (data.items || [])).map(normalizeLog);
      setRows((prev) => (reset ? arr : [...prev, ...arr]));
      setHasMore(arr.length === LIMIT);
      setOffset(pageOffset + arr.length);
    } catch (e) {
      setErr(e);
    } finally {
      setLoading(false);
    }
  }

  // Initial + bei Filterwechsel neu laden
  useEffect(() => {
    load(true);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userId, action, range]);

  // Clientseitige Fallback-Suche (falls Backend "q" ignoriert)
  const visible = useMemo(() => {
    if (!query) return rows;
    const q = query.toLowerCase();
    return rows.filter(r =>
      (r.user?.name || "").toLowerCase().includes(q) ||
      String(r.user_id ?? "").includes(q) ||
      String(r.action ?? "").toLowerCase().includes(q) ||
      String(r.info ?? "").toLowerCase().includes(q)
    );
  }, [rows, query]);

  return (
    <div className="rounded-2xl bg-white/5 border border-cyan-400/20 p-5">
      <h2 className="text-white/90 font-semibold mb-4">Audit-Logs</h2>

      {/* Toolbar */}
      <div className="mb-4 flex flex-wrap items-center gap-3">
        <UserPicker value={userId} onChange={setUserId} />

        <NiceDropdown
          value={action}
          onChange={setAction}
          placeholder="Alle Aktionen"
          options={[
            { value: "",            label: "Alle Aktionen" },
            { value: "login",       label: "Login" },
            { value: "logout",      label: "Logout" },
            { value: "booking",     label: "Buchung" },
            { value: "topup",       label: "Aufladung" },
            { value: "adjust",      label: "Kontokorrektur" },
            { value: "user_update", label: "User-Update" },
          ]}
        />

        <NiceDropdown
          value={range}
          onChange={setRange}
          placeholder="Zeitraum"
          options={[
            { value: "24h", label: "Letzte 24h" },
            { value: "7d",  label: "Letzte 7 Tage" },
            { value: "30d", label: "Letzte 30 Tage" },
            { value: "all", label: "Alles" },
          ]}
        />

        <input
          className="ml-auto w-full sm:w-64 px-3 py-2 rounded-xl bg-white/10 text-gray-100 border border-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-gray-400/40"
          placeholder="Suche (User, Aktion, Info)…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />

        <button
          className="px-3 py-2 rounded-xl bg-white/10 border border-gray-600 hover:bg-gray-700 text-gray-100"
          onClick={() => { setUserId(""); setAction(""); setRange("7d"); setQuery(""); load(true); }}
        >
          Zurücksetzen
        </button>
      </div>

      {/* Tabelle */}
      <div className="overflow-x-auto">
        <table className="min-w-full text-sm text-white/80">
          <thead className="text-white/60">
            <tr>
              <th className="text-left py-2 pr-4">Zeit</th>
              <th className="text-left py-2 pr-4">User</th>
              <th className="text-left py-2 pr-4">Aktion</th>
              <th className="text-left py-2 pr-4">Info</th>
              <th className="text-left py-2 pr-4">Δ&nbsp;Balance</th>
            </tr>
          </thead>
          <tbody>
            {visible.map((r) => (
              <tr key={r.id ?? `${r.timestamp}-${r.user_id}-${r.action}`} className="border-t border-white/10">
                <td className="py-2 pr-4 font-mono">
                  {fmtDT(r.timestamp ?? r.created_at ?? r.ts ?? r.time ?? r.date)}
                </td>
                <td className="py-2 pr-4">{r.user?.name ?? r.user?.alias ?? r.user_id}</td>
                <td className="py-2 pr-4 font-mono">{String(r.action ?? "-_-")}</td>
                <td className="py-2 pr-4">{r.info ?? "-_-"}</td>
                <td className="py-2 pr-4 font-mono">{euroDelta(r.new_balance_cents, r.old_balance_cents) ?? "-_-"}</td>
              </tr>
            ))}
            {loading && (
              <tr className="border-t border-white/10">
                <td className="py-3 pr-4 text-white/60" colSpan={5}>Laden…</td>
              </tr>
            )}
            {!loading && visible.length === 0 && (
              <tr className="border-t border-white/10">
                <td className="py-3 pr-4 text-white/60" colSpan={5}>Keine Einträge.</td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      <div className="mt-4 flex items-center gap-3">
        <button
          className="px-4 py-2 rounded-xl bg-white/10 border border-white/10 hover:bg-white/15 text-white/80 disabled:opacity-50"
          onClick={() => load(false)}
          disabled={loading || !hasMore}
        >
          Mehr laden
        </button>
        <div className="text-white/50 text-xs">
          {rows.length} geladen{hasMore ? " (Mehr verfügbar)" : ""}
        </div>
      </div>
    </div>
  );
}
