"use client";

import {
  useState,
  useEffect,
  useCallback,
  useMemo,
  useRef,
  forwardRef,
  useImperativeHandle,
} from "react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import Card from "./Card";
import RequestLoggerDetail from "./RequestLoggerDetail";
import { copyToClipboard } from "@/shared/utils/clipboard";
import {
  PROVIDER_COLORS,
  getHttpStatusStyle as getStatusStyle,
  getProtocolColor,
} from "@/shared/constants/colors";
import {
  formatTime,
  formatDuration,
  maskAccount,
  stableAccountSuffix,
  formatApiKeyLabel,
} from "@/shared/utils/formatting";
import { getProviderDisplayLabel } from "@/shared/utils/providerDisplayLabel";
import useEmailPrivacyStore from "@/store/emailPrivacyStore";
import {
  computeLogsSignature,
  shouldAutoRefresh,
  shouldTriggerInfiniteScroll,
} from "./requestLoggerSignature";
import {
  DEFAULT_REFRESH_INTERVAL_SEC,
  clampRefreshIntervalSec,
  readSavedRefreshIntervalSec,
  writeSavedRefreshIntervalSec,
} from "./requestLoggerPreferences";
import {
  LOG_TABLE_CLASS,
  LOG_TABLE_HEAD_CLASS,
  LOG_TABLE_HEADER_BG_STYLE,
  LOG_TABLE_HEADER_CELL_CLASS,
  LOG_TABLE_HEADER_CELL_RIGHT_CLASS,
  LOG_TABLE_ROW_CLASS,
} from "./logTableStyles";

// Number of call-log rows fetched per page. The viewer grows its window by this
// amount on "Load more" / infinite scroll so users can browse past the first
// page (previously hardcoded to a single 300-row window). See #2565.
// Reduced from 300 → 50 to avoid browser freeze and network saturation.
const PAGE_SIZE = 50;

function getLogTotalTokens(log) {
  return (log?.tokens?.in || 0) + (log?.tokens?.out || 0);
}

function getLogTps(log): number {
  const tokensOut = log?.tokens?.out || 0;
  const durationMs = log?.duration || 0;
  if (tokensOut <= 0 || durationMs <= 0) return 0;
  return tokensOut / (durationMs / 1000);
}

function formatTps(tps: number): string {
  if (tps <= 0) return "—";
  if (tps >= 100) return Math.round(tps).toLocaleString();
  return tps.toFixed(1);
}

function getCacheSourceMeta(cacheSource: unknown) {
  if (cacheSource === "semantic") {
    return {
      key: "semantic",
      className:
        "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 border border-emerald-500/30",
    };
  }

  return {
    key: "upstream",
    className: "bg-sky-500/15 text-sky-700 dark:text-sky-300 border border-sky-500/30",
  };
}

export interface RequestLoggerV2Handle {
  openDetail: (logEntry: any) => void;
  getSortedLogs: () => any[];
}

const RequestLoggerV2 = forwardRef<RequestLoggerV2Handle, { initialSelectedId?: string }>(
  (props, ref) => {
    const { initialSelectedId } = props as any;
    const t = useTranslations("requestLogger");
    const tCache = useTranslations("cache");
    const { emailsVisible } = useEmailPrivacyStore();

    // Get translated status filters
    const statusFilters = useMemo(
      () => [
        { key: "all", label: t("statusFilters.all"), icon: "" },
        { key: "error", label: t("statusFilters.error"), icon: "error" },
        { key: "ok", label: t("statusFilters.success"), icon: "check_circle" },
        { key: "combo", label: t("statusFilters.combo"), icon: "hub" },
      ],
      [t]
    );

    // Get translated columns
    const columns = useMemo(
      () => [
        { key: "status", label: t("columns.status") },
        { key: "cacheSource", label: t("columns.cacheSource") },
        { key: "model", label: t("columns.model") },
        { key: "requestedModel", label: t("columns.requested") },
        { key: "provider", label: t("columns.provider") },
        { key: "protocol", label: t("columns.protocol") },
        { key: "account", label: t("columns.account") },
        { key: "apiKey", label: t("columns.apiKey") },
        { key: "combo", label: t("columns.combo") },
        { key: "tokens", label: t("columns.tokens") },
        { key: "tps", label: t("columns.tps") },
        { key: "duration", label: t("columns.duration") },
        { key: "time", label: t("columns.time") },
      ],
      [t]
    );

    const [logs, setLogs] = useState([]);
    const [loading, setLoading] = useState(true);
    const [recording, setRecording] = useState(true);
    const [search, setSearch] = useState("");
    const [activeFilter, setActiveFilter] = useState("all");
    const [selectedModel, setSelectedModel] = useState("");
    const [selectedAccount, setSelectedAccount] = useState("");
    const [selectedProvider, setSelectedProvider] = useState("");
    const [selectedApiKey, setSelectedApiKey] = useState("");
    const [sortBy, setSortBy] = useState("newest");
    const [selectedLog, setSelectedLog] = useState(null);
    const [correlationIdFilter, setCorrelationIdFilter] = useState("");
    const [hoveredCid, setHoveredCid] = useState<string | null>(null);
    const [groupedView, setGroupedView] = useState(false);
    const [detailLoading, setDetailLoading] = useState(false);

    // Column sort toggle: clicking a column header toggles asc/desc
    const columnSortMap = {
      status: { desc: "status_desc", asc: "status_asc" },
      model: { desc: "model_desc", asc: "model_asc" },
      tokens: { desc: "tokens_desc", asc: "tokens_asc" },
      tps: { desc: "tps_desc", asc: "tps_asc" },
      duration: { desc: "duration_desc", asc: "duration_asc" },
      time: { desc: "newest", asc: "oldest" },
    };
    const toggleSort = useCallback((column: string) => {
      const mapping = columnSortMap[column as keyof typeof columnSortMap];
      if (!mapping) return;
      setSortBy((prev) => {
        if (prev === mapping.desc) return mapping.asc;
        return mapping.desc;
      });
    }, []);
    const getSortIndicator = useCallback(
      (column: string) => {
        const mapping = columnSortMap[column as keyof typeof columnSortMap];
        if (!mapping) return "";
        if (sortBy === mapping.desc) return " ↓";
        if (sortBy === mapping.asc) return " ↑";
        return "";
      },
      [sortBy]
    );
    const [detailData, setDetailData] = useState(null);
    const [detailLoggingEnabled, setDetailLoggingEnabled] = useState(false);
    const [detailLoggingLoading, setDetailLoggingLoading] = useState(false);
    const [limit, setLimit] = useState(PAGE_SIZE);
    const [hasMore, setHasMore] = useState(false);
    const [refreshIntervalSec, setRefreshIntervalSec] = useState(DEFAULT_REFRESH_INTERVAL_SEC);
    const intervalRef = useRef(null);
    const refreshIntervalSecRef = useRef(DEFAULT_REFRESH_INTERVAL_SEC);
    const detailRequestRef = useRef("");
    const hasLoadedRef = useRef(false);
    const logsSignatureRef = useRef("");
    const scrollContainerRef = useRef(null);
    const loadMoreSentinelRef = useRef(null);
    const hasScrolledRef = useRef(false);
    const [providerNodes, setProviderNodes] = useState([]);
    const visibleRef = useRef(true);

    const [visibleColumns, setVisibleColumns] = useState(() => {
      const defaultVisible = Object.fromEntries(columns.map((c) => [c.key, true]));
      if (globalThis.window === undefined) return defaultVisible;
      try {
        const saved = localStorage.getItem("loggerVisibleColumns");
        return saved ? { ...defaultVisible, ...JSON.parse(saved) } : defaultVisible;
      } catch {
        return defaultVisible;
      }
    });

    const toggleColumn = useCallback((key) => {
      setVisibleColumns((prev) => {
        const next = { ...prev, [key]: !prev[key] };
        try {
          localStorage.setItem("loggerVisibleColumns", JSON.stringify(next));
        } catch {}
        return next;
      });
    }, []);

    useEffect(() => {
      const saved = readSavedRefreshIntervalSec();
      refreshIntervalSecRef.current = saved;
      setRefreshIntervalSec(saved);
    }, []);

    useEffect(() => {
      refreshIntervalSecRef.current = refreshIntervalSec;
    }, [refreshIntervalSec]);

    const updateRefreshIntervalSec = useCallback(
      (valueOrUpdater: number | ((current: number) => number)) => {
        const current = refreshIntervalSecRef.current;
        const rawValue =
          typeof valueOrUpdater === "function" ? valueOrUpdater(current) : valueOrUpdater;
        const next = clampRefreshIntervalSec(rawValue);
        refreshIntervalSecRef.current = next;
        writeSavedRefreshIntervalSec(next);
        setRefreshIntervalSec(next);
      },
      []
    );

    const fetchLogs = useCallback(
      async (showLoading = false) => {
        if (showLoading) setLoading(true);
        try {
          const params = new URLSearchParams();
          if (search) params.set("search", search);
          if (activeFilter === "error") params.set("status", "error");
          if (activeFilter === "ok") params.set("status", "ok");
          if (activeFilter === "combo") params.set("combo", "1");
          if (selectedModel) params.set("model", selectedModel);
          if (selectedProvider) params.set("provider", selectedProvider);
          if (selectedAccount) params.set("account", selectedAccount);
          if (selectedApiKey) params.set("apiKey", selectedApiKey);
          if (correlationIdFilter) params.set("correlationId", correlationIdFilter);
          params.set("limit", String(limit));

          const res = await fetch(`/api/usage/call-logs?${params}`);
          if (res.ok) {
            const data = await res.json();
            // If the server returned a full window, more rows may exist beyond it.
            setHasMore(Array.isArray(data) && data.length >= limit);
            // Skip re-render if data hasn't changed (#1369 GPU perf). The signature
            // captures id + status + duration + tokens_out so in-progress updates
            // still re-render while identical snapshots are skipped.
            const sig = computeLogsSignature(data);
            if (sig !== logsSignatureRef.current) {
              logsSignatureRef.current = sig;
              setLogs(data);
            }
          }
        } catch (error) {
          console.error("Failed to fetch call logs:", error);
        } finally {
          if (showLoading) setLoading(false);
        }
      },
      [
        search,
        activeFilter,
        selectedModel,
        selectedAccount,
        selectedProvider,
        selectedApiKey,
        correlationIdFilter,
        limit,
      ]
    );

    useEffect(() => {
      const showLoading = !hasLoadedRef.current;
      hasLoadedRef.current = true;
      fetchLogs(showLoading);
    }, [fetchLogs]);

    // Fetch provider nodes for display labels
    useEffect(() => {
      fetch("/api/provider-nodes")
        .then((r) => (r.ok ? r.json() : { nodes: [] }))
        .then((d) => setProviderNodes(d.nodes || []))
        .catch(() => {});
    }, []);

    useEffect(() => {
      fetch("/api/logs/detail?limit=1")
        .then(async (res) => {
          if (!res.ok) return null;
          return await res.json();
        })
        .then((data) => {
          if (!data) return;
          setDetailLoggingEnabled(data.enabled === true);
        })
        .catch(() => {});
    }, []);

    // Visibility-aware auto-refresh: pause polling when tab is hidden or user has
    // scrolled past the first page, or when a detail modal is open.
    useEffect(() => {
      const onVisibility = () => {
        const isVisible = document.visibilityState === "visible";
        visibleRef.current = isVisible;
        if (isVisible && !selectedLog && shouldAutoRefresh(recording, limit, PAGE_SIZE)) {
          fetchLogs(false);
        }
      };
      // #4133: re-arm on window focus. Embedded / proxied hosts (Docker dashboard
      // wrappers, webviews) can fire a one-shot `visibilitychange` → hidden and
      // then keep reporting "hidden" — or recover without firing the event again —
      // which left `visibleRef` stuck `false` and froze auto-refresh permanently
      // (the "still not refreshing on 3.8.28, works on 3.8.24" report). A window
      // `focus` is a reliable signal the page is actively viewed, so re-arm and
      // poll. A genuinely backgrounded tab never receives focus, so this does not
      // defeat the perf pause.
      const onFocus = () => {
        visibleRef.current = true;
        if (!selectedLog && shouldAutoRefresh(recording, limit, PAGE_SIZE)) {
          fetchLogs(false);
        }
      };
      document.addEventListener("visibilitychange", onVisibility);
      window.addEventListener("focus", onFocus);
      return () => {
        document.removeEventListener("visibilitychange", onVisibility);
        window.removeEventListener("focus", onFocus);
      };
    }, [recording, limit, fetchLogs, selectedLog]);

    useEffect(() => {
      if (intervalRef.current) clearInterval(intervalRef.current);
      if (!selectedLog && shouldAutoRefresh(recording, limit, PAGE_SIZE)) {
        intervalRef.current = setInterval(() => {
          // #3972/#4054/#4133: poll while the page is plausibly viewed — the
          // event-tracked `visibleRef` (fail-open) OR a *live* `visibilityState`
          // read. A real background tab has both false → pause (perf); an
          // embedded host that misreports "hidden" keeps polling instead of
          // freezing. The window-`focus` re-arm above covers a host pinned
          // "hidden" while focused.
          if (visibleRef.current || document.visibilityState === "visible") {
            fetchLogs(false);
          }
        }, refreshIntervalSec * 1000);
      }
      return () => {
        if (intervalRef.current) clearInterval(intervalRef.current);
      };
    }, [recording, fetchLogs, limit, refreshIntervalSec, selectedLog]);

    // Reset the window back to the first page whenever the active filters change,
    // so switching filters doesn't keep fetching a large expanded window.
    useEffect(() => {
      setLimit(PAGE_SIZE);
      // #4269: a filter change is a fresh first-page view — re-arm the ghost-load-more
      // guard so auto-refresh resumes until the user scrolls again.
      hasScrolledRef.current = false;
    }, [
      search,
      activeFilter,
      selectedModel,
      selectedAccount,
      selectedProvider,
      selectedApiKey,
      correlationIdFilter,
    ]);

    const loadMore = useCallback(() => {
      setLimit((prev) => prev + PAGE_SIZE);
    }, []);

    // #4269: record the first genuine user scroll of the log list. Until then, the
    // infinite-scroll observer below must NOT grow the window (see
    // shouldTriggerInfiniteScroll) — otherwise a sentinel that is already visible on
    // mount fires a "ghost" loadMore and permanently pauses auto-refresh.
    useEffect(() => {
      const root = scrollContainerRef.current;
      if (!root) return;
      const onScroll = () => {
        if (root.scrollTop > 0) hasScrolledRef.current = true;
      };
      root.addEventListener("scroll", onScroll, { passive: true });
      return () => root.removeEventListener("scroll", onScroll);
    }, []);

    // Infinite scroll: grow the window when the sentinel near the bottom of the
    // scroll container becomes visible — but only after a real user scroll (#4269).
    useEffect(() => {
      const sentinel = loadMoreSentinelRef.current;
      const root = scrollContainerRef.current;
      if (!sentinel || !hasMore) return;
      const observer = new IntersectionObserver(
        (entries) => {
          if (
            shouldTriggerInfiniteScroll({
              isIntersecting: !!entries[0]?.isIntersecting,
              hasMore,
              loading,
              hasScrolled: hasScrolledRef.current,
            })
          ) {
            loadMore();
          }
        },
        { root, rootMargin: "200px" }
      );
      observer.observe(sentinel);
      return () => observer.disconnect();
    }, [hasMore, loading, loadMore]);

    const filteredLogs = useMemo(() => {
      let arr = logs;

      // Status filter
      if (activeFilter === "error") {
        arr = arr.filter((l) => l.status >= 400);
      } else if (activeFilter === "ok") {
        arr = arr.filter((l) => l.status >= 200 && l.status < 300);
      } else if (activeFilter === "combo") {
        arr = arr.filter((l) => l.comboName);
      }

      return arr;
    }, [logs, activeFilter]);

    // Grouped view: deduplicate by correlationId, keeping only the latest per group.
    // Rows without a correlationId are always shown.
    const dedupedLogs = useMemo(() => {
      if (!groupedView) return filteredLogs;
      const byCid = new Map<string, (typeof filteredLogs)[0]>();
      const noCid: typeof filteredLogs = [];
      for (const log of filteredLogs) {
        const cid = log.correlationId;
        if (!cid) {
          noCid.push(log);
          continue;
        }
        const existing = byCid.get(cid);
        if (
          !existing ||
          new Date(log.timestamp).getTime() > new Date(existing.timestamp).getTime()
        ) {
          byCid.set(cid, log);
        }
      }
      return [...noCid, ...byCid.values()];
    }, [filteredLogs, groupedView]);

    const sortedLogs = useMemo(() => {
      const arr = [...dedupedLogs];

      arr.sort((a, b) => {
        switch (sortBy) {
          case "oldest":
            return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
          case "tokens_desc":
            return getLogTotalTokens(b) - getLogTotalTokens(a);
          case "tokens_asc":
            return getLogTotalTokens(a) - getLogTotalTokens(b);
          case "duration_desc":
            return (b.duration || 0) - (a.duration || 0);
          case "duration_asc":
            return (a.duration || 0) - (b.duration || 0);
          case "tps_desc":
            return getLogTps(b) - getLogTps(a);
          case "tps_asc":
            return getLogTps(a) - getLogTps(b);
          case "status_desc":
            return (b.status || 0) - (a.status || 0);
          case "status_asc":
            return (a.status || 0) - (b.status || 0);
          case "model_asc":
            return (a.model || "").localeCompare(b.model || "");
          case "model_desc":
            return (b.model || "").localeCompare(a.model || "");
          case "newest":
          default:
            return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
        }
      });

      return arr;
    }, [dedupedLogs, sortBy]);

    // Group by correlationId: mark retries as children so they render indented
    // under the first request in each group. Compute group health:
    //   "healed"  — at least one failure followed by a success
    //   "failed"  — all attempts failed
    //   null      — single request or all succeeded
    const groupedLogs = useMemo(() => {
      const cidGroups = new Map();
      for (const log of sortedLogs) {
        const cid = log.correlationId;
        if (cid) {
          if (!cidGroups.has(cid)) cidGroups.set(cid, []);
          cidGroups.get(cid).push(log);
        }
      }
      return sortedLogs.map((log) => {
        const cid = log.correlationId;
        if (!cid) return { ...log, isRetry: false, groupSize: 1, groupStatus: null };
        const group = cidGroups.get(cid);
        if (!group || group.length <= 1)
          return { ...log, isRetry: false, groupSize: 1, groupStatus: null };
        const isFirst = group[0].id === log.id;
        const hasFailure = group.some((g) => g.status >= 400 || g.active);
        const hasSuccess = group.some((g) => g.status >= 200 && g.status < 300);
        const groupStatus = hasFailure && hasSuccess ? "healed" : hasFailure ? "failed" : null;
        return { ...log, isRetry: !isFirst, groupSize: group.length, groupStatus };
      });
    }, [sortedLogs]);

    // Fetch log detail from the persisted call-log endpoint. If a deep-linked
    // request is still being finalized, keep the modal open and poll this same
    // endpoint until the row appears.
    const router = useRouter();

    const openDetail = async (logEntry) => {
      // Guard: if no valid id provided, close instead of opening an empty modal
      if (!logEntry?.id) {
        try {
          closeDetail();
        } catch {}
        return;
      }

      const requestToken = `${logEntry.id}:${Date.now()}:${Math.random()}`;
      detailRequestRef.current = requestToken;
      const isCurrentDetailRequest = () => detailRequestRef.current === requestToken;

      setSelectedLog(logEntry);
      try {
        const url = new URL(globalThis.location.href);
        url.searchParams.set("id", logEntry.id);
        router.replace(url.pathname + url.search, { scroll: false });
      } catch (e) {
        // ignore navigation errors
      }
      setDetailLoading(true);
      setDetailData(null);
      try {
        const res = await fetch(`/api/logs/${logEntry.id}`, { cache: "no-store" });
        if (res.ok) {
          const data = await res.json();
          if (!isCurrentDetailRequest()) return;
          const dataHasPipeline =
            data?.pipelinePayloads && Object.keys(data.pipelinePayloads || {}).length > 0;
          setDetailData((prev: { pipelinePayloads: any }) => ({
            ...prev,
            ...data,
            pipelinePayloads: dataHasPipeline ? data.pipelinePayloads : prev?.pipelinePayloads,
          }));
          // ensure the modal summary reflects the fetched call log summary
          if (data && typeof data === "object") {
            setSelectedLog((prev: any) => ({
              ...prev,
              ...data,
              active: data.active === true,
            }));
          }
        } else {
          // A deep-linked id can legitimately 404 while the request is still
          // finalizing. Keep the modal open and poll /api/logs/[id] instead of
          // falling back to an in-memory active-request endpoint.
          if (!isCurrentDetailRequest()) return;
          if (res.status === 404) {
            if (logEntry.pendingLookup || logEntry.active) {
              setSelectedLog((prev: { method: any; path: any }) => ({
                ...prev,
                id: logEntry.id,
                status: 0,
                method: prev?.method,
                path: prev?.path || "",
              }));
              setDetailData({ detailState: "pending" });
              return;
            }
            try {
              console.warn("Log not found:", logEntry.id);
            } catch {}
            try {
              closeDetail();
            } catch {}
            return;
          }
          // other errors: show a minimal error indicator by setting detailData to an error object
          try {
            const body = await res.text().catch(() => null);
            if (!isCurrentDetailRequest()) return;
            setDetailData({ error: `Failed to fetch log (status ${res.status})`, body });
          } catch {}
        }
      } catch (error) {
        console.error("Failed to fetch log detail:", error);
      } finally {
        if (isCurrentDetailRequest()) setDetailLoading(false);
      }
    };

    const closeDetail = () => {
      detailRequestRef.current = "";
      setSelectedLog(null);
      setDetailData(null);
      try {
        // remove id param when closing detail
        const url = new URL(globalThis.location.href);
        url.searchParams.delete("id");
        router.replace(url.pathname + url.search, { scroll: false });
      } catch (e) {
        // ignore navigation errors
      }
    };

    const sortedLogsForNav = useMemo(() => sortedLogs, [sortedLogs]);

    useImperativeHandle(
      ref,
      () => ({
        openDetail,
        getSortedLogs: () => sortedLogsForNav,
      }),
      [openDetail, sortedLogsForNav]
    );

    // If the page provided an initialSelectedId (via ?id=), open it on mount.
    // Guard with a ref so subsequent URL updates (close -> replace) don't re-open the modal.
    const initialOpenedRef = useRef(false);
    useEffect(() => {
      if (initialSelectedId && !initialOpenedRef.current) {
        initialOpenedRef.current = true;
        openDetail({ id: initialSelectedId, pendingLookup: true })
          .then((r) => r)
          .catch((error_) => {
            console.error("Failed to open initial log id:", error_);
          });
      }
    }, [initialSelectedId]);

    useEffect(() => {
      const isActive = selectedLog?.active === true;
      if (!selectedLog?.id || !isActive) return;
      let cancelled = false;
      let graceCount = 0;
      const interval = setInterval(async () => {
        if (document.visibilityState !== "visible") return;
        try {
          const res = await fetch(`/api/logs/${selectedLog.id}`, { cache: "no-store" });
          if (cancelled) return;
          if (res.status === 404) {
            if (isActive) return;
            clearInterval(interval);
            return;
          }
          if (res.ok) {
            const data = await res.json();
            const stillActive = data.active === true;
            setDetailData((prev: { pipelinePayloads: any }) => ({
              ...prev,
              ...data,
              pipelinePayloads: data?.pipelinePayloads || prev?.pipelinePayloads,
            }));
            setSelectedLog((prev: any) => ({
              ...prev,
              ...data,
              active: stillActive,
            }));
            if (!stillActive) {
              graceCount++;
              if (graceCount >= 3) clearInterval(interval);
            }
          }
        } catch {
          // keep waiting; the detail endpoint is the single source of truth
        }
      }, 1000);
      return () => {
        cancelled = true;
        clearInterval(interval);
      };
    }, [selectedLog?.id, detailData?.detailState, selectedLog?.active, fetchLogs]);

    // Poll for related logs (same correlationId) while the detail modal is open.
    // This ensures newly completed retries appear without closing the modal.
    useEffect(() => {
      const cid = selectedLog?.correlationId;
      if (!selectedLog?.id || !cid) return;
      let cancelled = false;
      const interval = setInterval(async () => {
        if (document.visibilityState !== "visible") return;
        try {
          const res = await fetch(`/api/usage/call-logs?correlationId=${encodeURIComponent(cid)}`, {
            cache: "no-store",
          });
          if (cancelled || !res.ok) return;
          const cidLogs = await res.json();
          if (!Array.isArray(cidLogs) || cidLogs.length === 0) return;
          setLogs((prev) => {
            const ids = new Set(cidLogs.map((l: any) => l.id));
            let changed = false;
            const merged = prev.map((l: any) => {
              const updated = cidLogs.find((c: any) => c.id === l.id);
              if (updated) {
                changed = true;
                return { ...l, ...updated };
              }
              return l;
            });
            for (const cl of cidLogs) {
              if (!merged.some((m: any) => m.id === cl.id)) {
                merged.push(cl);
                changed = true;
              }
            }
            return changed ? merged : prev;
          });
        } catch {
          /* poll failed — non-critical */
        }
      }, 3000);
      return () => {
        cancelled = true;
        clearInterval(interval);
      };
    }, [selectedLog?.id, selectedLog?.correlationId]);

    const currentLogIndex = useMemo(() => {
      if (!selectedLog) return -1;
      return sortedLogsForNav.findIndex((l) => l.id === selectedLog.id);
    }, [selectedLog, sortedLogsForNav]);

    const handlePrev = useCallback(() => {
      const idx = currentLogIndex;
      const target = idx > 0 ? sortedLogsForNav[idx - 1] : null;
      if (target?.id) {
        openDetail(target)
          .then((r) => r)
          .catch((error_) => {
            console.error("Failed to open previous log id:", error_);
          });
      } else {
        closeDetail();
      }
    }, [currentLogIndex, sortedLogsForNav]);

    const handleNext = useCallback(() => {
      const idx = currentLogIndex;
      const target =
        idx >= 0 && idx < sortedLogsForNav.length - 1 ? sortedLogsForNav[idx + 1] : null;
      if (target?.id) {
        openDetail(target)
          .then((r) => r)
          .catch((error_) => {
            console.error("Failed to open previous log id:", error_);
          });
      } else {
        closeDetail();
      }
    }, [currentLogIndex, sortedLogsForNav]);

    const toggleDetailLogging = async () => {
      setDetailLoggingLoading(true);
      try {
        const nextEnabled = !detailLoggingEnabled;
        const res = await fetch("/api/logs/detail", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ enabled: nextEnabled }),
        });
        if (!res.ok) throw new Error(t("updatePipelineFailed"));
        setDetailLoggingEnabled(nextEnabled);
      } catch (error) {
        console.error("Failed to toggle pipeline logging:", error);
      } finally {
        setDetailLoggingLoading(false);
      }
    };

    const sourceLogsForDropdowns = logs;

    // Unique accounts and providers for dropdowns

    const uniqueAccounts = useMemo(
      () => [
        ...new Set(sourceLogsForDropdowns.map((l) => l.account).filter((a) => a && a !== "-")),
      ],
      [sourceLogsForDropdowns]
    );
    const uniqueModels = useMemo(
      () =>
        [
          ...new Set(
            sourceLogsForDropdowns.flatMap((l) => [l.model, l.requestedModel]).filter(Boolean)
          ),
        ].sort(),
      [sourceLogsForDropdowns]
    );
    const uniqueProviders = useMemo(
      () =>
        [
          ...new Set(sourceLogsForDropdowns.map((l) => l.provider).filter((p) => p && p !== "-")),
        ].sort(),
      [sourceLogsForDropdowns]
    );
    const uniqueApiKeys = useMemo(
      () =>
        [
          ...new Set(sourceLogsForDropdowns.map((l) => l.apiKeyId || l.apiKeyName).filter(Boolean)),
        ].sort(),
      [sourceLogsForDropdowns]
    );

    // Stats (memoized to avoid re-computation on every render)
    const { totalCount, okCount, errorCount, comboCount, apiKeyCount, runningCount } = useMemo(
      () => ({
        totalCount: filteredLogs.length,
        okCount: filteredLogs.filter((l) => l.status >= 200 && l.status < 300).length,
        errorCount: filteredLogs.filter((l) => l.status >= 400).length,
        comboCount: logs.filter((l) => l.comboName).length,
        apiKeyCount: uniqueApiKeys.length,
        runningCount: filteredLogs.filter((l) => l.active === true).length,
      }),
      [filteredLogs, logs, uniqueApiKeys]
    );

    return (
      <div className="flex flex-col gap-4">
        {/* Header Bar */}
        <div className="flex flex-wrap items-center gap-3">
          {/* Recording Toggle */}
          <button
            onClick={() => setRecording(!recording)}
            className={`flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium border transition-colors ${
              recording
                ? "bg-red-500/10 border-red-500/30 text-red-700 dark:text-red-400"
                : "bg-bg-subtle border-border text-text-muted"
            }`}
          >
            <span
              className={`w-2 h-2 rounded-full ${recording ? "bg-red-500 animate-pulse" : "bg-text-muted"}`}
            />
            {recording ? t("recording") : t("paused")}
          </button>

          <button
            onClick={toggleDetailLogging}
            disabled={detailLoggingLoading}
            className={`flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium border transition-colors disabled:opacity-60 ${
              detailLoggingEnabled
                ? "bg-amber-500/10 border-amber-500/30 text-amber-700 dark:text-amber-300"
                : "bg-bg-subtle border-border text-text-muted"
            }`}
            title={t("capturePipeline")}
          >
            <span
              className={`w-2 h-2 rounded-full ${detailLoggingEnabled ? "bg-amber-500" : "bg-text-muted"}`}
            />
            {detailLoggingLoading
              ? t("updatingPipelineLogs")
              : detailLoggingEnabled
                ? t("pipelineLogsOn")
                : t("pipelineLogsOff")}
          </button>

          {/* Search */}
          <div className="flex-1 min-w-[200px] relative">
            <span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-text-muted text-[18px]">
              search
            </span>
            <input
              type="text"
              placeholder={t("searchPlaceholder")}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full pl-10 pr-4 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:border-primary"
            />
          </div>

          {/* Correlation ID Filter */}
          <div className="min-w-[180px] relative">
            <span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-text-muted text-[16px]">
              tag
            </span>
            <input
              type="text"
              placeholder="Correlation ID"
              value={correlationIdFilter}
              onChange={(e) => setCorrelationIdFilter(e.target.value)}
              className="w-full pl-9 pr-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary font-mono placeholder:text-text-muted focus:outline-none focus:border-primary"
            />
          </div>

          {/* Group by CID toggle */}
          <button
            onClick={() => setGroupedView((v) => !v)}
            className={`flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium border transition-colors ${
              groupedView
                ? "bg-violet-500/15 border-violet-500/30 text-violet-700 dark:text-violet-300"
                : "bg-bg-subtle border-border text-text-muted hover:text-text-primary"
            }`}
            title={groupedView ? "Show all rows" : "Show latest per correlation ID"}
          >
            <span className="material-symbols-outlined text-[16px]">
              {groupedView ? "unfold_less" : "unfold_more"}
            </span>
            {groupedView ? "Grouped" : "All"}
          </button>

          {/* Provider Dropdown */}
          <select
            value={selectedProvider}
            onChange={(e) => setSelectedProvider(e.target.value)}
            className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[140px]"
          >
            <option value="">{t("allProviders")}</option>
            {uniqueProviders.map((p) => {
              const compatLabel = getProviderDisplayLabel(p, providerNodes);
              const pc = PROVIDER_COLORS[p];
              return (
                <option key={p} value={p}>
                  {compatLabel || pc?.label || p.toUpperCase()}
                </option>
              );
            })}
          </select>

          {/* Model Dropdown */}
          <select
            value={selectedModel}
            onChange={(e) => setSelectedModel(e.target.value)}
            className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[180px]"
          >
            <option value="">{t("allModels")}</option>
            {uniqueModels.map((model) => (
              <option key={model} value={model}>
                {model}
              </option>
            ))}
          </select>

          {/* Account Dropdown */}
          <select
            value={selectedAccount}
            onChange={(e) => setSelectedAccount(e.target.value)}
            className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[140px]"
          >
            <option value="">{t("allAccounts")}</option>
            {uniqueAccounts.map((a) => (
              <option key={a} value={a}>
                {emailsVisible ? a : `${maskAccount(a, false)} · #${stableAccountSuffix(a)}`}
              </option>
            ))}
          </select>

          {/* API Key Dropdown */}
          <select
            value={selectedApiKey}
            onChange={(e) => setSelectedApiKey(e.target.value)}
            className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[160px]"
          >
            <option value="">{t("allApiKeys")}</option>
            {uniqueApiKeys.map((value) => {
              const matched = logs.find((l) => (l.apiKeyId || l.apiKeyName) === value);
              const label = formatApiKeyLabel(matched?.apiKeyName, matched?.apiKeyId);
              return (
                <option key={value} value={value}>
                  {label}
                </option>
              );
            })}
          </select>

          {/* Stats */}
          <div className="flex items-center gap-2 text-xs text-text-muted">
            <span className="px-2 py-1 rounded bg-bg-subtle border border-border font-mono">
              {totalCount} {t("total")}
            </span>
            {runningCount > 0 && (
              <span className="px-2 py-1 rounded bg-amber-500/10 text-amber-700 dark:text-amber-400 font-mono">
                {runningCount} running
              </span>
            )}
            <span className="px-2 py-1 rounded bg-emerald-500/10 text-emerald-700 dark:text-emerald-400 font-mono">
              {okCount} {t("ok")}
            </span>
            {errorCount > 0 && (
              <span className="px-2 py-1 rounded bg-red-500/10 text-red-700 dark:text-red-400 font-mono">
                {errorCount} {t("err")}
              </span>
            )}
            {comboCount > 0 && (
              <span className="px-2 py-1 rounded bg-violet-500/10 text-violet-700 dark:text-violet-400 font-mono">
                {comboCount} {t("combo")}
              </span>
            )}
            {apiKeyCount > 0 && (
              <span className="px-2 py-1 rounded bg-primary/10 text-primary font-mono">
                {apiKeyCount} {t("keys")}
              </span>
            )}
            <span className="px-2 py-1 rounded bg-bg-subtle border border-border font-mono">
              {sortedLogs.length} {t("shown")}
            </span>
          </div>

          {/* Sort Dropdown */}
          <select
            value={sortBy}
            onChange={(e) => setSortBy(e.target.value)}
            className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[150px]"
            title={t("sortLogs")}
          >
            <option value="newest">{t("sortNewest")}</option>
            <option value="oldest">{t("sortOldest")}</option>
            <option value="tokens_desc">{t("sortTokensDesc")}</option>
            <option value="tokens_asc">{t("sortTokensAsc")}</option>
            <option value="duration_desc">{t("sortDurationDesc")}</option>
            <option value="duration_asc">{t("sortDurationAsc")}</option>
            <option value="status_desc">{t("sortStatusDesc")}</option>
            <option value="status_asc">{t("sortStatusAsc")}</option>
            <option value="model_asc">{t("sortModelAsc")}</option>
            <option value="model_desc">{t("sortModelDesc")}</option>
          </select>

          {/* Refresh interval */}
          <div className="flex items-center gap-1">
            <button
              onClick={() => updateRefreshIntervalSec((v) => v - 1)}
              className="w-6 h-6 flex items-center justify-center rounded hover:bg-bg-subtle text-text-muted hover:text-text-primary transition-colors text-sm font-bold"
              title="Decrease interval"
            >
              −
            </button>
            <input
              type="number"
              min={1}
              max={300}
              value={refreshIntervalSec}
              onChange={(e) => {
                const v = Number.parseInt(e.target.value, 10);
                if (!Number.isNaN(v)) updateRefreshIntervalSec(v);
              }}
              className="w-12 text-center text-[11px] bg-transparent border border-border rounded px-1 py-0.5 text-text-primary [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
              title="Auto-refresh interval in seconds"
            />
            <button
              onClick={() => updateRefreshIntervalSec((v) => v + 1)}
              className="w-6 h-6 flex items-center justify-center rounded hover:bg-bg-subtle text-text-muted hover:text-text-primary transition-colors text-sm font-bold"
              title="Increase interval"
            >
              +
            </button>
            <span className="text-[10px] text-text-muted">s</span>
          </div>

          {/* Refresh */}
          <button
            onClick={() => fetchLogs(false)}
            className="p-2 rounded-lg hover:bg-bg-subtle text-text-muted hover:text-text-primary transition-colors"
            title={t("refresh")}
          >
            <span className="material-symbols-outlined text-[18px]">refresh</span>
          </button>
        </div>

        {/* Quick Filters */}
        <div className="flex flex-wrap items-center gap-2">
          {/* Status Filters */}
          {statusFilters.map((f) => (
            <button
              key={f.key}
              onClick={() => setActiveFilter(activeFilter === f.key ? "all" : f.key)}
              className={`flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium border transition-all ${
                activeFilter === f.key
                  ? f.key === "error"
                    ? "bg-red-500/20 text-red-700 dark:text-red-400 border-red-500/40"
                    : f.key === "ok"
                      ? "bg-emerald-500/20 text-emerald-700 dark:text-emerald-400 border-emerald-500/40"
                      : f.key === "combo"
                        ? "bg-violet-500/20 text-violet-700 dark:text-violet-300 border-violet-500/40"
                        : "bg-primary text-white border-primary"
                  : "bg-bg-subtle border-border text-text-muted hover:border-text-muted"
              }`}
            >
              {f.icon && <span className="material-symbols-outlined text-[14px]">{f.icon}</span>}
              {f.label}
            </button>
          ))}

          {/* Divider */}
          {uniqueProviders.length > 0 && <span className="w-px h-5 bg-border mx-1" />}

          {/* Dynamic Provider Quick Filters (from data) */}
          {uniqueProviders.map((p) => {
            const compatLabel = getProviderDisplayLabel(p, providerNodes);
            const pc = PROVIDER_COLORS[p] || {
              bg: "#374151",
              text: "#fff",
              label: compatLabel || p.toUpperCase(),
            };
            const displayLabel = compatLabel || pc.label;
            const isActive = selectedProvider === p;
            return (
              <button
                key={p}
                onClick={() => setSelectedProvider(isActive ? "" : p)}
                className={`px-3 py-1 rounded-full text-xs font-bold uppercase border transition-all ${
                  isActive
                    ? "border-white/40 ring-1 ring-white/20"
                    : "border-transparent opacity-70 hover:opacity-100"
                }`}
                style={{
                  backgroundColor: isActive ? pc.bg : `${pc.bg}33`,
                  color: isActive ? pc.text : pc.bg,
                }}
              >
                {displayLabel}
              </button>
            );
          })}
        </div>

        {/* Column Visibility Toggles */}
        <div className="flex flex-wrap items-center gap-1.5">
          <span className="text-[10px] text-text-muted uppercase tracking-wider mr-1">
            {t("columnsLabel")}
          </span>
          {columns.map((col) => (
            <button
              key={col.key}
              onClick={() => toggleColumn(col.key)}
              className={`px-2 py-0.5 rounded text-[10px] font-medium border transition-all ${
                visibleColumns[col.key]
                  ? "bg-primary/15 text-primary border-primary/30"
                  : "bg-bg-subtle text-text-muted border-border opacity-50 hover:opacity-80"
              }`}
            >
              {col.label}
            </button>
          ))}
        </div>

        {/* Table */}
        <Card padding="none" className="min-h-[460px] resize-y overflow-auto bg-surface">
          <div
            ref={scrollContainerRef}
            className="p-0 overflow-x-auto overflow-y-auto h-full min-h-[460px]"
          >
            {loading && logs.length === 0 ? (
              <div className="p-8 text-center text-text-muted">{t("loadingLogs")}</div>
            ) : logs.length === 0 ? (
              <div className="p-8 text-center text-text-muted">
                <span className="material-symbols-outlined text-[48px] mb-2 block opacity-40">
                  receipt_long
                </span>
                {t("noLogs")}
              </div>
            ) : sortedLogs.length === 0 ? (
              <div className="p-8 text-center text-text-muted">{t("noMatchingLogs")}</div>
            ) : (
              <table className={LOG_TABLE_CLASS}>
                <thead className={LOG_TABLE_HEAD_CLASS} style={LOG_TABLE_HEADER_BG_STYLE}>
                  <tr className={LOG_TABLE_ROW_CLASS} style={LOG_TABLE_HEADER_BG_STYLE}>
                    {visibleColumns.status && (
                      <th
                        className={`${LOG_TABLE_HEADER_CELL_CLASS} cursor-pointer select-none`}
                        onClick={() => toggleSort("status")}
                      >
                        {t("columns.status")}
                        {getSortIndicator("status")}
                      </th>
                    )}
                    {visibleColumns.cacheSource && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.cacheSource")}</th>
                    )}
                    {visibleColumns.model && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.model")}</th>
                    )}
                    {visibleColumns.requestedModel && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.requested")}</th>
                    )}
                    {visibleColumns.provider && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.provider")}</th>
                    )}
                    {visibleColumns.protocol && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.protocol")}</th>
                    )}
                    {visibleColumns.account && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.account")}</th>
                    )}
                    {visibleColumns.apiKey && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.apiKey")}</th>
                    )}
                    {visibleColumns.combo && (
                      <th className={LOG_TABLE_HEADER_CELL_CLASS}>{t("columns.combo")}</th>
                    )}
                    {visibleColumns.tokens && (
                      <th
                        className={`${LOG_TABLE_HEADER_CELL_RIGHT_CLASS} cursor-pointer select-none`}
                        onClick={() => toggleSort("tokens")}
                      >
                        {t("columns.tokens")}
                        {getSortIndicator("tokens")}
                      </th>
                    )}
                    {visibleColumns.tps && (
                      <th
                        className={`${LOG_TABLE_HEADER_CELL_RIGHT_CLASS} cursor-pointer select-none`}
                        onClick={() => toggleSort("tps")}
                      >
                        {t("columns.tps")}
                        {getSortIndicator("tps")}
                      </th>
                    )}
                    {visibleColumns.duration && (
                      <th
                        className={`${LOG_TABLE_HEADER_CELL_RIGHT_CLASS} cursor-pointer select-none`}
                        onClick={() => toggleSort("duration")}
                      >
                        {t("columns.duration")}
                        {getSortIndicator("duration")}
                      </th>
                    )}
                    {visibleColumns.time && (
                      <th
                        className={`${LOG_TABLE_HEADER_CELL_RIGHT_CLASS} cursor-pointer select-none`}
                        onClick={() => toggleSort("time")}
                      >
                        {t("columns.time")}
                        {getSortIndicator("time")}
                      </th>
                    )}
                  </tr>
                </thead>
                <tbody className="divide-y divide-border/30">
                  {groupedLogs.map((log) => {
                    const isActive = log.active === true;
                    const statusStyle = isActive ? null : getStatusStyle(log.status);
                    const protocolKey = isActive ? null : log.sourceFormat || log.provider;
                    const protocol = protocolKey
                      ? getProtocolColor(protocolKey, log.provider)
                      : null;
                    const compatLabel = getProviderDisplayLabel(log.provider, providerNodes);
                    const providerColor = PROVIDER_COLORS[log.provider] || {
                      bg: "#374151",
                      text: "#fff",
                      label: compatLabel || (log.provider || "-").toUpperCase(),
                    };
                    const providerLabel = log.providerDisplay || compatLabel || providerColor.label;
                    const isError = !isActive && log.status >= 400;
                    const cacheSourceMeta = getCacheSourceMeta(log.cacheSource);
                    const isSemanticCache = cacheSourceMeta?.key === "semantic";
                    const accountLabel = maskAccount(log.account, emailsVisible);

                    return (
                      <tr
                        key={log.id}
                        onClick={() => openDetail(log)}
                        data-cid={log.correlationId || undefined}
                        onMouseEnter={() => log.correlationId && setHoveredCid(log.correlationId)}
                        onMouseLeave={() => setHoveredCid(null)}
                        className={
                          `cursor-pointer transition-colors ` +
                          `${
                            isError
                              ? "bg-red-500/5 hover:bg-red-500/15 dark:hover:bg-red-400/15"
                              : "hover:bg-sky-500/10 dark:hover:bg-sky-400/10"
                          } ` +
                          `${log.isRetry ? "border-l-2 border-l-amber-500/50" : ""} ` +
                          `${hoveredCid && log.correlationId === hoveredCid ? "bg-violet-500/10 dark:bg-violet-400/10 ring-1 ring-violet-500/20" : ""}`
                        }
                        style={
                          log.isRetry
                            ? {
                                backgroundColor:
                                  hoveredCid && log.correlationId === hoveredCid
                                    ? undefined
                                    : "rgba(245,158,11,0.03)",
                              }
                            : undefined
                        }
                      >
                        {visibleColumns.status && (
                          <td className="px-3 py-2">
                            {isActive ? (
                              <span
                                className="inline-flex items-center justify-center w-7 h-7 rounded-full bg-amber-500/15 border border-amber-500/25"
                                title="In progress"
                              >
                                <span className="inline-block h-3 w-3 rounded-full border-2 border-amber-500 border-t-transparent animate-spin" />
                              </span>
                            ) : (
                              <span className="inline-flex items-center gap-1">
                                <span
                                  className="inline-block px-2 py-0.5 rounded text-[10px] font-bold min-w-[36px] text-center"
                                  style={{
                                    backgroundColor: statusStyle.bg,
                                    color: statusStyle.text,
                                  }}
                                >
                                  {log.status || "..."}
                                </span>
                                {log.groupStatus === "healed" &&
                                  !log.isRetry &&
                                  log.status >= 400 && (
                                    <span
                                      className="text-emerald-500 text-[11px]"
                                      title="Recovered by retry"
                                    >
                                      ✓
                                    </span>
                                  )}
                                {log.isRetry && (
                                  <button
                                    className="inline-flex items-center text-amber-500 hover:text-amber-400 text-[11px] ml-0.5"
                                    title="Go to parent request"
                                    onClick={(e) => {
                                      e.stopPropagation();
                                      const parent = groupedLogs.find(
                                        (g) => g.correlationId === log.correlationId && !g.isRetry
                                      );
                                      if (parent) openDetail(parent);
                                    }}
                                  >
                                    ↳
                                  </button>
                                )}
                              </span>
                            )}
                          </td>
                        )}
                        {visibleColumns.cacheSource && (
                          <td className="px-3 py-2">
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : (
                              <span
                                className={`inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase ${cacheSourceMeta?.className || ""}`}
                                title={
                                  isSemanticCache ? t("semanticCacheHit") : t("upstreamResponse")
                                }
                              >
                                {isSemanticCache ? t("semantic") : t("upstream")}
                              </span>
                            )}
                          </td>
                        )}
                        {visibleColumns.model && (
                          <td className="px-3 py-2 font-medium text-primary font-mono text-[11px]">
                            <div className="flex items-center gap-1.5">
                              <span>{log.model}</span>
                              {log.groupStatus === "healed" && !log.isRetry && (
                                <span
                                  className="inline-flex items-center gap-0.5 px-1 py-0 rounded text-[8px] font-bold bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border border-emerald-500/25"
                                  title={`Failed, recovered after ${log.groupSize - 1} retry`}
                                >
                                  healed
                                </span>
                              )}
                              {log.groupStatus === "failed" && !log.isRetry && (
                                <span
                                  className="inline-flex items-center gap-0.5 px-1 py-0 rounded text-[8px] font-bold bg-red-500/15 text-red-600 dark:text-red-400 border border-red-500/25"
                                  title={`All ${log.groupSize} attempts failed`}
                                >
                                  failed
                                </span>
                              )}
                              {log.modelPinned && (
                                <span
                                  className="inline-flex items-center gap-0.5 px-1 py-0 rounded text-[8px] font-bold bg-violet-500/15 text-violet-600 dark:text-violet-400 border border-violet-500/25"
                                  title="Model selected via context-cache session pinning"
                                >
                                  pinned
                                </span>
                              )}
                            </div>
                            {log.correlationId && !log.isRetry && log.groupSize > 1 && (
                              <div
                                className="text-[9px] text-text-muted font-normal truncate max-w-[120px]"
                                title={log.correlationId}
                              >
                                {log.correlationId.slice(0, 12)}… · {log.groupSize} attempts
                              </div>
                            )}
                            {log.correlationId && !log.isRetry && log.groupSize <= 1 && (
                              <div
                                className="text-[9px] text-text-muted font-normal truncate max-w-[120px]"
                                title={log.correlationId}
                              >
                                {log.correlationId.slice(0, 12)}…
                              </div>
                            )}
                            {log.correlationId && log.isRetry && (
                              <div
                                className="text-[9px] text-amber-500/70 font-normal truncate max-w-[120px]"
                                title={log.correlationId}
                              >
                                {log.correlationId.slice(0, 12)}…
                              </div>
                            )}
                          </td>
                        )}
                        {visibleColumns.requestedModel && (
                          <td className="px-3 py-2 font-mono text-[11px]">
                            {log.requestedModel ? (
                              <span
                                className={
                                  log.requestedModel !== log.model
                                    ? "text-amber-600 dark:text-amber-400"
                                    : "text-text-muted"
                                }
                                title={
                                  log.requestedModel !== log.model
                                    ? t("requestedRoutedTitle", {
                                        requested: log.requestedModel,
                                        routed: log.model,
                                      })
                                    : log.requestedModel
                                }
                              >
                                {log.requestedModel}
                              </span>
                            ) : (
                              <span className="text-text-muted text-[10px]">—</span>
                            )}
                          </td>
                        )}
                        {visibleColumns.provider && (
                          <td className="px-3 py-2">
                            <span
                              className="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase"
                              style={{
                                backgroundColor: providerColor.bg,
                                color: providerColor.text,
                              }}
                            >
                              {providerLabel}
                            </span>
                          </td>
                        )}
                        {visibleColumns.protocol && (
                          <td className="px-3 py-2">
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : (
                              <span
                                className="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase"
                                style={
                                  protocol
                                    ? { backgroundColor: protocol.bg, color: protocol.text }
                                    : {}
                                }
                              >
                                {protocol?.label || "—"}
                              </span>
                            )}
                          </td>
                        )}
                        {visibleColumns.account && (
                          <td
                            className="px-3 py-2 text-text-muted truncate max-w-[120px]"
                            title={accountLabel}
                          >
                            {accountLabel}
                          </td>
                        )}
                        {visibleColumns.apiKey && (
                          <td
                            className="px-3 py-2 text-text-muted truncate max-w-[140px]"
                            title={log.apiKeyName || log.apiKeyId || t("noApiKey")}
                          >
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : (
                              formatApiKeyLabel(log.apiKeyName, log.apiKeyId)
                            )}
                          </td>
                        )}
                        {visibleColumns.combo && (
                          <td className="px-3 py-2">
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : log.comboName ? (
                              <span className="inline-block px-2 py-0.5 rounded-full text-[9px] font-bold bg-violet-500/20 text-violet-800 dark:text-violet-300 border border-violet-500/40">
                                {log.comboName}
                              </span>
                            ) : (
                              <span className="text-text-muted text-[10px]">—</span>
                            )}
                          </td>
                        )}
                        {visibleColumns.tokens && (
                          <td className="px-3 py-2 text-right whitespace-nowrap">
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : (
                              <>
                                <span className="text-text-muted">TI:</span>{" "}
                                <span className="text-primary">
                                  {log.tokens?.in?.toLocaleString() || 0}
                                </span>
                                <span className="mx-1 text-border">|</span>
                                <span className="text-text-muted">TO:</span>{" "}
                                <span className="text-emerald-700 dark:text-emerald-400">
                                  {log.tokens?.out?.toLocaleString() || 0}
                                </span>
                                {log.tokens?.cacheRead != null && log.tokens.cacheRead > 0 && (
                                  <>
                                    <span className="mx-1 text-border">|</span>
                                    <span className="text-text-muted">CR:</span>{" "}
                                    <span
                                      className="text-sky-700 dark:text-sky-400"
                                      title={tCache("cachedTokensCol")}
                                    >
                                      {log.tokens.cacheRead.toLocaleString()}
                                    </span>
                                  </>
                                )}
                                {log.tokens?.cacheWrite != null && log.tokens.cacheWrite > 0 && (
                                  <>
                                    <span className="mx-1 text-border">|</span>
                                    <span className="text-text-muted">CW:</span>{" "}
                                    <span
                                      className="text-amber-700 dark:text-amber-400"
                                      title={tCache("cacheCreation")}
                                    >
                                      {log.tokens.cacheWrite.toLocaleString()}
                                    </span>
                                  </>
                                )}
                                {log.tokens?.compressed != null && log.tokens.compressed > 0 && (
                                  <>
                                    <span className="mx-1 text-border">|</span>
                                    <span
                                      className="text-purple-500 dark:text-purple-400 font-semibold"
                                      title={`${log.tokens.compressed.toLocaleString()} tokens compressed`}
                                    >
                                      ↓{log.tokens.compressed.toLocaleString()}
                                    </span>
                                  </>
                                )}
                              </>
                            )}
                          </td>
                        )}
                        {visibleColumns.tps && (
                          <td className="px-3 py-2 text-right whitespace-nowrap font-mono">
                            {isActive ? (
                              <span className="text-text-muted text-[10px]">—</span>
                            ) : (
                              (() => {
                                const tps = getLogTps(log);
                                const color =
                                  tps <= 0
                                    ? "text-text-muted"
                                    : tps >= 80
                                      ? "text-emerald-600 dark:text-emerald-400"
                                      : tps >= 30
                                        ? "text-sky-600 dark:text-sky-400"
                                        : "text-amber-600 dark:text-amber-400";
                                return (
                                  <span className={color} title={`${tps.toFixed(2)} tokens/sec`}>
                                    {formatTps(tps)}
                                  </span>
                                );
                              })()
                            )}
                          </td>
                        )}
                        {visibleColumns.duration && (
                          <td className="px-3 py-2 text-right text-text-muted font-mono">
                            {formatDuration(log.duration)}
                          </td>
                        )}
                        {visibleColumns.time && (
                          <td className="px-3 py-2 text-right text-text-muted">
                            {formatTime(log.timestamp)}
                          </td>
                        )}
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}

            {hasMore && sortedLogs.length > 0 && (
              <div
                ref={loadMoreSentinelRef}
                className="flex justify-center py-3 border-t border-border/30"
              >
                <button
                  type="button"
                  onClick={loadMore}
                  className="px-4 py-1.5 text-xs rounded-md border border-border bg-bg-subtle hover:bg-bg-muted text-text-muted transition-colors"
                >
                  {loading ? t("loadingMore") : t("loadMore")}
                </button>
              </div>
            )}
          </div>
        </Card>

        <div className="text-[10px] text-text-muted italic">
          {t("callLogsInfo", {
            dataDir: "{DATA_DIR}/call_logs/",
            retentionDays: "CALL_LOG_RETENTION_DAYS",
            maxEntries: "CALL_LOG_MAX_ENTRIES",
          })}
        </div>

        {/* Detail Modal */}
        {selectedLog && (
          <RequestLoggerDetail
            log={selectedLog}
            detail={detailData}
            loading={detailLoading}
            debugEnabled={selectedLog.active ? true : detailLoggingEnabled}
            emailsVisible={emailsVisible}
            onClose={closeDetail}
            onCopy={copyToClipboard}
            onPrevious={handlePrev}
            onNext={handleNext}
            relatedLogs={
              selectedLog.correlationId
                ? groupedLogs.filter((l) => l.correlationId === selectedLog.correlationId)
                : []
            }
            onSelectRelated={(r) => {
              closeDetail();
              openDetail(r);
            }}
          />
        )}
      </div>
    );
  }
);

RequestLoggerV2.displayName = "RequestLoggerV2";

export default RequestLoggerV2;
