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

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 {
  switch (status.toLowerCase()) {
    case "success":
    case "ok":
      return "success";
    case "failure":
    case "error":
    case "blocked":
      return "destructive";
    case "pending":
    case "warning":
      return "warning";
    default:
      return "default";
  }
}

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={cx(commonTableViewportClass, "flex-1")}>
        <div className={commonTableWrapperClass}>
          <Table className={commonTableClass}>
            <TableHeader className={commonTableHeaderClass}>
              <TableRow
                className={cx(
                  commonTableRowClass,
                  commonStickyTableHeaderClass,
                )}
              >
                <TableHead className={cx(commonTableHeadClass, "w-[190px]")}>
                  {t("ui.common.audit.table.time", "Time")}
                </TableHead>
                <TableHead className={cx(commonTableHeadClass, "w-[180px]")}>
                  {t("ui.common.audit.table.user_id", "User ID")}
                </TableHead>
                <TableHead className={cx(commonTableHeadClass, "w-[180px]")}>
                  {t("ui.common.audit.table.action", "Action")}
                </TableHead>
                <TableHead className={cx(commonTableHeadClass, "w-[260px]")}>
                  {t("ui.common.audit.table.client_id", "Client ID")}
                </TableHead>
                <TableHead className={cx(commonTableHeadClass, "w-[120px]")}>
                  {t("ui.common.audit.table.status", "Status")}
                </TableHead>
                <TableHead className={cx(commonTableHeadClass, "w-[80px]")} />
              </TableRow>
            </TableHeader>
            <TableBody className={commonTableBodyClass}>
              {logs.map((log, index) => {
                const details = parseAuditDetails(log.details);
                const actorLabel = resolveAuditActor(log, details);
                const actionLabel = resolveAuditAction(log, details);
                const targetLabel = resolveAuditTarget(details);
                const rowKey = `${log.event_id}-${log.timestamp}-${index}`;
                const expanded = Boolean(expandedRows[rowKey]);
                const { date, time } = formatAuditDateParts(log.timestamp);

                return (
                  <React.Fragment key={rowKey}>
                    <TableRow className={cx(commonTableRowClass, "bg-card/40")}>
                      <TableCell
                        className={cx(
                          commonTableCellClass,
                          "text-xs text-muted-foreground",
                        )}
                      >
                        <div className="space-y-1">
                          <div>{date}</div>
                          <div>{time}</div>
                        </div>
                      </TableCell>
                      <TableCell 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>
                      </TableCell>
                      <TableCell
                        className={cx(
                          commonTableCellClass,
                          "text-xs text-muted-foreground",
                        )}
                      >
                        <div className="font-semibold text-foreground">
                          {actionLabel}
                        </div>
                      </TableCell>
                      <TableCell
                        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>
                      </TableCell>
                      <TableCell className={commonTableCellClass}>
                        <span
                          className={getCommonBadgeClasses({
                            variant: statusVariant(log.status),
                          })}
                        >
                          {log.status}
                        </span>
                      </TableCell>
                      <TableCell
                        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>
                      </TableCell>
                    </TableRow>
                    {expanded && (
                      <TableRow
                        className={cx(commonTableRowClass, "bg-card/20")}
                      >
                        <TableCell
                          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(log.event_id) },
                                )}
                              </div>
                              <div>
                                {t(
                                  "ui.common.audit.details.ip",
                                  "IP · {{value}}",
                                  {
                                    value: formatAuditValue(log.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(log.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>
                        </TableCell>
                      </TableRow>
                    )}
                  </React.Fragment>
                );
              })}
              {logs.length === 0 && !loading && (
                <TableRow className={commonTableRowClass}>
                  <TableCell
                    colSpan={6}
                    className={cx(
                      commonTableCellClass,
                      "text-center text-muted-foreground py-8",
                    )}
                  >
                    {t("msg.common.audit.empty", "No audit logs found.")}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </div>
      <div className="p-4 border-t text-center flex-shrink-0 bg-background/50 backdrop-blur-sm z-10">
        {hasNextPage ? (
          <div className="flex flex-col items-center gap-2">
            {isFetchingNextPage && (
              <span className="text-xs text-muted-foreground animate-pulse">
                {t("msg.common.loading", "Loading more...")}
              </span>
            )}
            <button
              type="button"
              className={getCommonButtonClasses({
                variant: "outline",
                size: "sm",
              })}
              onClick={onLoadMore}
              disabled={isFetchingNextPage}
            >
              {isFetchingNextPage
                ? t("msg.common.loading", "Loading...")
                : t("ui.common.audit.load_more", "Load more")}
            </button>
          </div>
        ) : logs.length > 0 ? (
          <span className="text-xs text-muted-foreground">
            {t("msg.common.audit.end", "End of audit feed")}
          </span>
        ) : null}
      </div>
    </div>
  );
}

// Internal table components for cleaner implementation
function Table({
  className,
  children,
  style,
}: {
  className?: string;
  children: React.ReactNode;
  style?: React.CSSProperties;
}) {
  return (
    <table className={className} style={style}>
      {children}
    </table>
  );
}

function TableHeader({
  className,
  children,
}: {
  className?: string;
  children: React.ReactNode;
}) {
  return <thead className={className}>{children}</thead>;
}

function TableBody({
  className,
  children,
}: {
  className?: string;
  children: React.ReactNode;
}) {
  return <tbody className={className}>{children}</tbody>;
}

function TableRow({
  className,
  children,
}: {
  className?: string;
  children: React.ReactNode;
}) {
  return <tr className={className}>{children}</tr>;
}

function TableHead({
  className,
  children,
}: {
  className?: string;
  children?: React.ReactNode;
}) {
  return <th className={className}>{children}</th>;
}

function TableCell({
  className,
  children,
  colSpan,
}: {
  className?: string;
  children: React.ReactNode;
  colSpan?: number;
}) {
  return (
    <td className={className} colSpan={colSpan}>
      {children}
    </td>
  );
}
