import { useState, useMemo, useCallback } from 'react';
import {
  Badge, Button, DateRangePicker, Input, Select, MonoText, CodeBlock, DataTable,
} from '@cameleer/design-system';
import type { Column } from '@cameleer/design-system';
import { Download } from 'lucide-react';
import { useAuditLog, type AuditEvent } from '../../api/queries/admin/audit';
import styles from './AuditLogPage.module.css';
import tableStyles from '../../styles/table-section.module.css';

const CATEGORIES = [
  { value: '', label: 'All categories' },
  { value: 'INFRA', label: 'INFRA' },
  { value: 'AUTH', label: 'AUTH' },
  { value: 'USER_MGMT', label: 'USER_MGMT' },
  { value: 'CONFIG', label: 'CONFIG' },
  { value: 'RBAC', label: 'RBAC' },
  { value: 'AGENT', label: 'AGENT' },
  { value: 'DEPLOYMENT', label: 'DEPLOYMENT' },
];

function exportCsv(events: AuditEvent[]) {
  const headers = ['Timestamp', 'User', 'Category', 'Action', 'Target', 'Result', 'Details'];
  const rows = events.map(e => [
    e.timestamp, e.username, e.category, e.action, e.target, e.result, e.detail ?? '',
  ]);
  const csv = [headers, ...rows].map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\n');
  const blob = new Blob([csv], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `cameleer-audit-${new Date().toISOString().slice(0, 16).replace(':', '-')}.csv`;
  a.click();
  URL.revokeObjectURL(url);
}

function formatTimestamp(iso: string): string {
  return new Date(iso).toLocaleString('en-GB', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
    hour12: false,
  });
}

type AuditRow = Omit<AuditEvent, 'id'> & { id: string };

const COLUMNS: Column<AuditRow>[] = [
  {
    key: 'timestamp', header: 'Timestamp', width: '170px', sortable: true,
    render: (_, row) => <MonoText size="xs">{formatTimestamp(row.timestamp)}</MonoText>,
  },
  {
    key: 'username', header: 'User', sortable: true,
    render: (_, row) => <span style={{ fontWeight: 500 }}>{row.username}</span>,
  },
  {
    key: 'category', header: 'Category', width: '110px', sortable: true,
    render: (_, row) => <Badge label={row.category} color="auto" />,
  },
  { key: 'action', header: 'Action' },
  {
    key: 'target', header: 'Target',
    render: (_, row) => <span className={styles.target}>{row.target}</span>,
  },
  {
    key: 'result', header: 'Result', width: '90px', sortable: true,
    render: (_, row) => (
      <Badge label={row.result} color={row.result === 'SUCCESS' ? 'success' : 'error'} />
    ),
  },
];

export default function AuditLogPage() {
  const [dateRange, setDateRange] = useState({
    start: new Date(Date.now() - 7 * 24 * 3600_000),
    end: new Date(),
  });
  const [userFilter, setUserFilter] = useState('');
  const [categoryFilter, setCategoryFilter] = useState('');
  const [searchFilter, setSearchFilter] = useState('');
  const [page, setPage] = useState(0);
  const [sortField, setSortField] = useState<string>('timestamp');
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');

  const handleSortChange = useCallback((key: string, dir: 'asc' | 'desc') => {
    setSortField(key);
    setSortDir(dir);
    setPage(0);
  }, []);

  const { data } = useAuditLog({
    username: userFilter || undefined,
    category: categoryFilter || undefined,
    search: searchFilter || undefined,
    from: dateRange.start.toISOString(),
    to: dateRange.end.toISOString(),
    sort: sortField,
    order: sortDir,
    page,
    size: 25,
  });

  const rows: AuditRow[] = useMemo(
    () => (data?.items || []).map((item) => ({ ...item, id: String(item.id) })),
    [data],
  );
  const totalCount = data?.totalCount ?? 0;

  return (
    <div>
      <div className={styles.filters}>
        <DateRangePicker
          value={dateRange}
          onChange={(range) => { setDateRange(range); setPage(0); }}
        />
        <Input
          placeholder="Filter by user..."
          value={userFilter}
          onChange={(e) => { setUserFilter(e.target.value); setPage(0); }}
          onClear={() => { setUserFilter(''); setPage(0); }}
          className={styles.filterInput}
        />
        <Select
          options={CATEGORIES}
          value={categoryFilter}
          onChange={(e) => { setCategoryFilter(e.target.value); setPage(0); }}
          className={styles.filterSelect}
        />
        <Input
          placeholder="Search action or target..."
          value={searchFilter}
          onChange={(e) => { setSearchFilter(e.target.value); setPage(0); }}
          onClear={() => { setSearchFilter(''); setPage(0); }}
          className={styles.filterInput}
        />
      </div>

      <div className={tableStyles.tableSection}>
        <div className={tableStyles.tableHeader}>
          <span className={tableStyles.tableTitle}>Audit Log</span>
          <div className={tableStyles.tableRight}>
            <span className={tableStyles.tableMeta}>
              {totalCount} events
            </span>
            <Badge label="AUTO" color="success" />
            <Button variant="ghost" size="sm" onClick={() => exportCsv(data?.items ?? [])}>
              <Download size={14} /> Export CSV
            </Button>
          </div>
        </div>
        <DataTable
          columns={COLUMNS}
          data={rows}
          sortable
          flush
          pageSize={25}
          onSortChange={handleSortChange}
          rowAccent={(row) => row.result === 'FAILURE' ? 'error' : undefined}
          expandedContent={(row) => (
            <div className={styles.expandedDetail}>
              <div className={styles.detailGrid}>
                <div className={styles.detailField}>
                  <span className={styles.detailLabel}>IP Address</span>
                  <MonoText size="xs">{row.ipAddress}</MonoText>
                </div>
                <div className={styles.detailField}>
                  <span className={styles.detailLabel}>User Agent</span>
                  <span className={styles.detailValue}>{row.userAgent}</span>
                </div>
              </div>
              <div className={styles.detailField}>
                <span className={styles.detailLabel}>Detail</span>
                <CodeBlock content={JSON.stringify(row.detail, null, 2)} language="json" />
              </div>
            </div>
          )}
        />
      </div>
    </div>
  );
}
