import { ChevronDown, ChevronUp, Copy } from "lucide-react";
import * as React from "react";
import type { CommonAuditLog } from "../../audit";
import {
  formatAuditDateParts,
  formatAuditValue,
  parseAuditDetails,
  resolveAuditAction,
  resolveAuditActor,
  resolveAuditTarget,
} from "../../audit";
import {
  getCommonBadgeClasses,
  type CommonBadgeVariant,
} from "../../../ui/badge";
import { getCommonButtonClasses } from "../../../ui/button";
import {
  commonStickyTableHeaderClass,
  commonTableBodyClass,
  commonTableCellClass,
  commonTableClass,
  commonTableHeadClass,
  commonTableHeaderClass,
  commonTableRowClass,
  commonTableShellClass,
  commonTableViewportClass,
  commonTableWrapperClass,
} from "../../../ui/table";

type AuditTranslate = (
  key: string,
  fallback: string,
  vars?: Record<string, string | number>,
) => string;

type AuditLogTableProps = {
  logs: CommonAuditLog[];
  t: AuditTranslate;
  loading: boolean;
  hasNextPage: boolean;
  isFetchingNextPage: boolean;
  onLoadMore: () => void;
  className?: string;
};

function cx(...classNames: Array<string | false | null | undefined>) {
  return classNames.filter(Boolean).join(" ");
}

function statusVariant(status: string): CommonBadgeVariant {
  return status === "success" || status === "ok" ? "success" : "warning";
}

export function AuditLogTable({
  logs,
  t,
  loading,
  hasNextPage,
  isFetchingNextPage,
  onLoadMore,
  className,
}: AuditLogTableProps) {
  const [expandedRows, setExpandedRows] = React.useState<
    Record<string, boolean>
  >({});

  const handleCopy = (value: string) => {
    if (!value) {
      return;
    }
    navigator.clipboard.writeText(value);
  };

  return (
    <div className={cx(commonTableShellClass, className)}>
      <div className={commonTableViewportClass}>
        <div className={commonTableWrapperClass}>
          <table className={cx(commonTableClass, "table-fixed")}>
            <thead
              className={cx(commonTableHeaderClass, commonStickyTableHeaderClass)}
            >
              <tr className={commonTableRowClass}>
                <th className={cx(commonTableHeadClass, "w-[190px]")}>
                  {t("ui.common.audit.table.time", "Time")}
                </th>
                <th className={cx(commonTableHeadClass, "w-[180px]")}>
                  {t("ui.common.audit.table.user_id", "User ID")}
                </th>
                <th className={cx(commonTableHeadClass, "w-[180px]")}>
                  {t("ui.common.audit.table.action", "Action")}
                </th>
                <th className={cx(commonTableHeadClass, "w-[260px]")}>
                  {t("ui.common.audit.table.client_id", "Client ID")}
                </th>
                <th className={cx(commonTableHeadClass, "w-[120px]")}>
                  {t("ui.common.audit.table.status", "Status")}
                </th>
                <th className={cx(commonTableHeadClass, "w-[80px]")} />
              </tr>
            </thead>
            <tbody className={commonTableBodyClass}>
              {loading && logs.length === 0 ? (
                <tr className={commonTableRowClass}>
                  <td
                    colSpan={6}
                    className={cx(
                      commonTableCellClass,
                      "py-8 text-center text-muted-foreground",
                    )}
                  >
                    {t("msg.common.audit.loading", "Loading audit logs...")}
                  </td>
                </tr>
              ) : logs.length === 0 ? (
                <tr className={commonTableRowClass}>
                  <td
                    colSpan={6}
                    className={cx(commonTableCellClass, "text-center text-muted-foreground")}
                  >
                    {t("msg.common.audit.empty", "No audit logs found.")}
                  </td>
                </tr>
              ) : (
                logs.map((row, index) => {
                  const details = parseAuditDetails(row.details);
                  const actorLabel = resolveAuditActor(row, details);
                  const actionLabel = resolveAuditAction(row, details);
                  const targetLabel = resolveAuditTarget(details);
                  const rowKey = `${row.event_id}-${row.timestamp}-${index}`;
                  const expanded = Boolean(expandedRows[rowKey]);
                  const { date, time } = formatAuditDateParts(row.timestamp);
                  return (
                    <React.Fragment key={rowKey}>
                      <tr className={cx(commonTableRowClass, "bg-card/40")}>
                        <td className={cx(commonTableCellClass, "text-xs text-muted-foreground")}>
                          <div className="space-y-1">
                            <div>{date}</div>
                            <div>{time}</div>
                          </div>
                        </td>
                        <td className={commonTableCellClass}>
                          <div className="flex items-center gap-2">
                            <code className="rounded-md bg-secondary/60 px-2 py-1 text-xs text-muted-foreground">
                              {actorLabel}
                            </code>
                            {actorLabel !== "-" ? (
                              <button
                                type="button"
                                className={cx(
                                  getCommonButtonClasses({
                                    variant: "ghost",
                                    size: "icon",
                                  }),
                                  "h-7 w-7 text-muted-foreground hover:text-primary",
                                )}
                                aria-label={t(
                                  "ui.common.audit.copy.actor_id",
                                  "Copy User ID",
                                )}
                                onClick={() => handleCopy(actorLabel)}
                              >
                                <Copy className="h-3 w-3" />
                              </button>
                            ) : null}
                          </div>
                        </td>
                        <td
                          className={cx(commonTableCellClass, "text-xs text-muted-foreground")}
                        >
                          <div className="font-semibold text-foreground">
                            {actionLabel}
                          </div>
                        </td>
                        <td
                          className={cx(commonTableCellClass, "text-xs text-muted-foreground")}
                        >
                          <div className="flex items-center gap-2">
                            <span className="break-all">{targetLabel}</span>
                            {targetLabel !== "-" ? (
                              <button
                                type="button"
                                className={cx(
                                  getCommonButtonClasses({
                                    variant: "ghost",
                                    size: "icon",
                                  }),
                                  "h-7 w-7 text-muted-foreground hover:text-primary",
                                )}
                                aria-label={t(
                                  "ui.common.audit.copy.target",
                                  "Copy Client ID",
                                )}
                                onClick={() => handleCopy(targetLabel)}
                              >
                                <Copy className="h-3 w-3" />
                              </button>
                            ) : null}
                          </div>
                        </td>
                        <td className={commonTableCellClass}>
                          <span
                            className={getCommonBadgeClasses({
                              variant: statusVariant(row.status),
                            })}
                          >
                            {row.status}
                          </span>
                        </td>
                        <td className={cx(commonTableCellClass, "text-right")}>
                          <button
                            type="button"
                            className={getCommonButtonClasses({
                              variant: "ghost",
                              size: "sm",
                            })}
                            onClick={() =>
                              setExpandedRows((prev) => ({
                                ...prev,
                                [rowKey]: !expanded,
                              }))
                            }
                          >
                            {expanded ? (
                              <ChevronUp className="h-4 w-4" />
                            ) : (
                              <ChevronDown className="h-4 w-4" />
                            )}
                          </button>
                        </td>
                      </tr>
                      {expanded ? (
                        <tr className={cx(commonTableRowClass, "bg-card/20")}>
                          <td colSpan={6} className={cx(commonTableCellClass, "text-xs")}>
                            <div className="grid gap-4 text-muted-foreground md:grid-cols-3">
                              <div className="space-y-1">
                                <div className="uppercase tracking-[0.16em]">
                                  {t("ui.common.audit.details.request", "Request")}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.request_id",
                                    "Request ID · {{value}}",
                                    {
                                      value: formatAuditValue(details.request_id),
                                    },
                                  )}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.event_id",
                                    "Event ID · {{value}}",
                                    {
                                      value: formatAuditValue(row.event_id),
                                    },
                                  )}
                                </div>
                                <div>
                                  {t("ui.common.audit.details.ip", "IP · {{value}}", {
                                    value: formatAuditValue(row.ip_address),
                                  })}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.method",
                                    "Method · {{value}}",
                                    {
                                      value: formatAuditValue(details.method),
                                    },
                                  )}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.path",
                                    "Path · {{value}}",
                                    {
                                      value: formatAuditValue(details.path),
                                    },
                                  )}
                                </div>
                                <div>
                                  {t(
                                    "ui.common.audit.details.latency",
                                    "Latency · {{value}}",
                                    {
                                      value:
                                        details.latency_ms !== undefined
                                          ? `${details.latency_ms}ms`
                                          : "-",
                                    },
                                  )}
                                </div>
                              </div>
                              <div className="space-y-1">
                                <div className="uppercase tracking-[0.16em]">
                                  {t("ui.common.audit.details.actor", "Actor")}
                                </div>
                                <div>
                                  {t(
                                    "ui.common.audit.details.actor_id",
                                    "User ID · {{value}}",
                                    { value: actorLabel },
                                  )}
                                </div>
                                <div>
                                  {t(
                                    "ui.common.audit.details.tenant",
                                    "Tenant · {{value}}",
                                    {
                                      value: formatAuditValue(details.tenant_id),
                                    },
                                  )}
                                </div>
                                <div>
                                  {t(
                                    "ui.common.audit.details.device",
                                    "Device · {{value}}",
                                    {
                                      value: formatAuditValue(row.device_id),
                                    },
                                  )}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.target",
                                    "Client ID · {{value}}",
                                    { value: targetLabel },
                                  )}
                                </div>
                              </div>
                              <div className="space-y-1">
                                <div className="uppercase tracking-[0.16em]">
                                  {t("ui.common.audit.details.result", "Result")}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.error",
                                    "Error · {{value}}",
                                    {
                                      value: formatAuditValue(details.error),
                                    },
                                  )}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.before",
                                    "Before · {{value}}",
                                    {
                                      value: formatAuditValue(details.before),
                                    },
                                  )}
                                </div>
                                <div className="break-all">
                                  {t(
                                    "ui.common.audit.details.after",
                                    "After · {{value}}",
                                    {
                                      value: formatAuditValue(details.after),
                                    },
                                  )}
                                </div>
                              </div>
                            </div>
                          </td>
                        </tr>
                      ) : null}
                    </React.Fragment>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>
      <div className="pt-6 text-center flex-shrink-0">
        {hasNextPage ? (
          <button
            type="button"
            className={getCommonButtonClasses({ variant: "outline" })}
            onClick={onLoadMore}
            disabled={isFetchingNextPage}
          >
            {isFetchingNextPage
              ? t("msg.common.loading", "Loading...")
              : t("ui.common.audit.load_more", "Load more")}
          </button>
        ) : (
          <span className="text-xs text-muted-foreground">
            {t("msg.common.audit.end", "End of audit feed")}
          </span>
        )}
      </div>
    </div>
  );
}
