"use client";

import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { customInstance } from "@/config/axios";
import toast from "react-hot-toast";
import { humanizeAuditLog, extractRequestBodyFacts } from "@/lib/logHumanizer";

interface AuditLog {
  id: number;
  action: string;
  resource_type: string;
  resource_id: string | number | null;
  // Some resources (clients, screenings) carry a UUID alongside the numeric id.
  // Optional because most resources still use only the numeric id.
  resource_uuid?: string | null;
  actor_id: number | null;
  actor_name: string | null;
  actor_role: string | null;
  // Backend-populated owner info — present on `client | screening | screening_report
  // | visibility_settings`. Null on other resources or for old rows pre-deploy.
  resource_owner_id: number | null;
  resource_owner_name: string | null;
  resource_owner_role: string | null;
  // Backend computes this; trust it. False on old rows, null-owner rows, and
  // any row where actor_id === resource_owner_id.
  is_cross_access: boolean;
  ip_address: string | null;
  details: object | null;
  created_at: string;
}

const ROLE_COLORS: Record<string, string> = {
  individual: "bg-blue-50 text-blue-600",
  practitioner: "bg-purple-50 text-purple-600",
  admin: "bg-red-50 text-red-600",
  "practice-manager": "bg-orange-50 text-orange-600",
};

const ACTION_COLORS: Record<string, string> = {
  view: "bg-blue-50 text-blue-600",
  view_list: "bg-blue-50 text-blue-600",
  create: "bg-green-50 text-green-600",
  update: "bg-orange-50 text-orange-600",
  delete: "bg-red-50 text-red-600",
  start_screening: "bg-indigo-50 text-indigo-600",
  submit_screening: "bg-teal-50 text-teal-600",
  share_report: "bg-cyan-50 text-cyan-600",
  download_report: "bg-sky-50 text-sky-600",
  change_visibility: "bg-amber-50 text-amber-600",
};

const RESOURCE_COLORS: Record<string, string> = {
  client: "bg-violet-50 text-violet-600",
  screening: "bg-emerald-50 text-emerald-600",
  screening_report: "bg-cyan-50 text-cyan-600",
  visibility_settings: "bg-amber-50 text-amber-600",
};

const ACTIONS = [
  "view",
  "view_list",
  "create",
  "update",
  "delete",
  "start_screening",
  "submit_screening",
  "share_report",
  "download_report",
  "change_visibility",
];

const RESOURCES = ["client", "screening", "screening_report", "visibility_settings"];

const ROLES = ["practitioner", "practice-manager", "individual"];

export default function AdminAuditLogs() {
  const t = useTranslations();

  // Filters (temp state while editing, applied state for fetching)
  const [tempAction, setTempAction] = useState("");
  const [tempResource, setTempResource] = useState("");
  const [tempRole, setTempRole] = useState("");
  const [tempActorName, setTempActorName] = useState("");
  const [tempDateFrom, setTempDateFrom] = useState("");
  const [tempDateTo, setTempDateTo] = useState("");

  const [filterAction, setFilterAction] = useState("");
  const [filterResource, setFilterResource] = useState("");
  const [filterRole, setFilterRole] = useState("");
  const [filterActorName, setFilterActorName] = useState("");
  const [filterDateFrom, setFilterDateFrom] = useState("");
  const [filterDateTo, setFilterDateTo] = useState("");
  // Cross-access toggle is applied immediately (no temp/apply step) — admins
  // expect a single click to surface suspicious events.
  const [crossAccessOnly, setCrossAccessOnly] = useState(false);

  const [logs, setLogs] = useState<AuditLog[]>([]);
  const [loading, setLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalCount, setTotalCount] = useState(0);

  const [selectedLog, setSelectedLog] = useState<AuditLog | null>(null);
  const [selectedLogDetail, setSelectedLogDetail] = useState<AuditLog | null>(null);
  const [detailOpen, setDetailOpen] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [showTechnical, setShowTechnical] = useState(false);

  const [limit, setLimit] = useState(10);

  const fetchLogs = async () => {
    try {
      setLoading(true);
      const params: Record<string, string | number> = {
        page: currentPage,
        limit,
      };
      if (filterAction) params.action = filterAction;
      if (filterResource) params.resource_type = filterResource;
      if (filterRole) params.actor_role = filterRole;
      if (filterActorName) params.actor_name = filterActorName;
      if (filterDateFrom) params.date_from = filterDateFrom;
      if (filterDateTo) params.date_to = filterDateTo;
      if (crossAccessOnly) params.cross_access = "true";

      // customInstance already unwraps axios response.data
      // Backend returns flat array: [{...}, {...}] or paginated: { data: { logs: [...], total_count, ... } }
      const result = await customInstance<any>({
        url: "/v1/audit-logs",
        method: "GET",
        params,
      });

      if (Array.isArray(result)) {
        // Flat array response
        setLogs(result);
        setTotalCount(result.length);
        setTotalPages(1);
      } else if (result?.data?.logs) {
        // Paginated wrapper response
        setLogs(result.data.logs);
        setTotalCount(result.data.total_count || 0);
        setTotalPages(result.data.total_pages || 1);
      } else if (Array.isArray(result?.data)) {
        // { data: [...] } wrapper without pagination
        setLogs(result.data);
        setTotalCount(result.data.length);
        setTotalPages(1);
      } else {
        setLogs([]);
      }
    } catch (error) {
      console.error("Error fetching audit logs:", error);
      setLogs([]);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchLogs();
  }, [currentPage, limit, filterAction, filterResource, filterRole, filterActorName, filterDateFrom, filterDateTo, crossAccessOnly]);

  const handleApplyFilters = () => {
    setFilterAction(tempAction);
    setFilterResource(tempResource);
    setFilterRole(tempRole);
    setFilterActorName(tempActorName);
    setFilterDateFrom(tempDateFrom);
    setFilterDateTo(tempDateTo);
    setCurrentPage(1);
  };

  const handleResetFilters = () => {
    setTempAction("");
    setTempResource("");
    setTempRole("");
    setTempActorName("");
    setTempDateFrom("");
    setTempDateTo("");
    setFilterAction("");
    setFilterResource("");
    setFilterRole("");
    setFilterActorName("");
    setFilterDateFrom("");
    setFilterDateTo("");
    setCrossAccessOnly(false);
    setCurrentPage(1);
  };

  // Filter-respecting, page-iterating XLS export. Mirrors the /admin/api-logs export pattern:
  // title row merged+centered across all columns, HTML-as-XLS so Excel/Sheets render the merge
  // without needing an external library. Backend can return either a flat array or a paginated
  // wrapper — handle both by short-circuiting the loop after the first page if no total_pages.
  const exportToXLS = async () => {
    const PAGE_SIZE = 500;
    const all: AuditLog[] = [];
    let page = 1;
    let totalPagesRemote = 1;
    let complete = true;
    const filters: Record<string, string | number> = {};
    if (filterAction) filters.action = filterAction;
    if (filterResource) filters.resource_type = filterResource;
    if (filterRole) filters.actor_role = filterRole;
    if (filterActorName) filters.actor_name = filterActorName;
    if (filterDateFrom) filters.date_from = filterDateFrom;
    if (filterDateTo) filters.date_to = filterDateTo;
    if (crossAccessOnly) filters.cross_access = "true";
    try {
      do {
        const result = await customInstance<any>({ // eslint-disable-line @typescript-eslint/no-explicit-any
          url: '/v1/audit-logs',
          method: 'GET',
          params: { page, limit: PAGE_SIZE, ...filters },
        });
        if (Array.isArray(result)) {
          all.push(...result);
          totalPagesRemote = 1; // flat-array response → no pagination, exit after first page
        } else if (result?.data?.logs) {
          all.push(...(result.data.logs || []));
          totalPagesRemote = result.data.total_pages || 1;
        } else if (Array.isArray(result?.data)) {
          all.push(...result.data);
          totalPagesRemote = 1;
        } else {
          totalPagesRemote = 1;
        }
        page += 1;
      } while (page <= totalPagesRemote);
    } catch (error) {
      console.error('Error exporting audit logs:', error);
      complete = false;
    }

    if (all.length === 0) {
      toast.error(t("admin.subscription.noDataToExport"));
      return;
    }
    if (!complete) {
      toast.error(t("admin.subscription.exportTruncated"));
    }
    toast.success(t("admin.subscription.exportingRows", { count: all.length }));

    const headers = [
      'Sr No', 'Action', 'Resource Type', 'Resource ID',
      'Actor', 'Role',
      'Owner', 'Owner Role', 'Cross-Access',
      'IP Address', 'Date',
    ];
    const rows = all.map((log, index) => [
      (index + 1).toString(),
      log.action || '',
      log.resource_type || '',
      log.resource_id !== null && log.resource_id !== undefined ? String(log.resource_id) : '',
      log.actor_name || '',
      log.actor_role || '',
      log.resource_owner_name || '',
      log.resource_owner_role || '',
      log.is_cross_access ? 'YES' : 'No',
      log.ip_address || '',
      formatDate(log.created_at),
    ]);

    // Formula-guarded HTML escape for XLS cells (see admin/api-logs for rationale).
    const escape = (v: string) => {
      const guarded = /^[=+\-@\t\r]/.test(v) ? `'${v}` : v;
      return guarded.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
    };
    const title = 'Audit Logs';
    const colCount = headers.length;
    const xlsContent = `<html xmlns:x="urn:schemas-microsoft-com:office:excel"><head><meta charset="UTF-8"/></head><body>
<table border="1">
  <tr><th colspan="${colCount}" style="text-align:center;font-size:14px;background:#f3f4f6;padding:8px">${escape(title)}</th></tr>
  <tr>${headers.map((h) => `<th style="background:#f9fafb;text-align:left;padding:6px">${escape(h)}</th>`).join('')}</tr>
  ${rows.map((row) => `<tr>${row.map((cell) => `<td style="padding:4px 6px">${escape(cell)}</td>`).join('')}</tr>`).join('\n  ')}
</table>
</body></html>`;

    const blob = new Blob([xlsContent], { type: 'application/vnd.ms-excel;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', `audit-logs_${new Date().toISOString().split('T')[0]}.xls`);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  const handleRowClick = async (log: AuditLog) => {
    setSelectedLog(log);
    setDetailOpen(true);
    setDetailLoading(true);
    setShowTechnical(false);
    try {
      const result = await customInstance<any>({
        url: `/v1/audit-logs/${log.id}`,
        method: "GET",
      });
      // customInstance unwraps axios .data — result is either the object or { data: {...} }
      const detail = result?.data?.id ? result.data : result;
      setSelectedLogDetail(detail);
    } catch {
      // Fall back to the list data if detail fetch fails
      setSelectedLogDetail(log);
    } finally {
      setDetailLoading(false);
    }
  };

  const handleCloseDetail = () => {
    setDetailOpen(false);
    setSelectedLog(null);
    setSelectedLogDetail(null);
    setShowTechnical(false);
  };

  const formatDate = (dateString: string) => {
    if (!dateString) return "-";
    return new Date(dateString).toLocaleDateString("en-US", {
      day: "numeric",
      month: "short",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  const formatLabel = (str: string) => {
    if (!str) return "-";
    return str
      .replace(/_/g, " ")
      .replace(/\b\w/g, (c) => c.toUpperCase());
  };

  const renderPagination = () => {
    const pages: (number | string)[] = [];
    if (totalPages <= 7) {
      for (let i = 1; i <= totalPages; i++) pages.push(i);
    } else if (currentPage <= 3) {
      pages.push(1, 2, 3, "...", totalPages - 1, totalPages);
    } else if (currentPage >= totalPages - 2) {
      pages.push(1, 2, "...", totalPages - 2, totalPages - 1, totalPages);
    } else {
      pages.push(1, "...", currentPage - 1, currentPage, currentPage + 1, "...", totalPages);
    }

    return pages.map((page, index) =>
      typeof page === "number" ? (
        <button
          key={index}
          onClick={() => setCurrentPage(page)}
          className={`w-8 h-8 rounded-lg text-sm font-medium cursor-pointer ${
            currentPage === page
              ? "bg-gray-100 text-gray-900"
              : "text-gray-600 hover:bg-gray-50"
          }`}
        >
          {page}
        </button>
      ) : (
        <span key={index} className="px-2 text-gray-400">
          {page}
        </span>
      )
    );
  };

  if (loading && logs.length === 0) {
    return (
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        <div className="flex items-center justify-center h-64">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#3B9EC9]"></div>
        </div>
      </main>
    );
  }

  return (
    <>
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        <div className="bg-white rounded-xl border border-gray-200 shadow-sm">
          {/* Header — title on its own row so it never competes with filters for space; below
              it a single wrap-friendly row with all filter inputs + action buttons inline. */}
          <div className="p-5 border-b border-gray-200">
            <h3 className="text-lg font-semibold text-gray-900 mb-3">
              {t("admin.auditLogs.title")}
              {totalCount > 0 && (
                <span className="ml-2 text-sm font-normal text-gray-500">
                  ({totalCount} {totalCount === 1 ? t("admin.auditLogs.logSingular") : t("admin.auditLogs.logPlural")})
                </span>
              )}
            </h3>
            <div className="flex flex-wrap items-center gap-2">
                <select
                  value={tempAction}
                  onChange={(e) => setTempAction(e.target.value)}
                  className="px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] min-w-[130px] cursor-pointer"
                >
                  <option value="">{t("admin.auditLogs.allActions")}</option>
                  {ACTIONS.map((a) => (
                    <option key={a} value={a}>{formatLabel(a)}</option>
                  ))}
                </select>
                <select
                  value={tempResource}
                  onChange={(e) => setTempResource(e.target.value)}
                  className="px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] min-w-[130px] cursor-pointer"
                >
                  <option value="">{t("admin.auditLogs.allResources")}</option>
                  {RESOURCES.map((r) => (
                    <option key={r} value={r}>{formatLabel(r)}</option>
                  ))}
                </select>
                <select
                  value={tempRole}
                  onChange={(e) => setTempRole(e.target.value)}
                  className="px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] min-w-[120px] cursor-pointer"
                >
                  <option value="">{t("admin.auditLogs.allRoles")}</option>
                  {ROLES.map((r) => (
                    <option key={r} value={r}>{formatLabel(r)}</option>
                  ))}
                </select>
                <input
                  type="text"
                  placeholder={t("admin.auditLogs.actorNamePlaceholder")}
                  value={tempActorName}
                  onChange={(e) => setTempActorName(e.target.value)}
                  className="w-40 px-4 py-2 border border-gray-200 rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-[#3B9EC9]"
                />
                <input
                  type="date"
                  value={tempDateFrom}
                  onChange={(e) => setTempDateFrom(e.target.value)}
                  className="px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
                  title={t("admin.auditLogs.dateFrom")}
                />
                <input
                  type="date"
                  value={tempDateTo}
                  onChange={(e) => setTempDateTo(e.target.value)}
                  className="px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
                  title={t("admin.auditLogs.dateTo")}
                />
                <button
                  onClick={handleApplyFilters}
                  className="px-4 py-2 bg-[#3B9EC9] text-white text-sm font-medium rounded-lg hover:bg-[#2D8AB5] transition cursor-pointer"
                >
                  {t("admin.auditLogs.apply")}
                </button>
                <button
                  onClick={handleResetFilters}
                  className="px-4 py-2 border border-gray-200 text-gray-600 text-sm font-medium rounded-lg hover:bg-gray-50 transition cursor-pointer"
                >
                  {t("admin.auditLogs.reset")}
                </button>
                <button
                  onClick={exportToXLS}
                  disabled={logs.length === 0}
                  className="flex items-center gap-2 px-4 py-2 bg-white border border-[#3B9EC9] text-[#3B9EC9] text-sm font-medium rounded-lg hover:bg-[#3B9EC9]/5 transition cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                  </svg>
                  {t("admin.subscription.export")}
                </button>
                <select
                  value={limit}
                  onChange={(e) => { setLimit(Number(e.target.value)); setCurrentPage(1); }}
                  className="px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
                >
                  <option value={10}>10</option>
                  <option value={25}>25</option>
                  <option value={50}>50</option>
                  <option value={100}>100</option>
                </select>
                <label
                  className="flex items-center gap-2 ml-1 text-sm text-gray-700 cursor-pointer select-none"
                  title={t("admin.auditLogs.filter.crossAccessHint")}
                >
                  <input
                    type="checkbox"
                    checked={crossAccessOnly}
                    onChange={(e) => { setCrossAccessOnly(e.target.checked); setCurrentPage(1); }}
                    className="w-4 h-4 rounded border-gray-300 text-red-500 focus:ring-red-500 cursor-pointer"
                  />
                  <span className="inline-flex items-center gap-1">
                    <svg className="w-4 h-4 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M5.07 19h13.86a2 2 0 001.74-3L13.74 4a2 2 0 00-3.48 0L3.34 16a2 2 0 001.73 3z" />
                    </svg>
                    {t("admin.auditLogs.filter.crossAccessOnly")}
                  </span>
                </label>
              </div>
            </div>

          {/* Table */}
          <div className="mx-5 mb-5 mt-5 border border-gray-300 rounded-lg overflow-hidden">
            <div className="overflow-x-auto">
              <table className="w-full border-collapse min-w-[920px] table-fixed">
                <thead>
                  <tr className="bg-gray-50">
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300 w-[340px]">
                      {t("admin.auditLogs.colWhat")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300 w-40">
                      {t("admin.auditLogs.colWho")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300 w-40">
                      {t("admin.auditLogs.colOwner")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300 w-40">
                      {t("admin.auditLogs.colWhen")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-gray-300">
                      {t("admin.auditLogs.colFrom")}
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {loading ? (
                    Array.from({ length: 8 }).map((_, i) => (
                      <tr key={i} className="border-b border-gray-300">
                        {Array.from({ length: 5 }).map((__, j) => (
                          <td key={j} className="px-5 py-4 border-r border-gray-300 last:border-r-0">
                            <div className="h-4 bg-gray-100 rounded animate-pulse" />
                          </td>
                        ))}
                      </tr>
                    ))
                  ) : logs.length === 0 ? (
                    <tr>
                      <td colSpan={5} className="px-5 py-12 text-center">
                        <div className="flex flex-col items-center gap-2 text-gray-400">
                          <svg className="w-10 h-10" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1}>
                            <path strokeLinecap="round" strokeLinejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                          </svg>
                          <p className="text-sm">{t("admin.auditLogs.noLogs")}</p>
                        </div>
                      </td>
                    </tr>
                  ) : (
                    logs.map((log, index) => {
                      const humanized = humanizeAuditLog(log);
                      const resourceLabel = humanized.resourceNameKey ? t(humanized.resourceNameKey) : "";
                      const headline = t(humanized.headlineKey, {
                        ...humanized.headlineValues,
                        resource: resourceLabel,
                      });
                      const isCross = log.is_cross_access;
                      return (
                        <tr
                          key={log.id}
                          onClick={() => handleRowClick(log)}
                          className={`transition cursor-pointer ${
                            isCross
                              ? "bg-red-50/40 hover:bg-red-50/70 border-l-4 border-l-red-400"
                              : "hover:bg-gray-50/50"
                          } ${index !== logs.length - 1 ? "border-b border-gray-300" : ""}`}
                        >
                          <td className="px-5 py-3.5 border-r border-gray-300">
                            <p className="text-sm text-gray-800 line-clamp-2">
                              {/* Inline warning icon up front so cross-access rows
                                  read as "⚠ jaoeo viewed client #22" — visible at
                                  first glance even if the colored pill below is
                                  scrolled out of view on dense tables. */}
                              {isCross && (
                                <svg className="inline-block w-4 h-4 mr-1 text-red-600 align-text-bottom" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5} aria-hidden="true">
                                  <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M5.07 19h13.86a2 2 0 001.74-3L13.74 4a2 2 0 00-3.48 0L3.34 16a2 2 0 001.73 3z" />
                                </svg>
                              )}
                              {headline}
                            </p>
                            {/* Cross-access pill + owner suffix — appears below the headline so the
                                row stays scannable. Owner-only (non-cross) rows skip this since the
                                owner info is shown in the slider. */}
                            {isCross && (
                              <div className="mt-1 flex flex-wrap items-center gap-1.5 text-xs">
                                <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-red-100 text-red-700 font-medium">
                                  {t("admin.auditLogs.crossAccess")}
                                </span>
                                {log.resource_owner_name && (
                                  <span className="text-gray-500">
                                    {t("admin.auditLogs.crossAccessOwnerSuffix", { owner: log.resource_owner_name })}
                                  </span>
                                )}
                              </div>
                            )}
                          </td>
                          <td className="px-5 py-3.5 border-r border-gray-300">
                            {log.actor_name ? (
                              <div className="flex flex-col gap-1">
                                <span className="text-sm text-gray-800">{log.actor_name}</span>
                                {log.actor_role && (
                                  <span className={`self-start inline-flex items-center px-2 py-0.5 rounded text-xs font-medium capitalize ${ROLE_COLORS[log.actor_role] || "bg-gray-50 text-gray-600"}`}>
                                    {formatLabel(log.actor_role)}
                                  </span>
                                )}
                              </div>
                            ) : (
                              <span className="text-sm text-gray-400">-</span>
                            )}
                          </td>
                          {/* Owner cell — three states:
                              1. owner null  → "-"
                              2. owner === actor → "(self)" muted
                              3. owner ≠ actor → name + role pill (red text when cross-access) */}
                          <td className="px-5 py-3.5 border-r border-gray-300">
                            {!log.resource_owner_name || log.resource_owner_id == null ? (
                              <span className="text-sm text-gray-400">-</span>
                            ) : log.resource_owner_id === log.actor_id ? (
                              <span className="text-sm text-gray-400">{t("admin.auditLogs.ownerSelfShort")}</span>
                            ) : (
                              <div className="flex flex-col gap-1">
                                <span className={`text-sm ${isCross ? "text-red-700 font-medium" : "text-gray-800"}`}>
                                  {log.resource_owner_name}
                                </span>
                                {log.resource_owner_role && (
                                  <span className="self-start inline-flex items-center px-2 py-0.5 rounded text-xs font-medium capitalize bg-gray-100 text-gray-700">
                                    {formatLabel(log.resource_owner_role)}
                                  </span>
                                )}
                              </div>
                            )}
                          </td>
                          <td className="px-5 py-3.5 text-sm text-gray-500 border-r border-gray-300">
                            {formatDate(log.created_at)}
                          </td>
                          <td className="px-5 py-3.5 text-sm text-gray-600 font-mono">
                            {log.ip_address || "-"}
                          </td>
                        </tr>
                      );
                    })
                  )}
                </tbody>
              </table>
            </div>
          </div>

          {/* Pagination */}
          {totalPages > 1 && (
            <div className="px-5 py-4 border-t border-gray-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
              <button
                onClick={() => setCurrentPage((prev) => Math.max(1, prev - 1))}
                disabled={currentPage === 1}
                className="flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                {t("admin.common.previous")}
              </button>

              <div className="flex items-center gap-1">{renderPagination()}</div>

              <button
                onClick={() => setCurrentPage((prev) => Math.min(totalPages, prev + 1))}
                disabled={currentPage === totalPages}
                className="flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
              >
                {t("admin.common.next")}
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                </svg>
              </button>
            </div>
          )}
        </div>
      </main>

      {/* Audit Log Detail Drawer */}
      {detailOpen && selectedLog && (
        <div
          className="fixed inset-0 z-50 flex items-end sm:items-center justify-center sm:justify-end"
          style={{ animation: "fadeIn 0.2s ease-out" }}
        >
          <style dangerouslySetInnerHTML={{
            __html: `
              @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
              @keyframes slideIn { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } }
            `,
          }} />

          {/* Backdrop */}
          <div
            className="absolute inset-0 bg-black/30"
            onClick={handleCloseDetail}
          />

          {/* Drawer */}
          <div
            className="relative bg-white w-full sm:w-[520px] h-full max-h-screen sm:max-h-screen overflow-hidden flex flex-col shadow-xl"
            style={{ animation: "slideIn 0.3s ease-out" }}
          >
            {/* Header */}
            <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 flex-shrink-0">
              <div className="flex items-center gap-3">
                <h3 className="text-base font-semibold text-gray-900">{t("admin.auditLogs.detailTitle")}</h3>
                <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold ${ACTION_COLORS[selectedLog.action] || "bg-gray-50 text-gray-600"}`}>
                  {formatLabel(selectedLog.action)}
                </span>
              </div>
              <button
                onClick={handleCloseDetail}
                className="text-gray-400 hover:text-gray-600 transition cursor-pointer"
              >
                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>

            {/* Body — friendly layout: one-sentence headline up top, plain
                quick facts below, raw resource type/id/JSON tucked under a
                "Show technical details" toggle for non-tech admins. */}
            <div className="flex-1 overflow-y-auto p-6 space-y-5">
              {detailLoading ? (
                <div className="flex items-center justify-center h-32">
                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#3B9EC9]"></div>
                </div>
              ) : (() => {
                const log = selectedLogDetail || selectedLog;
                const humanized = humanizeAuditLog(log);
                const resourceLabel = humanized.resourceNameKey ? t(humanized.resourceNameKey) : "";
                const headline = t(humanized.headlineKey, {
                  ...humanized.headlineValues,
                  resource: resourceLabel,
                });
                const tip = humanized.tipKey ? t(humanized.tipKey) : null;
                const isCross = log.is_cross_access;
                // Friendly key/value pairs from `details.request_body` — surfaces
                // the actual data the user submitted (email, score, role, etc.)
                // so admins don't have to read raw JSON.
                const bodyFacts = extractRequestBodyFacts(log.details);
                // Show owner row whenever backend populated it. Render "(self)"
                // when actor === owner so the admin can confirm at a glance that
                // nothing's suspicious; render the owner's name + role otherwise.
                const hasOwner = log.resource_owner_id != null;
                const ownerIsSelf =
                  hasOwner && log.resource_owner_id === log.actor_id;
                return (
                  <>
                    {/* Plain-English headline — replaces the cryptic action/resource pills */}
                    <div
                      className={`rounded-lg border px-4 py-3 ${
                        isCross
                          ? "border-red-200 bg-red-50"
                          : "border-gray-200 bg-gray-50"
                      }`}
                    >
                      <p className={`text-sm font-medium ${isCross ? "text-red-900" : "text-gray-800"}`}>
                        {headline}
                      </p>
                      {isCross && log.resource_owner_name && (
                        <p className="text-xs text-red-700 mt-1">
                          {t("admin.auditLogs.crossAccessOwnerSuffix", { owner: log.resource_owner_name })}
                        </p>
                      )}
                    </div>

                    {/* Quick facts */}
                    <div className="grid grid-cols-2 gap-x-4 gap-y-3">
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.when")}</p>
                        <p className="text-sm text-gray-800">{formatDate(log.created_at)}</p>
                      </div>
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.who")}</p>
                        {log.actor_name ? (
                          <div className="flex flex-col gap-1">
                            <p className="text-sm text-gray-800">{log.actor_name}</p>
                            {log.actor_role && (
                              <span className={`self-start inline-flex items-center px-2 py-0.5 rounded text-xs font-medium capitalize ${ROLE_COLORS[log.actor_role] || "bg-gray-50 text-gray-600"}`}>
                                {formatLabel(log.actor_role)}
                              </span>
                            )}
                          </div>
                        ) : (
                          <p className="text-sm text-gray-400">-</p>
                        )}
                      </div>
                      {log.resource_id != null && resourceLabel && (
                        <div>
                          <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.page")}</p>
                          <p className="text-sm text-gray-800 capitalize">
                            {resourceLabel} #{log.resource_id}
                          </p>
                        </div>
                      )}
                      {/* "Client" fact — shown whenever backend supplied client info
                          in details. Especially useful for screening / report actions
                          where the resource itself doesn't name the client. */}
                      {humanized.clientName && (
                        <div>
                          <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.client")}</p>
                          <p className="text-sm text-gray-800">
                            {humanized.clientName}
                            {humanized.clientId && (
                              <span className="text-gray-500"> #{humanized.clientId}</span>
                            )}
                          </p>
                        </div>
                      )}
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.from")}</p>
                        <p className="text-sm font-mono text-gray-800">{log.ip_address || "-"}</p>
                      </div>
                      {hasOwner && (
                        <div className="col-span-2">
                          <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.fact.owner")}</p>
                          {ownerIsSelf ? (
                            <p className="text-sm text-gray-500">{t("admin.auditLogs.fact.ownerSelf")}</p>
                          ) : (
                            <div className="flex flex-col gap-1">
                              <p className={`text-sm ${isCross ? "text-red-800 font-medium" : "text-gray-800"}`}>
                                {log.resource_owner_name}
                              </p>
                              {log.resource_owner_role && (
                                <span className="self-start inline-flex items-center px-2 py-0.5 rounded text-xs font-medium capitalize bg-gray-100 text-gray-700">
                                  {formatLabel(log.resource_owner_role)}
                                </span>
                              )}
                            </div>
                          )}
                        </div>
                      )}
                    </div>

                    {/* Submitted info — friendly key/value pairs from request_body.
                        Lets the admin see "Email: john@x.com / Score: 14" without
                        cracking open the technical-details JSON. Hidden when the
                        request had no surfaceable scalar fields. */}
                    {bodyFacts.length > 0 && (
                      <div>
                        <p className="text-xs font-semibold uppercase tracking-wide text-gray-500 mb-3">
                          {t("admin.auditLogs.section.submittedData")}
                        </p>
                        <div className="grid grid-cols-2 gap-x-4 gap-y-3">
                          {bodyFacts.map(({ labelKey, value }) => (
                            <div key={labelKey + value}>
                              <p className="text-xs font-medium text-gray-500 mb-1">{t(labelKey)}</p>
                              <p className="text-sm text-gray-800 break-all">{value}</p>
                            </div>
                          ))}
                        </div>
                      </div>
                    )}

                    {/* Cross-access warning — most important visual cue when actor
                        accessed another user's data. Stronger than the regular tip
                        because this is the HIPAA-relevant case. */}
                    {isCross && (
                      <div className="rounded-lg border-2 border-red-300 bg-red-50 px-4 py-3">
                        <p className="text-sm font-bold uppercase tracking-wide text-red-900 mb-1 flex items-center gap-2">
                          <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
                            <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M5.07 19h13.86a2 2 0 001.74-3L13.74 4a2 2 0 00-3.48 0L3.34 16a2 2 0 001.73 3z" />
                          </svg>
                          {t("admin.auditLogs.crossAccessDetected")}
                        </p>
                        <p className="text-sm text-red-900 leading-relaxed">
                          {t("admin.auditLogs.tip.crossAccess")}
                        </p>
                      </div>
                    )}

                    {/* "What does this mean?" — plain-English explanation shown for
                        every action so a non-technical admin always knows what just
                        happened and whether to act. Skipped when the cross-access
                        warning is already showing (it serves the same purpose, more
                        strongly). Delete actions get amber styling instead of blue
                        because they warrant extra caution. */}
                    {tip && !isCross && (
                      <div
                        className={`rounded-lg border px-4 py-3 ${
                          humanized.tipKey === "admin.auditLogs.tip.delete"
                            ? "border-amber-200 bg-amber-50"
                            : "border-blue-200 bg-blue-50"
                        }`}
                      >
                        <p
                          className={`text-xs font-semibold uppercase tracking-wide mb-1 ${
                            humanized.tipKey === "admin.auditLogs.tip.delete"
                              ? "text-amber-900"
                              : "text-blue-900"
                          }`}
                        >
                          {t("admin.auditLogs.section.whatItMeans")}
                        </p>
                        <p
                          className={`text-sm leading-relaxed ${
                            humanized.tipKey === "admin.auditLogs.tip.delete"
                              ? "text-amber-900"
                              : "text-blue-900"
                          }`}
                        >
                          {tip}
                        </p>
                      </div>
                    )}

                    {/* Technical details — collapsed by default */}
                    <div>
                      <button
                        type="button"
                        onClick={() => setShowTechnical((v) => !v)}
                        className="w-full flex items-center justify-between px-3 py-2 border border-gray-200 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50 transition cursor-pointer"
                      >
                        <span>
                          {showTechnical
                            ? t("admin.auditLogs.section.hideTechnical")
                            : t("admin.auditLogs.section.showTechnical")}
                        </span>
                        <svg
                          className={`w-4 h-4 text-gray-400 transition-transform ${showTechnical ? "rotate-180" : ""}`}
                          fill="none"
                          viewBox="0 0 24 24"
                          stroke="currentColor"
                          strokeWidth={2}
                        >
                          <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
                        </svg>
                      </button>

                      {showTechnical && (
                        <div className="mt-3 space-y-3">
                          <div className="grid grid-cols-2 gap-3">
                            <div>
                              <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.colAction")}</p>
                              <span className={`inline-flex items-center px-2.5 py-0.5 rounded text-xs font-semibold ${ACTION_COLORS[log.action] || "bg-gray-50 text-gray-600"}`}>
                                {formatLabel(log.action)}
                              </span>
                            </div>
                            <div>
                              <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.colResource")}</p>
                              <span className={`inline-flex items-center px-2.5 py-0.5 rounded text-xs font-semibold ${RESOURCE_COLORS[log.resource_type] || "bg-gray-50 text-gray-600"}`}>
                                {formatLabel(log.resource_type)}
                              </span>
                            </div>
                            <div>
                              <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.colResourceId")}</p>
                              <p className="text-sm font-mono text-gray-800">{log.resource_id ?? "-"}</p>
                            </div>
                            {log.resource_uuid && (
                              <div className="col-span-2">
                                <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.colResourceUuid")}</p>
                                <p className="text-xs font-mono text-gray-800 break-all">{log.resource_uuid}</p>
                              </div>
                            )}
                          </div>

                          {log.details && (
                            <div>
                              <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.auditLogs.details")}</p>
                              <div className="bg-gray-50 rounded-lg border border-gray-200 overflow-auto max-h-60">
                                <pre className="px-3 py-2 text-xs font-mono text-gray-700 whitespace-pre-wrap break-all">
                                  {JSON.stringify(log.details, null, 2)}
                                </pre>
                              </div>
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  </>
                );
              })()}
            </div>

            {/* Footer */}
            <div className="px-6 py-4 border-t border-gray-200 flex-shrink-0">
              <button
                onClick={handleCloseDetail}
                className="w-full px-4 py-2.5 border border-gray-300 rounded-full text-sm font-medium text-gray-600 hover:bg-gray-50 transition cursor-pointer"
              >
                {t("admin.modals.close")}
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}
