"use client";

import { Fragment, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useLocale, useTranslations } from "next-intl";
import { ChevronDown, Loader2 } from "lucide-react";
import { apiGet, apiGetPaged } from "@/lib/api/client";
import { useAuthStore } from "@/lib/stores/auth.store";
import { formatNumber } from "@/lib/format";
import { isoTodayTehran } from "@/lib/reports/analytics";
import { Button } from "@/components/ui/button";
import { JalaliDateField } from "@/components/ui/jalali-date-field";
import { LabeledField } from "@/components/ui/labeled-field";
import { Card, CardContent } from "@/components/ui/card";
import { EmployeeDetailsDialog } from "@/components/hr/employee-details-dialog";
import { cn } from "@/lib/utils";

const KNOWN_ROLES = ["Owner", "Manager", "Cashier", "Waiter", "Chef", "Delivery"];

type Branch = { id: string; name: string };

type AuditLogRow = {
  id: string;
  category: string;
  action: string;
  entityType?: string | null;
  entityId?: string | null;
  branchId?: string | null;
  actorId?: string | null;
  actorName?: string | null;
  actorRole?: string | null;
  summary: string;
  detailsJson?: string | null;
  createdAt: string;
};

const CATEGORIES = ["", "Payment", "Order", "Register", "Staff"] as const;
const PAGE_SIZE = 30;

function isoDaysAgoTehran(days: number): string {
  const today = isoTodayTehran();
  const d = new Date(`${today}T00:00:00Z`);
  d.setUTCDate(d.getUTCDate() - days);
  return d.toISOString().slice(0, 10);
}

export function AuditLogsTab() {
  const t = useTranslations("reports.auditLog");
  const tHr = useTranslations("hr");
  const locale = useLocale();
  const numberLocale = locale === "en" ? "en-US" : "fa-IR";
  const cafeId = useAuthStore((s) => s.user?.cafeId);

  // The actor whose details dialog is open.
  const [actor, setActor] = useState<{ id: string; name?: string | null } | null>(null);
  const roleLabel = (r: string) => (KNOWN_ROLES.includes(r) ? tHr(`roles.${r}`) : r);

  const [category, setCategory] = useState<string>("");
  const [from, setFrom] = useState<string>(() => isoDaysAgoTehran(7));
  const [to, setTo] = useState<string>(() => isoTodayTehran());
  const [branchId, setBranchId] = useState<string>("");
  const [page, setPage] = useState(1);
  const [expanded, setExpanded] = useState<string | null>(null);

  const { data: branches = [] } = useQuery({
    queryKey: ["branches", cafeId],
    queryFn: () => apiGet<Branch[]>(`/api/cafes/${cafeId}/branches`),
    enabled: !!cafeId,
  });

  const queryString = useMemo(() => {
    const params = new URLSearchParams({
      page: String(page),
      pageSize: String(PAGE_SIZE),
      // The API filters on UTC timestamps; pass the Iran-day boundaries.
      from: `${from}T00:00:00+03:30`,
      to: `${to}T23:59:59+03:30`,
    });
    if (category) params.set("category", category);
    if (branchId) params.set("branchId", branchId);
    return params.toString();
  }, [page, from, to, category, branchId]);

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ["audit-logs", cafeId, queryString],
    queryFn: () => apiGetPaged<AuditLogRow>(`/api/cafes/${cafeId}/audit-logs?${queryString}`),
    enabled: !!cafeId,
  });

  const rows = data?.items ?? [];
  const total = data?.meta.total ?? 0;
  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));

  const dateTimeFormatter = useMemo(
    () =>
      new Intl.DateTimeFormat(locale === "en" ? "en-US" : "fa-IR-u-ca-persian", {
        year: "2-digit",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        hour12: false,
      }),
    [locale]
  );

  if (!cafeId) return null;

  return (
    <div className="space-y-4">
      <Card className="rounded-xl border border-border/80 bg-card">
        <CardContent className="flex flex-wrap items-end gap-4 pt-6">
          <LabeledField label={t("category")} htmlFor="audit-cat">
            <select
              id="audit-cat"
              className="h-9 min-w-[9rem] rounded-md border border-input bg-background px-3 text-sm"
              value={category}
              onChange={(e) => {
                setCategory(e.target.value);
                setPage(1);
              }}
            >
              {CATEGORIES.map((c) => (
                <option key={c} value={c}>
                  {c === "" ? t("allCategories") : t(`categories.${c}`)}
                </option>
              ))}
            </select>
          </LabeledField>
          <LabeledField label={t("fromDate")} htmlFor="audit-from">
            <JalaliDateField
              id="audit-from"
              className="w-40"
              value={from}
              onChange={(iso) => {
                setFrom(iso);
                setPage(1);
              }}
            />
          </LabeledField>
          <LabeledField label={t("toDate")} htmlFor="audit-to">
            <JalaliDateField
              id="audit-to"
              className="w-40"
              value={to}
              onChange={(iso) => {
                setTo(iso);
                setPage(1);
              }}
            />
          </LabeledField>
          {branches.length > 1 ? (
            <LabeledField label={t("branch")} htmlFor="audit-branch">
              <select
                id="audit-branch"
                className="h-9 min-w-[10rem] rounded-md border border-input bg-background px-3 text-sm"
                value={branchId}
                onChange={(e) => {
                  setBranchId(e.target.value);
                  setPage(1);
                }}
              >
                <option value="">{t("allBranches")}</option>
                {branches.map((b) => (
                  <option key={b.id} value={b.id}>
                    {b.name}
                  </option>
                ))}
              </select>
            </LabeledField>
          ) : null}
        </CardContent>
      </Card>

      <Card className="rounded-xl border border-border/80 bg-card">
        <CardContent className="overflow-x-auto pt-6">
          {isLoading ? (
            <div className="flex items-center justify-center py-10 text-muted-foreground">
              <Loader2 className="size-5 animate-spin" />
            </div>
          ) : isError ? (
            <div className="flex flex-col items-center gap-3 py-8 text-center text-sm text-muted-foreground">
              <p>{t("loadFailed")}</p>
              <Button variant="outline" size="sm" onClick={() => refetch()}>
                {t("retry")}
              </Button>
            </div>
          ) : rows.length === 0 ? (
            <p className="py-8 text-center text-sm text-muted-foreground">{t("empty")}</p>
          ) : (
            <table className="w-full min-w-[42rem] text-sm">
              <thead>
                <tr className="border-b text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
                  <th className="py-2 text-start">{t("colTime")}</th>
                  <th className="py-2 text-start">{t("colCategory")}</th>
                  <th className="py-2 text-start">{t("colActor")}</th>
                  <th className="py-2 text-start">{t("colSummary")}</th>
                  <th className="py-2 text-end" />
                </tr>
              </thead>
              <tbody>
                {rows.map((row) => {
                  const isOpen = expanded === row.id;
                  let details: Record<string, unknown> | null = null;
                  if (isOpen && row.detailsJson) {
                    try {
                      details = JSON.parse(row.detailsJson) as Record<string, unknown>;
                    } catch {
                      details = null;
                    }
                  }
                  return (
                    <Fragment key={row.id}>
                      <tr className="border-b border-border/50">
                        <td className="whitespace-nowrap py-2.5 tabular-nums text-muted-foreground">
                          {dateTimeFormatter.format(new Date(row.createdAt))}
                        </td>
                        <td className="py-2.5">
                          <span className="rounded-full bg-muted px-2 py-0.5 text-xs font-medium">
                            {(CATEGORIES as readonly string[]).includes(row.category)
                              ? t(`categories.${row.category}`)
                              : row.category}
                          </span>
                        </td>
                        <td className="py-2.5">
                          {row.actorId ? (
                            <button
                              type="button"
                              onClick={() =>
                                setActor({ id: row.actorId!, name: row.actorName })
                              }
                              className="text-start font-medium text-[#0F6E56] hover:underline"
                            >
                              {row.actorName ?? t("unknownActor")}
                            </button>
                          ) : (
                            <span>{t("systemActor")}</span>
                          )}
                          {row.actorRole ? (
                            <span className="ms-1.5 text-xs text-muted-foreground">
                              ({roleLabel(row.actorRole)})
                            </span>
                          ) : null}
                        </td>
                        <td className="max-w-[22rem] py-2.5">
                          <span className="line-clamp-2">{row.summary}</span>
                        </td>
                        <td className="py-2.5 text-end">
                          {row.detailsJson ? (
                            <button
                              type="button"
                              onClick={() => setExpanded(isOpen ? null : row.id)}
                              className="inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground"
                              aria-expanded={isOpen}
                            >
                              {t("details")}
                              <ChevronDown
                                className={cn(
                                  "size-3.5 transition-transform",
                                  isOpen && "rotate-180"
                                )}
                              />
                            </button>
                          ) : null}
                        </td>
                      </tr>
                      {isOpen && details ? (
                        <tr className="border-b border-border/50 bg-muted/40">
                          <td colSpan={5} className="px-3 py-3">
                            <dl className="grid gap-x-6 gap-y-1.5 text-xs sm:grid-cols-2">
                              {Object.entries(details).map(([key, value]) => (
                                <div key={key} className="flex gap-2">
                                  <dt className="shrink-0 font-medium text-muted-foreground">
                                    {key}:
                                  </dt>
                                  <dd
                                    className="min-w-0 break-all tabular-nums"
                                    dir="ltr"
                                  >
                                    {typeof value === "object"
                                      ? JSON.stringify(value)
                                      : String(value)}
                                  </dd>
                                </div>
                              ))}
                            </dl>
                          </td>
                        </tr>
                      ) : null}
                    </Fragment>
                  );
                })}
              </tbody>
            </table>
          )}

          {totalPages > 1 ? (
            <div className="flex items-center justify-center gap-3 pt-4">
              <Button
                variant="outline"
                size="sm"
                disabled={page <= 1}
                onClick={() => setPage((p) => p - 1)}
              >
                {t("prevPage")}
              </Button>
              <span className="text-xs tabular-nums text-muted-foreground">
                {formatNumber(page, numberLocale)} / {formatNumber(totalPages, numberLocale)}
              </span>
              <Button
                variant="outline"
                size="sm"
                disabled={page >= totalPages}
                onClick={() => setPage((p) => p + 1)}
              >
                {t("nextPage")}
              </Button>
            </div>
          ) : null}
        </CardContent>
      </Card>

      <EmployeeDetailsDialog
        cafeId={cafeId}
        employeeId={actor?.id ?? null}
        fallbackName={actor?.name}
        onClose={() => setActor(null)}
      />
    </div>
  );
}
