"use client";

import { useState, useEffect, useMemo } from "react";
import { useTranslations } from "next-intl";
import { customInstance } from "@/config/axios";
import toast from "react-hot-toast";
import { classifyApiLog, parseUserAgent, type ApiSeverity } from "@/lib/logHumanizer";

interface ApiLog {
  id: number;
  method: string;
  url: string;
  status_code: number;
  ip_address: string | null;
  user_agent: string | null;
  actor_id: number | null;
  actor_name: string | null;
  actor_role: string | null;
  error_message: string | null;
  stack_trace: string | null;
  request_body: object | null;
  created_at: string;
}

const SEVERITY_STYLES: Record<ApiSeverity, { dot: string; pill: string; banner: string; bannerText: string }> = {
  critical: {
    dot: "bg-red-500",
    pill: "bg-red-50 text-red-700 border-red-200",
    banner: "bg-red-50 border-red-200",
    bannerText: "text-red-800",
  },
  warning: {
    dot: "bg-yellow-500",
    pill: "bg-yellow-50 text-yellow-700 border-yellow-200",
    banner: "bg-yellow-50 border-yellow-200",
    bannerText: "text-yellow-800",
  },
  bot: {
    dot: "bg-gray-400",
    pill: "bg-gray-50 text-gray-600 border-gray-200",
    banner: "bg-gray-50 border-gray-200",
    bannerText: "text-gray-700",
  },
  ok: {
    dot: "bg-green-500",
    pill: "bg-green-50 text-green-700 border-green-200",
    banner: "bg-green-50 border-green-200",
    bannerText: "text-green-800",
  },
};

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 METHOD_COLORS: Record<string, string> = {
  GET: "bg-blue-50 text-blue-600",
  POST: "bg-green-50 text-green-600",
  PUT: "bg-orange-50 text-orange-600",
  PATCH: "bg-purple-50 text-purple-600",
  DELETE: "bg-red-50 text-red-600",
};

function getStatusColor(code: number): string {
  if (code >= 200 && code < 300) return "bg-green-50 text-green-600";
  if (code >= 400 && code < 500) return "bg-yellow-50 text-yellow-600";
  if (code >= 500) return "bg-red-50 text-red-600";
  return "bg-gray-50 text-gray-600";
}

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

  // Filters (temp state while editing, applied state for fetching)
  const [tempStatusCode, setTempStatusCode] = useState("");
  const [tempMethod, setTempMethod] = useState("");
  const [tempDateFrom, setTempDateFrom] = useState("");
  const [tempDateTo, setTempDateTo] = useState("");
  const [tempActorName, setTempActorName] = useState("");

  const [filterStatusCode, setFilterStatusCode] = useState("");
  const [filterMethod, setFilterMethod] = useState("");
  const [filterDateFrom, setFilterDateFrom] = useState("");
  const [filterDateTo, setFilterDateTo] = useState("");
  const [filterActorName, setFilterActorName] = useState("");

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

  const [selectedLog, setSelectedLog] = useState<ApiLog | null>(null);
  const [detailOpen, setDetailOpen] = useState(false);
  const [showTechnical, setShowTechnical] = useState(false);
  const [showBotScans, setShowBotScans] = useState(false);

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

  // Classify each log on the client. Backend doesn't store severity — and
  // since the rules (status code + path heuristics) are purely a function of
  // existing fields, deriving here keeps the migration footprint to zero.
  const classifiedLogs = useMemo(
    () => logs.map((log) => ({ log, classification: classifyApiLog(log) })),
    [logs]
  );

  const visibleLogs = useMemo(
    () =>
      showBotScans
        ? classifiedLogs
        : classifiedLogs.filter((row) => !row.classification.isBotScan),
    [classifiedLogs, showBotScans]
  );

  const botScanCount = useMemo(
    () => classifiedLogs.filter((row) => row.classification.isBotScan).length,
    [classifiedLogs]
  );

  // Friendly device string for the slider — falls back gracefully when the
  // raw UA is missing or doesn't match a known browser/OS.
  const formatDevice = (ua: string | null): string => {
    const parsed = parseUserAgent(ua);
    const browser = parsed.browserKey ? t(parsed.browserKey) : null;
    const os = parsed.osKey ? t(parsed.osKey) : null;
    const version = parsed.browserVersion || "";
    if (browser && os) return t("admin.apiLogs.deviceFmt", { browser, version, os });
    if (browser) return t("admin.apiLogs.deviceBrowserOnly", { browser, version });
    if (os) return t("admin.apiLogs.deviceOsOnly", { os });
    return t("admin.apiLogs.deviceUnknown");
  };

  const fetchLogs = async () => {
    try {
      setLoading(true);
      const params: Record<string, string | number> = {
        page: currentPage,
        limit,
      };
      if (filterStatusCode) params.status_code = Number(filterStatusCode);
      if (filterMethod) params.method = filterMethod;
      if (filterDateFrom) params.date_from = filterDateFrom;
      if (filterDateTo) params.date_to = filterDateTo;
      const response = await customInstance<{
        data: {
          logs: ApiLog[];
          total_count: number;
          page: number;
          limit: number;
          total_pages: number;
        };
      }>({
        url: "/v1/api-logs",
        method: "GET",
        params,
      });

      let filteredLogs = response.data.logs || [];
      const hasClientFilter = !!(filterActorName || filterDateFrom || filterDateTo);

      if (filterDateFrom) {
        const from = new Date(filterDateFrom);
        from.setHours(0, 0, 0, 0);
        filteredLogs = filteredLogs.filter(
          (log) => new Date(log.created_at) >= from
        );
      }
      if (filterDateTo) {
        const to = new Date(filterDateTo);
        to.setHours(23, 59, 59, 999);
        filteredLogs = filteredLogs.filter(
          (log) => new Date(log.created_at) <= to
        );
      }
      if (filterActorName) {
        const search = filterActorName.toLowerCase();
        filteredLogs = filteredLogs.filter(
          (log) => log.actor_name?.toLowerCase().includes(search)
        );
      }

      setLogs(filteredLogs);
      setTotalCount(hasClientFilter ? filteredLogs.length : (response.data.total_count || 0));
      setTotalPages(hasClientFilter ? 1 : (response.data.total_pages || 1));
    } catch (error) {
      console.error("Error fetching API logs:", error);
      setLogs([]);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchLogs();
  }, [currentPage, limit, filterStatusCode, filterMethod, filterDateFrom, filterDateTo, filterActorName]);

  const handleApplyFilters = () => {
    setFilterStatusCode(tempStatusCode);
    setFilterMethod(tempMethod);
    setFilterDateFrom(tempDateFrom);
    setFilterDateTo(tempDateTo);
    setFilterActorName(tempActorName);
    setCurrentPage(1);
  };

  const handleResetFilters = () => {
    setTempStatusCode("");
    setTempMethod("");
    setTempDateFrom("");
    setTempDateTo("");
    setTempActorName("");
    setFilterStatusCode("");
    setFilterMethod("");
    setFilterDateFrom("");
    setFilterDateTo("");
    setFilterActorName("");
    setCurrentPage(1);
  };

  // Filter-respecting, page-iterating XLS export. Mirrors the /admin/subscription export pattern:
  // title row merged+centered across all columns, HTML-as-XLS so Excel/Sheets render the merge
  // without needing an external library.
  const exportToXLS = async () => {
    const PAGE_SIZE = 500;
    const all: ApiLog[] = [];
    let page = 1;
    let totalPagesRemote = 1;
    let complete = true;
    const serverFilters: Record<string, string | number> = {};
    if (filterStatusCode) serverFilters.status_code = Number(filterStatusCode);
    if (filterMethod) serverFilters.method = filterMethod;
    if (filterDateFrom) serverFilters.date_from = filterDateFrom;
    if (filterDateTo) serverFilters.date_to = filterDateTo;
    try {
      do {
        const resp = await customInstance<{
          data: { logs: ApiLog[]; total_pages: number };
        }>({
          url: '/v1/api-logs',
          method: 'GET',
          params: { page, limit: PAGE_SIZE, ...serverFilters },
        });
        all.push(...(resp.data.logs || []));
        totalPagesRemote = resp.data.total_pages || 1;
        page += 1;
      } while (page <= totalPagesRemote);
    } catch (error) {
      console.error('Error exporting API logs:', error);
      complete = false;
    }

    // Client-side filters (actor_name is client-side in fetchLogs, so apply it here too).
    let exportRows = all;
    if (filterActorName) {
      const search = filterActorName.toLowerCase();
      exportRows = exportRows.filter((log) => log.actor_name?.toLowerCase().includes(search));
    }

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

    const headers = ['Sr No', 'Method', 'URL', 'Status Code', 'Actor', 'Role', 'IP Address', 'Date'];
    const rows = exportRows.map((log, index) => [
      (index + 1).toString(),
      log.method || '',
      log.url || '',
      log.status_code?.toString() || '',
      log.actor_name || '',
      log.actor_role || '',
      log.ip_address || '',
      formatDate(log.created_at),
    ]);

    // Formula-guarded HTML escape for XLS cells. Log URLs + actor names are user-controlled
    // (via request paths / auth payloads) — if any starts with = + - @ tab or CR, Excel would
    // evaluate it as a formula. Prefix with ' to neutralize before HTML-entity-escaping.
    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 = 'API 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', `api-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 = (log: ApiLog) => {
    setSelectedLog(log);
    setDetailOpen(true);
    setShowTechnical(false);
  };

  const handleCloseDetail = () => {
    setDetailOpen(false);
    setSelectedLog(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 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; filters + actions below on a single wrap-friendly row. */}
          <div className="p-5 border-b border-gray-200">
            <h3 className="text-lg font-semibold text-gray-900 mb-3">
              {t("admin.apiLogs.title")}
              {totalCount > 0 && (
                <span className="ml-2 text-sm font-normal text-gray-500">
                  ({totalCount} {totalCount === 1 ? t("admin.apiLogs.logSingular") : t("admin.apiLogs.logPlural")})
                </span>
              )}
            </h3>
            <div className="flex flex-wrap items-center gap-2">
                <input
                  type="number"
                  placeholder={t("admin.apiLogs.statusCodePlaceholder")}
                  value={tempStatusCode}
                  onChange={(e) => setTempStatusCode(e.target.value)}
                  className="w-28 px-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#3B9EC9]"
                  title={t("admin.apiLogs.statusCode")}
                />
                <select
                  value={tempMethod}
                  onChange={(e) => setTempMethod(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.apiLogs.allMethods")}</option>
                  <option value="GET">GET</option>
                  <option value="POST">POST</option>
                  <option value="PUT">PUT</option>
                  <option value="PATCH">PATCH</option>
                  <option value="DELETE">DELETE</option>
                </select>
                <input
                  type="text"
                  placeholder={t("admin.apiLogs.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.apiLogs.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.apiLogs.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.apiLogs.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.apiLogs.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-600 cursor-pointer select-none">
                  <input
                    type="checkbox"
                    checked={showBotScans}
                    onChange={(e) => setShowBotScans(e.target.checked)}
                    className="w-4 h-4 rounded border-gray-300 text-[#3B9EC9] focus:ring-[#3B9EC9] cursor-pointer"
                  />
                  {showBotScans ? t("admin.apiLogs.filter.hideBotScans") : t("admin.apiLogs.filter.showBotScans")}
                  {botScanCount > 0 && !showBotScans && (
                    <span className="text-xs text-gray-400">({botScanCount})</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-[900px]">
                <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-36">
                      {t("admin.apiLogs.colSeverity")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300">
                      {t("admin.apiLogs.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.apiLogs.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-32">
                      {t("admin.apiLogs.colFrom")}
                    </th>
                    <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-gray-300 w-44">
                      {t("admin.apiLogs.colWhen")}
                    </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>
                    ))
                  ) : visibleLogs.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.apiLogs.noLogs")}</p>
                        </div>
                      </td>
                    </tr>
                  ) : (
                    visibleLogs.map(({ log, classification }, index) => {
                      const styles = SEVERITY_STYLES[classification.severity];
                      const featureLabel = classification.pageNameKey
                        ? t(classification.pageNameKey)
                        : classification.pageNameFallback;
                      const headline = t(classification.headlineKey, {
                        ...classification.headlineValues,
                        // Some headlines reference {feature}/{path} — supply both so any rule
                        // that opts into them resolves cleanly.
                        feature: featureLabel,
                      });
                      return (
                        <tr
                          key={log.id}
                          onClick={() => handleRowClick(log)}
                          className={`hover:bg-gray-50/50 transition cursor-pointer ${
                            classification.isBotScan ? "opacity-70" : ""
                          } ${index !== visibleLogs.length - 1 ? "border-b border-gray-300" : ""}`}
                        >
                          <td className="px-5 py-3.5 border-r border-gray-300">
                            <span
                              className={`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium border ${styles.pill}`}
                            >
                              <span className={`w-1.5 h-1.5 rounded-full ${styles.dot}`} />
                              {t(classification.severityLabelKey)}
                            </span>
                          </td>
                          <td className="px-5 py-3.5 border-r border-gray-300">
                            <p className="text-sm text-gray-800 line-clamp-2">{headline}</p>
                            {classification.pageNameKey && (
                              <p className="text-xs text-gray-500 mt-0.5">{featureLabel}</p>
                            )}
                          </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"}`}>
                                    {log.actor_role}
                                  </span>
                                )}
                              </div>
                            ) : (
                              <span className="text-sm text-gray-400">{t("admin.apiLogs.fact.anonymous")}</span>
                            )}
                          </td>
                          <td className="px-5 py-3.5 text-sm text-gray-600 border-r border-gray-300 font-mono">
                            {log.ip_address || "-"}
                          </td>
                          <td className="px-5 py-3.5 text-sm text-gray-500">
                            {formatDate(log.created_at)}
                          </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>

      {/* Log Detail Modal */}
      {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 — friendly admin view. Headline + quick facts up top, raw
              technical fields collapsed by default so a non-technical admin
              never has to read a stack trace. */}
          {(() => {
            const classification = classifyApiLog(selectedLog);
            const styles = SEVERITY_STYLES[classification.severity];
            const featureLabel = classification.pageNameKey
              ? t(classification.pageNameKey)
              : classification.pageNameFallback;
            const headline = t(classification.headlineKey, {
              ...classification.headlineValues,
              feature: featureLabel,
            });
            const tip = t(classification.tipKey);
            const device = formatDevice(selectedLog.user_agent);
            return (
              <div
                className="relative bg-white w-full sm:w-[560px] 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.apiLogs.detailTitle")}</h3>
                    <span className={`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium border ${styles.pill}`}>
                      <span className={`w-1.5 h-1.5 rounded-full ${styles.dot}`} />
                      {t(classification.severityLabelKey)}
                    </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 */}
                <div className="flex-1 overflow-y-auto p-6 space-y-5">
                  {/* Headline banner — colored to match severity. The single
                      sentence answers "what happened" without forcing the admin
                      to interpret a status code. */}
                  <div className={`rounded-lg border px-4 py-3 ${styles.banner}`}>
                    <p className={`text-sm font-medium ${styles.bannerText}`}>{headline}</p>
                  </div>

                  {/* Quick facts — labels are deliberately plain English. */}
                  <div>
                    <p className="text-xs font-semibold uppercase tracking-wide text-gray-500 mb-3">
                      {t("admin.apiLogs.section.quickFacts")}
                    </p>
                    <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.apiLogs.fact.when")}</p>
                        <p className="text-sm text-gray-800">{formatDate(selectedLog.created_at)}</p>
                      </div>
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.fact.who")}</p>
                        {selectedLog.actor_name ? (
                          <div className="flex flex-col gap-1">
                            <p className="text-sm text-gray-800">{selectedLog.actor_name}</p>
                            {selectedLog.actor_role && (
                              <span className={`self-start inline-flex items-center px-2 py-0.5 rounded text-xs font-medium capitalize ${ROLE_COLORS[selectedLog.actor_role] || "bg-gray-50 text-gray-600"}`}>
                                {selectedLog.actor_role}
                              </span>
                            )}
                          </div>
                        ) : (
                          <p className="text-sm text-gray-500">{t("admin.apiLogs.fact.anonymous")}</p>
                        )}
                      </div>
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.fact.page")}</p>
                        <p className="text-sm text-gray-800">{featureLabel}</p>
                      </div>
                      <div>
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.fact.from")}</p>
                        <p className="text-sm font-mono text-gray-800">{selectedLog.ip_address || "-"}</p>
                      </div>
                      <div className="col-span-2">
                        <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.fact.device")}</p>
                        <p className="text-sm text-gray-800">{device}</p>
                      </div>
                    </div>
                  </div>

                  {/* "What does this mean?" — short plain-English explanation
                      so admin knows whether to act, escalate, or ignore. */}
                  <div className="rounded-lg border border-blue-200 bg-blue-50 px-4 py-3">
                    <p className="text-xs font-semibold uppercase tracking-wide text-blue-900 mb-1">
                      {t("admin.apiLogs.section.whatItMeans")}
                    </p>
                    <p className="text-sm text-blue-900 leading-relaxed">{tip}</p>
                  </div>

                  {/* Technical details — collapsed by default. Hidden behind a
                      toggle so the slider stays approachable; expanding it
                      reveals everything a developer would need to debug. */}
                  <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 className="flex items-center gap-2">
                        <svg className="w-4 h-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
                        </svg>
                        {showTechnical
                          ? t("admin.apiLogs.section.hideTechnical")
                          : t("admin.apiLogs.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 text-xs">
                        <div className="grid grid-cols-2 gap-3">
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.colId")}</p>
                            <p className="font-mono text-gray-800">{selectedLog.id}</p>
                          </div>
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.colMethod")}</p>
                            <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold font-mono ${METHOD_COLORS[selectedLog.method] || "bg-gray-50 text-gray-600"}`}>
                              {selectedLog.method}
                            </span>
                          </div>
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.colStatus")}</p>
                            <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold font-mono ${getStatusColor(selectedLog.status_code)}`}>
                              {selectedLog.status_code}
                            </span>
                          </div>
                        </div>

                        <div>
                          <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.colUrl")}</p>
                          <div className="bg-gray-50 rounded-lg px-3 py-2 border border-gray-200">
                            <p className="font-mono text-gray-800 break-all">{selectedLog.url}</p>
                          </div>
                        </div>

                        {selectedLog.user_agent && (
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.userAgent")}</p>
                            <div className="bg-gray-50 rounded-lg px-3 py-2 border border-gray-200">
                              <p className="text-gray-600 break-all">{selectedLog.user_agent}</p>
                            </div>
                          </div>
                        )}

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

                        {selectedLog.error_message && (
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.errorMessage")}</p>
                            <div className="bg-red-50 rounded-lg px-3 py-2 border border-red-200">
                              <p className="text-red-700 break-words">{selectedLog.error_message}</p>
                            </div>
                          </div>
                        )}

                        {selectedLog.stack_trace && (
                          <div>
                            <p className="text-xs font-medium text-gray-500 mb-1">{t("admin.apiLogs.stackTrace")}</p>
                            <div className="bg-gray-900 rounded-lg border border-gray-700 overflow-auto max-h-60">
                              <pre className="px-3 py-2 font-mono text-gray-300 whitespace-pre-wrap break-all">
                                {selectedLog.stack_trace}
                              </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>
      )}
    </>
  );
}
