// src/features/admin-audit/AuditTrail.tsx
// Admin: Global Audit Trail - paginated, immutable log.
// Filters: admin name search, action dropdown, targetType chips, date range.

'use client';

import { useCallback, useMemo, useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { usePaginatedQuery } from '@/lib/hooks/usePaginatedQuery';
import { AdminListPage } from '@/components/ui/domain/admin/AdminListPage';
import {
  AdminTable,
  AdminTableToolbar,
  useAdminTableLayout,
  type ColumnDef,
} from '@/components/ui/domain/admin';
import { AdminFilterBar, type FilterChip } from '@/components/ui/domain/admin/AdminFilterBar';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { useAdminFilters } from '@/components/ui/domain/admin/AdminFilterBar/useAdminFilters';
import { Pill } from '@/components/ui/primitives/Pill';
import { Button } from '@/components/ui/primitives/Button';
import type { AuditEntryRow } from '@/server/admin/_shared/audit-trail';
import { formatDate } from '@/lib/format';
import { buildCsv, downloadBlob } from '@/lib/admin/export';

const TABLE_ID = '/admin/system/audit';

// ─── Types ────────────────────────────────────────────────────────────────────

export interface AuditTrailProps {
  initialEntries: AuditEntryRow[];
  initialTotal: number;
  initialPage?: number;
}

// ─── Filter param keys ────────────────────────────────────────────────────────

const FILTER_KEYS = ['adminSearch', 'action', 'targetType', 'from', 'to'];

// ─── Tone helpers ─────────────────────────────────────────────────────────────

type PillTone = 'success' | 'warning' | 'danger' | 'neutral' | 'info';

function actionTone(action: string): PillTone {
  if (action === 'APPROVE' || action === 'RESTORE_REVIEW') return 'success';
  if (action === 'REJECT' || action === 'BAN' || action === 'REMOVE_REVIEW') return 'danger';
  if (action === 'FREEZE') return 'warning';
  if (action === 'UNFREEZE') return 'neutral';
  if (action === 'GRANT_ADMIN') return 'info';
  if (action === 'REVOKE_ADMIN') return 'warning';
  return 'neutral';
}

// ─── Note cell ────────────────────────────────────────────────────────────────

function NoteCell({
  note,
  expandLabel,
  collapseLabel,
}: {
  note: string | null;
  expandLabel: string;
  collapseLabel: string;
}) {
  const [expanded, setExpanded] = useState(false);
  if (!note) return <span className="text-text-secondary text-xs">—</span>;
  const isLong = note.length > 120;
  const displayed = !isLong || expanded ? note : `${note.slice(0, 120)}…`;
  return (
    <span className="text-text-secondary text-xs">
      {displayed}
      {isLong && (
        <Button
          type="button"
          variant="ghost"
          size="sm"
          className="ms-1 underline"
          onClick={() => setExpanded((v) => !v)}
          aria-expanded={expanded}
        >
          {expanded ? collapseLabel : expandLabel}
        </Button>
      )}
    </span>
  );
}

// ─── Component ────────────────────────────────────────────────────────────────

export function AuditTrail({ initialEntries, initialTotal, initialPage }: AuditTrailProps) {
  const t = useT('admin_audit');

  // ── Read active filter values from URL params ─────────────────────────────
  const { filters } = useAdminFilters(FILTER_KEYS);
  const adminSearchFilter = filters['adminSearch'] ?? '';
  const actionFilter = filters['action'] ?? '';
  const targetTypeFilter = filters['targetType'] ?? '';
  const fromFilter = filters['from'] ?? '';
  const toFilter = filters['to'] ?? '';

  const params = useMemo(() => {
    const next: Record<string, string> = {};
    if (adminSearchFilter) next.adminSearch = adminSearchFilter;
    if (actionFilter) next.action = actionFilter;
    if (targetTypeFilter) next.targetType = targetTypeFilter;
    if (fromFilter) next.from = fromFilter;
    if (toFilter) next.to = toFilter;
    return next;
  }, [actionFilter, adminSearchFilter, fromFilter, targetTypeFilter, toFilter]);

  // ── Paginated data ─────────────────────────────────────────────────────────
  const {
    data,
    total,
    totalPages,
    page,
    isLoading,
    isInitialLoading,
    isRefetching,
    error,
    setPage,
  } = usePaginatedQuery<AuditEntryRow>({
    endpoint: '/api/admin/audit',
    params,
    limit: 20,
    initialData: initialEntries,
    initialTotal,
    initialPage,
    dataKey: 'entries',
  });

  // ── Action label map ──────────────────────────────────────────────────────

  type ActionKey =
    | 'action_approve'
    | 'action_reject'
    | 'action_freeze'
    | 'action_unfreeze'
    | 'action_ban'
    | 'action_remove_review'
    | 'action_restore_review'
    | 'action_add_quantity'
    | 'action_grant_admin'
    | 'action_revoke_admin';

  const ACTION_LABEL_MAP: Record<string, ActionKey> = {
    APPROVE: 'action_approve',
    REJECT: 'action_reject',
    FREEZE: 'action_freeze',
    UNFREEZE: 'action_unfreeze',
    BAN: 'action_ban',
    REMOVE_REVIEW: 'action_remove_review',
    RESTORE_REVIEW: 'action_restore_review',
    ADD_QUANTITY: 'action_add_quantity',
    GRANT_ADMIN: 'action_grant_admin',
    REVOKE_ADMIN: 'action_revoke_admin',
  };

  // ── Chips ─────────────────────────────────────────────────────────────────
  const targetTypeChips: FilterChip[] = [
    { key: 'targetType', value: 'DEAL', label: t('target_type_deal') },
    { key: 'targetType', value: 'VENDOR', label: t('target_type_vendor') },
    { key: 'targetType', value: 'REVIEW', label: t('target_type_review') },
    { key: 'targetType', value: 'USER', label: t('target_type_user') },
    { key: 'action', value: 'APPROVE', label: t('action_approve') },
    { key: 'action', value: 'REJECT', label: t('action_reject') },
    { key: 'action', value: 'FREEZE', label: t('action_freeze') },
    { key: 'action', value: 'UNFREEZE', label: t('action_unfreeze') },
    { key: 'action', value: 'BAN', label: t('action_ban') },
    { key: 'action', value: 'REMOVE_REVIEW', label: t('action_remove_review') },
    { key: 'action', value: 'RESTORE_REVIEW', label: t('action_restore_review') },
    { key: 'action', value: 'GRANT_ADMIN', label: t('action_grant_admin') },
    { key: 'action', value: 'REVOKE_ADMIN', label: t('action_revoke_admin') },
  ];

  // ── Column definitions ────────────────────────────────────────────────────
  const columns: ColumnDef<AuditEntryRow>[] = [
    {
      key: 'createdAt',
      label: t('col_date'),
      render: (r) => formatDate(r.createdAt, 'he'),
      exportValue: (r) => r.createdAt,
      width: 'w-28',
    },
    {
      key: 'adminName',
      label: t('filter_admin_search'),
      render: (r) => (
        <span className="text-text-primary font-medium">{r.adminName ?? t('actor_ai')}</span>
      ),
      exportValue: (r) => r.adminName ?? t('actor_ai'),
    },
    {
      key: 'action',
      label: t('filter_action'),
      render: (r) => {
        const key = ACTION_LABEL_MAP[r.action];
        const label = key ? t(key) : r.action;
        return (
          <Pill tone={actionTone(r.action)} size="sm">
            {label}
          </Pill>
        );
      },
      exportValue: (r) => {
        const key = ACTION_LABEL_MAP[r.action];
        return key ? t(key) : r.action;
      },
    },
    {
      key: 'targetType',
      label: t('filter_target_type'),
      render: (r) => {
        const labelMap: Record<string, string> = {
          DEAL: t('target_type_deal'),
          VENDOR: t('target_type_vendor'),
          REVIEW: t('target_type_review'),
          USER: t('target_type_user'),
        };
        return labelMap[r.targetType] ?? r.targetType;
      },
      exportValue: (r) => r.targetType,
    },
    {
      key: 'targetId',
      label: t('target_id_label'),
      render: (r) => <span className="font-mono text-xs">{r.targetId.slice(0, 8)}…</span>,
      exportValue: (r) => r.targetId,
    },
    {
      key: 'note',
      label: t('col_note'),
      render: (r) => (
        <NoteCell note={r.note} expandLabel={t('note_expand')} collapseLabel={t('note_collapse')} />
      ),
      exportValue: (r) => r.note ?? '',
    },
  ];
  const layout = useAdminTableLayout(TABLE_ID, columns);
  const exportColumns = layout.visibleColumns;

  const handleExportPageCsv = useCallback(() => {
    downloadBlob(
      `multideal-audit-page-${new Date().toISOString().slice(0, 10)}.csv`,
      'text/csv;charset=utf-8',
      buildCsv(exportColumns, data),
    );
  }, [data, exportColumns]);

  const handleExportAllCsv = useCallback(async () => {
    const qs = new URLSearchParams({ ...params, export: 'csv' });
    const res = await fetch(`/api/admin/audit?${qs.toString()}`);
    if (!res.ok) return;
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.download = `multideal-audit-${new Date().toISOString().slice(0, 10)}.csv`;
    anchor.click();
    URL.revokeObjectURL(url);
  }, [params]);

  // ── Render ────────────────────────────────────────────────────────────────
  return (
    <AdminListPage
      status={error ? 'error' : isInitialLoading ? 'loading' : 'idle'}
      busy={isRefetching}
      onRetry={() => setPage(page)}
      primaryAction={
        <AdminTableToolbar
          layout={layout}
          columns={columns}
          total={total}
          page={page}
          limit={20}
          isLoading={isLoading}
          onExportPageCsv={handleExportPageCsv}
          onExportAllCsv={handleExportAllCsv}
        />
      }
      filterBar={
        <AdminFilterBar
          chips={targetTypeChips}
          searchKey="adminSearch"
          dateRange={{ fromKey: 'from', toKey: 'to' }}
        />
      }
      table={
        <AdminTable<AuditEntryRow>
          tableId={TABLE_ID}
          layout={layout}
          columnControls
          columns={columns}
          rows={data}
          loading={isLoading}
          virtualize={{
            estimateRowHeight: 56,
            scrollRestorationKey: TABLE_ID,
            scrollRestorationReady: !isInitialLoading && data.length > 0,
          }}
        />
      }
      pagination={
        totalPages > 1 ? (
          <Pagination page={page} totalPages={totalPages} onPageChange={setPage} />
        ) : undefined
      }
    />
  );
}
