import { useInfiniteQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
  ChevronDown,
  ChevronUp,
  Copy,
  ListChecks,
  RefreshCw,
  Search,
  Terminal,
} from "lucide-react";
import * as React from "react";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "../../components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../../components/ui/table";
import type { AuditLog } from "../../lib/adminApi";
import { fetchAuditLogs } from "../../lib/adminApi";
import { t } from "../../lib/i18n";

const defaultAuditFilters = [
  "method:POST path:/api/v1/*",
  "status:failure",
  "latency_ms:>1000",
];

type AuditDetails = {
  request_id?: string;
  method?: string;
  path?: string;
  status?: number;
  latency_ms?: number;
  error?: string;
  tenant_id?: string;
  actor_id?: string;
  action?: string;
  target?: string;
  before?: unknown;
  after?: unknown;
};

function parseDetails(details?: string): AuditDetails {
  if (!details) {
    return {};
  }
  try {
    const parsed = JSON.parse(details);
    if (parsed && typeof parsed === "object") {
      return parsed as AuditDetails;
    }
  } catch {}
  return {};
}

function formatCellValue(value: unknown) {
  if (value === null || value === undefined || value === "") {
    return "-";
  }
  if (typeof value === "string") {
    return value;
  }
  try {
    return JSON.stringify(value);
  } catch {
    return String(value);
  }
}

function formatIsoDateTime(value: string) {
  if (!value) {
    return { date: "-", time: "-" };
  }
  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    return { date: value, time: "-" };
  }
  const date = parsed.toISOString().slice(0, 10);
  const time = parsed.toLocaleTimeString("ko-KR", { hour12: false });
  return { date, time };
}

function AuditLogsPage() {
  const [filters, setFilters] = React.useState(defaultAuditFilters);
  const [filterDraft, setFilterDraft] = React.useState("");
  const [expandedRows, setExpandedRows] = React.useState<
    Record<string, boolean>
  >({});

  const handleCopy = (value: string) => {
    if (!value) {
      return;
    }
    navigator.clipboard.writeText(value);
  };
  const {
    data,
    isLoading,
    error,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isFetching,
    refetch,
  } = useInfiniteQuery({
    queryKey: ["audit-logs"],
    queryFn: ({ pageParam }) => fetchAuditLogs(50, pageParam),
    initialPageParam: undefined as string | undefined,
    getNextPageParam: (lastPage) => lastPage.next_cursor || undefined,
  });

  const logs =
    data?.pages?.flatMap(
      (page) =>
        page?.items?.filter((item): item is AuditLog => Boolean(item)) ?? [],
    ) ?? [];

  const handleAddFilter = () => {
    const trimmed = filterDraft.trim();
    if (!trimmed) {
      return;
    }
    setFilters((prev) => (prev.includes(trimmed) ? prev : [...prev, trimmed]));
    setFilterDraft("");
  };

  if (isLoading) {
    return (
      <div className="p-8 text-center">
        {t("msg.admin.audit.loading", "Loading audit logs...")}
      </div>
    );
  }

  if (error) {
    const errMsg =
      (error as AxiosError<{ error?: string }>).response?.data?.error ??
      (error as Error).message;
    return (
      <div className="p-8 text-center text-red-500">
        {t("msg.admin.audit.load_error", "Error loading logs: {{error}}", {
          error: errMsg,
        })}
      </div>
    );
  }

  return (
    <div className="space-y-6 flex flex-col h-[calc(100vh-theme(spacing.32))]">
      <header className="flex flex-wrap items-start justify-between gap-4 flex-shrink-0 sticky top-[-2.5rem] z-20 bg-background/95 backdrop-blur pt-4 pb-2 -mt-4">
        <div>
          <h2 className="text-3xl font-semibold">
            {t("ui.admin.audit.title", "감사 로그")}
          </h2>
          <p className="text-sm text-[var(--color-muted)]">
            {t(
              "msg.admin.audit.subtitle",
              "Command 요청 기반 ClickHouse 로그를 조회합니다. 사용자/테넌트는 추후 세션 연동 시 자동 채워집니다.",
            )}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            onClick={() => refetch()}
            disabled={isFetching}
          >
            <RefreshCw size={16} />
            {t("ui.common.refresh", "새로고침")}
          </Button>
          <Button>
            <ListChecks size={16} />
            {t("ui.admin.audit.export_csv", "Export CSV")}
          </Button>
        </div>
      </header>

      <Card className="glass-panel flex-1 flex flex-col min-h-0 overflow-hidden">
        <CardHeader className="flex flex-row items-center justify-between flex-shrink-0">
          <div>
            <CardTitle>
              {t("ui.admin.audit.registry.title", "Log Registry")}
            </CardTitle>
            <CardDescription>
              {t("msg.admin.audit.registry.count", "총 {{count}}개 로그", {
                count: logs.length,
              })}
            </CardDescription>
          </div>
        </CardHeader>
        <CardContent className="flex-1 flex flex-col min-h-0 pt-0">
          <div className="mb-4 flex flex-wrap items-center gap-2 flex-shrink-0">
            <div className="flex flex-1 items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.02)] px-4 py-2 text-[var(--color-muted)]">
              <Search size={14} />
              <input
                value={filterDraft}
                onChange={(event) => setFilterDraft(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === "Enter") {
                    handleAddFilter();
                  }
                }}
                placeholder={t(
                  "ui.admin.audit.filters.placeholder",
                  "필터 추가 (예: status:failure)",
                )}
                className="w-full bg-transparent text-sm text-foreground outline-none"
              />
              <Button size="sm" variant="outline" onClick={handleAddFilter}>
                {t("ui.common.add", "추가")}
              </Button>
            </div>
            {filters.length === 0 ? (
              <span className="text-xs text-[var(--color-muted)]">
                {t("msg.admin.audit.filters.empty", "필터 없음")}
              </span>
            ) : (
              filters.map((filter) => (
                <span
                  key={filter}
                  className="inline-flex items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.04)] px-3 py-1 text-xs text-[var(--color-muted)]"
                >
                  <Terminal size={12} />
                  {filter}
                  <button
                    type="button"
                    onClick={() =>
                      setFilters((prev) =>
                        prev.filter((item) => item !== filter),
                      )
                    }
                    className="inline-flex h-5 w-5 items-center justify-center rounded-full border border-[var(--color-border)] text-[10px] text-[var(--color-muted)]"
                    aria-label={t(
                      "ui.admin.audit.filters.remove",
                      "{{filter}} 필터 제거",
                      { filter },
                    )}
                  >
                    ×
                  </button>
                </span>
              ))
            )}
          </div>
          <div className="flex-1 rounded-md border overflow-hidden flex flex-col">
            <div className="flex-1 overflow-auto relative custom-scrollbar">
              <Table className="table-fixed">
                <TableHeader className="sticky top-0 z-10 bg-secondary shadow-sm">
                  <TableRow>
                    <TableHead className="w-[140px]">
                      {t("ui.admin.audit.table.time", "TIME")}
                    </TableHead>
                    <TableHead className="w-[160px]">
                      {t("ui.admin.audit.table.actor", "ACTOR (ID)")}
                    </TableHead>
                    <TableHead>
                      {t("ui.admin.audit.table.request", "REQUEST")}
                    </TableHead>
                    <TableHead>
                      {t("ui.admin.audit.table.path", "PATH")}
                    </TableHead>
                    <TableHead className="w-[120px]">
                      {t("ui.admin.audit.table.status", "STATUS")}
                    </TableHead>
                    <TableHead>
                      {t(
                        "ui.admin.audit.table.action_target",
                        "Action / Target",
                      )}
                    </TableHead>
                    <TableHead className="w-[80px]" />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {isLoading && (
                    <TableRow>
                      <TableCell colSpan={7}>
                        {t("msg.common.loading", "로딩 중...")}
                      </TableCell>
                    </TableRow>
                  )}
                  {!isLoading && logs.length === 0 && (
                    <TableRow>
                      <TableCell colSpan={7}>
                        {t(
                          "msg.admin.audit.empty",
                          "아직 수집된 감사 로그가 없습니다.",
                        )}
                      </TableCell>
                    </TableRow>
                  )}
                  {logs.map((row, index) => {
                    const details = parseDetails(row.details);
                    const actionLabel =
                      details.action ||
                      (details.method && details.path
                        ? `${details.method} ${details.path}`
                        : row.event_type);
                    const rowKey = `${row.event_id}-${row.timestamp}-${index}`;
                    const isExpanded = Boolean(expandedRows[rowKey]);
                    return (
                      <React.Fragment key={rowKey}>
                        <TableRow className="bg-card/40">
                          <TableCell className="text-xs text-[var(--color-muted)]">
                            {(() => {
                              const { date, time } = formatIsoDateTime(
                                row.timestamp,
                              );
                              return (
                                <div className="space-y-1">
                                  <div>{date}</div>
                                  <div>{time}</div>
                                </div>
                              );
                            })()}
                          </TableCell>
                          <TableCell>
                            <div className="flex items-center gap-2">
                              <code className="rounded-md bg-secondary/60 px-2 py-1 text-xs text-muted-foreground">
                                {row.user_id || details.actor_id || "-"}
                              </code>
                              {(row.user_id || details.actor_id) && (
                                <Button
                                  variant="ghost"
                                  size="icon"
                                  className="h-7 w-7 text-muted-foreground hover:text-primary"
                                  aria-label={t(
                                    "ui.admin.audit.copy.actor_id",
                                    "Copy actor id",
                                  )}
                                  onClick={() =>
                                    handleCopy(
                                      row.user_id || details.actor_id || "",
                                    )
                                  }
                                >
                                  <Copy className="h-3 w-3" />
                                </Button>
                              )}
                            </div>
                          </TableCell>
                          <TableCell className="text-xs text-[var(--color-muted)]">
                            <div className="flex items-start gap-2">
                              <span className="break-all">
                                {formatCellValue(details.request_id)}
                              </span>
                              {details.request_id && (
                                <Button
                                  variant="ghost"
                                  size="icon"
                                  className="h-7 w-7 text-muted-foreground hover:text-primary"
                                  aria-label={t(
                                    "ui.admin.audit.copy.request_id",
                                    "Copy request id",
                                  )}
                                  onClick={() =>
                                    handleCopy(details.request_id || "")
                                  }
                                >
                                  <Copy className="h-3 w-3" />
                                </Button>
                              )}
                            </div>
                          </TableCell>
                          <TableCell className="text-xs text-[var(--color-muted)]">
                            <div className="font-semibold text-foreground">
                              {formatCellValue(details.method)}
                            </div>
                            <div className="break-all">
                              {formatCellValue(details.path)}
                            </div>
                          </TableCell>
                          <TableCell>
                            <Badge
                              variant={
                                row.status === "success" || row.status === "ok"
                                  ? "success"
                                  : "warning"
                              }
                            >
                              {row.status}
                            </Badge>
                          </TableCell>
                          <TableCell className="text-xs text-[var(--color-muted)]">
                            <div className="font-semibold text-foreground">
                              {actionLabel}
                            </div>
                            {details.target && (
                              <div className="flex items-center gap-2">
                                <span className="break-all">
                                  {t(
                                    "ui.admin.audit.target",
                                    "Target · {{target}}",
                                    {
                                      target: details.target,
                                    },
                                  )}
                                </span>
                                <Button
                                  variant="ghost"
                                  size="icon"
                                  className="h-7 w-7 text-muted-foreground hover:text-primary"
                                  aria-label={t(
                                    "ui.admin.audit.copy.target",
                                    "Copy target",
                                  )}
                                  onClick={() =>
                                    handleCopy(details.target || "")
                                  }
                                >
                                  <Copy className="h-3 w-3" />
                                </Button>
                              </div>
                            )}
                          </TableCell>
                          <TableCell className="text-right">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() =>
                                setExpandedRows((prev) => ({
                                  ...prev,
                                  [rowKey]: !isExpanded,
                                }))
                              }
                            >
                              {isExpanded ? (
                                <ChevronUp className="h-4 w-4" />
                              ) : (
                                <ChevronDown className="h-4 w-4" />
                              )}
                            </Button>
                          </TableCell>
                        </TableRow>
                        {isExpanded && (
                          <TableRow className="bg-card/20">
                            <TableCell colSpan={7} className="text-xs">
                              <div className="grid gap-4 text-[var(--color-muted)] md:grid-cols-3">
                                <div className="space-y-1">
                                  <div className="uppercase tracking-[0.16em]">
                                    {t(
                                      "ui.admin.audit.details.request",
                                      "Request",
                                    )}
                                  </div>
                                  <div className="break-all">
                                    {t(
                                      "ui.admin.audit.details.request_id",
                                      "Request ID · {{value}}",
                                      {
                                        value: formatCellValue(
                                          details.request_id,
                                        ),
                                      },
                                    )}
                                  </div>
                                  <div className="break-all">
                                    {t(
                                      "ui.admin.audit.details.event_id",
                                      "Event ID · {{value}}",
                                      {
                                        value: formatCellValue(row.event_id),
                                      },
                                    )}
                                  </div>
                                  <div>
                                    {t(
                                      "ui.admin.audit.details.ip",
                                      "IP · {{value}}",
                                      {
                                        value: formatCellValue(row.ip_address),
                                      },
                                    )}
                                  </div>
                                  <div>
                                    {t(
                                      "ui.admin.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.admin.audit.details.actor", "Actor")}
                                  </div>
                                  <div>
                                    {t(
                                      "ui.admin.audit.details.actor_id",
                                      "Actor ID · {{value}}",
                                      {
                                        value:
                                          row.user_id ||
                                          details.actor_id ||
                                          "-",
                                      },
                                    )}
                                  </div>
                                  <div>
                                    {t(
                                      "ui.admin.audit.details.tenant",
                                      "Tenant · {{value}}",
                                      {
                                        value: formatCellValue(
                                          details.tenant_id,
                                        ),
                                      },
                                    )}
                                  </div>
                                  <div>
                                    {t(
                                      "ui.admin.audit.details.device",
                                      "Device · {{value}}",
                                      {
                                        value: formatCellValue(row.device_id),
                                      },
                                    )}
                                  </div>
                                </div>
                                <div className="space-y-1">
                                  <div className="uppercase tracking-[0.16em]">
                                    {t(
                                      "ui.admin.audit.details.result",
                                      "Result",
                                    )}
                                  </div>
                                  <div className="break-all">
                                    {t(
                                      "ui.admin.audit.details.error",
                                      "Error · {{value}}",
                                      {
                                        value: formatCellValue(details.error),
                                      },
                                    )}
                                  </div>
                                  <div className="break-all">
                                    {t(
                                      "ui.admin.audit.details.before",
                                      "Before · {{value}}",
                                      {
                                        value: formatCellValue(details.before),
                                      },
                                    )}
                                  </div>
                                  <div className="break-all">
                                    {t(
                                      "ui.admin.audit.details.after",
                                      "After · {{value}}",
                                      {
                                        value: formatCellValue(details.after),
                                      },
                                    )}
                                  </div>
                                </div>
                              </div>
                            </TableCell>
                          </TableRow>
                        )}
                      </React.Fragment>
                    );
                  })}
                </TableBody>
              </Table>
            </div>
          </div>
          <div className="pt-4 text-center flex-shrink-0">
            {hasNextPage ? (
              <Button
                variant="outline"
                onClick={() => fetchNextPage()}
                disabled={isFetchingNextPage}
              >
                {isFetchingNextPage
                  ? t("msg.common.loading", "Loading...")
                  : t("ui.admin.audit.load_more", "Load more")}
              </Button>
            ) : (
              <span className="text-xs text-[var(--color-muted)]">
                {t("msg.admin.audit.end", "End of audit feed")}
              </span>
            )}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

export default AuditLogsPage;
