'use client';

import { useState, useMemo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { apiClient } from '@/infrastructure/api/api-client';
import { queryKeys } from '@/infrastructure/api/query-keys';
import { cn } from '@/lib/utils';

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

interface AuditLog {
  id: string;
  timestamp: string;
  actionType: string;
  actorType: string;
  actorId: string;
  resourceType: string;
  resourceId: string;
  description: string;
  detail: Record<string, unknown>;
}

type AuditLogsResponse = AuditLog[];

interface Filters {
  dateFrom: string;
  dateTo: string;
  actionType: string;
  actorType: string;
  resourceType: string;
}

// ── Constants ───────────────────────────────────────────────────────────────

const ACTION_TYPES = ['', 'CREATE', 'UPDATE', 'DELETE', 'LOGIN', 'EXECUTE', 'APPROVE', 'REJECT'];
const ACTOR_TYPES = ['', 'user', 'system', 'agent'];
const RESOURCE_TYPES = ['', 'server', 'task', 'standing_order', 'runbook', 'credential', 'user'];
const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];

// ── Main Component ──────────────────────────────────────────────────────────

export default function AuditLogsPage() {
  const { t } = useTranslation('audit');
  const { t: tc } = useTranslation('common');
  const [filters, setFilters] = useState<Filters>({
    dateFrom: '',
    dateTo: '',
    actionType: '',
    actorType: '',
    resourceType: '',
  });
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(25);
  const [expandedId, setExpandedId] = useState<string | null>(null);

  // Build query params from filters
  const queryParams = useMemo(() => {
    const params: Record<string, string> = {
      page: String(page),
      pageSize: String(pageSize),
    };
    if (filters.dateFrom) params.dateFrom = filters.dateFrom;
    if (filters.dateTo) params.dateTo = filters.dateTo;
    if (filters.actionType) params.actionType = filters.actionType;
    if (filters.actorType) params.actorType = filters.actorType;
    if (filters.resourceType) params.resourceType = filters.resourceType;
    return params;
  }, [filters, page, pageSize]);

  const queryString = useMemo(() => {
    const sp = new URLSearchParams(queryParams);
    return sp.toString();
  }, [queryParams]);

  const { data, isLoading, error } = useQuery({
    queryKey: queryKeys.auditLogs.list(queryParams),
    queryFn: () => apiClient<AuditLogsResponse>(`/api/v1/audit/logs?${queryString}`),
  });

  const logs = Array.isArray(data) ? data : [];
  const total = logs.length;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const updateFilter = useCallback((key: keyof Filters, value: string) => {
    setFilters((prev) => ({ ...prev, [key]: value }));
    setPage(1); // reset to first page on filter change
  }, []);

  const handlePageSizeChange = useCallback((newSize: number) => {
    setPageSize(newSize);
    setPage(1);
  }, []);

  // ── CSV Export ─────────────────────────────────────────────────────────────

  const exportCsv = useCallback(() => {
    if (logs.length === 0) return;

    const headers = [t('logs.table.timestamp'), t('logs.table.action'), t('logs.table.actorType'), t('logs.table.actorId'), t('logs.table.resourceType'), t('logs.table.resourceId'), t('logs.table.description')];
    const rows = logs.map((log) => [
      log.timestamp,
      log.actionType,
      log.actorType,
      log.actorId,
      log.resourceType,
      log.resourceId,
      `"${(log.description || '').replace(/"/g, '""')}"`,
    ]);

    const csvContent = [headers.join(','), ...rows.map((r) => r.join(','))].join('\n');
    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `audit-logs-${new Date().toISOString().slice(0, 10)}.csv`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  }, [logs, t]);

  // ── Render ─────────────────────────────────────────────────────────────────

  return (
    <div>
      <div className="flex justify-between items-center mb-6">
        <div>
          <h1 className="text-2xl font-bold">{t('logs.title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">
            {t('logs.subtitle')}
          </p>
        </div>
        <button
          onClick={exportCsv}
          disabled={logs.length === 0}
          className="px-4 py-2 border rounded-md text-sm hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {t('logs.exportCsv')}
        </button>
      </div>

      {/* Filters */}
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3 mb-4 p-4 bg-card border rounded-lg">
        <div>
          <label className="block text-xs text-muted-foreground mb-1">{t('logs.filters.dateFrom')}</label>
          <input
            type="date"
            value={filters.dateFrom}
            onChange={(e) => updateFilter('dateFrom', e.target.value)}
            className="w-full px-2 py-1.5 bg-input border rounded-md text-sm"
          />
        </div>
        <div>
          <label className="block text-xs text-muted-foreground mb-1">{t('logs.filters.dateTo')}</label>
          <input
            type="date"
            value={filters.dateTo}
            onChange={(e) => updateFilter('dateTo', e.target.value)}
            className="w-full px-2 py-1.5 bg-input border rounded-md text-sm"
          />
        </div>
        <div>
          <label className="block text-xs text-muted-foreground mb-1">{t('logs.filters.actionType')}</label>
          <select
            value={filters.actionType}
            onChange={(e) => updateFilter('actionType', e.target.value)}
            className="w-full px-2 py-1.5 bg-input border rounded-md text-sm"
          >
            {ACTION_TYPES.map((at) => (
              <option key={at} value={at}>{at || tc('all')}</option>
            ))}
          </select>
        </div>
        <div>
          <label className="block text-xs text-muted-foreground mb-1">{t('logs.filters.actorType')}</label>
          <select
            value={filters.actorType}
            onChange={(e) => updateFilter('actorType', e.target.value)}
            className="w-full px-2 py-1.5 bg-input border rounded-md text-sm"
          >
            {ACTOR_TYPES.map((at) => (
              <option key={at} value={at}>{at || tc('all')}</option>
            ))}
          </select>
        </div>
        <div>
          <label className="block text-xs text-muted-foreground mb-1">{t('logs.filters.resourceType')}</label>
          <select
            value={filters.resourceType}
            onChange={(e) => updateFilter('resourceType', e.target.value)}
            className="w-full px-2 py-1.5 bg-input border rounded-md text-sm"
          >
            {RESOURCE_TYPES.map((rt) => (
              <option key={rt} value={rt}>{rt || tc('all')}</option>
            ))}
          </select>
        </div>
      </div>

      {/* Loading / Error */}
      {isLoading && <p className="text-muted-foreground py-4">{t('logs.loading')}</p>}
      {error && <p className="text-red-500 py-4">{t('logs.loadError')} {(error as Error).message}</p>}

      {/* Table */}
      {!isLoading && !error && (
        <>
          <div className="overflow-x-auto border rounded-lg">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-muted/50 text-left">
                  <th className="py-2 px-3 font-medium w-8"></th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.timestamp')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.action')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.actorType')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.actorId')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.resourceType')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.resourceId')}</th>
                  <th className="py-2 px-3 font-medium">{t('logs.table.description')}</th>
                </tr>
              </thead>
              <tbody>
                {logs.map((log) => (
                  <LogRow
                    key={log.id}
                    log={log}
                    isExpanded={expandedId === log.id}
                    onToggle={() => setExpandedId(expandedId === log.id ? null : log.id)}
                  />
                ))}
                {logs.length === 0 && (
                  <tr>
                    <td colSpan={8} className="py-8 text-center text-muted-foreground">
                      {t('logs.empty')}
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>

          {/* Pagination */}
          <div className="flex items-center justify-between mt-4">
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <span>{t('logs.pagination.rowsPerPage')}:</span>
              <select
                value={pageSize}
                onChange={(e) => handlePageSizeChange(Number(e.target.value))}
                className="px-2 py-1 bg-input border rounded text-sm"
              >
                {PAGE_SIZE_OPTIONS.map((size) => (
                  <option key={size} value={size}>{size}</option>
                ))}
              </select>
              <span className="ml-2">
                {total > 0
                  ? `${(page - 1) * pageSize + 1}--${Math.min(page * pageSize, total)} of ${total}`
                  : tc('noResults')}
              </span>
            </div>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page <= 1}
                className="px-3 py-1.5 border rounded-md text-sm hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {t('logs.pagination.previous')}
              </button>
              <span className="text-sm text-muted-foreground">
                {t('logs.pagination.pageOf', { current: page, total: totalPages })}
              </span>
              <button
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                disabled={page >= totalPages}
                className="px-3 py-1.5 border rounded-md text-sm hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {t('logs.pagination.next')}
              </button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// ── Row Component ───────────────────────────────────────────────────────────

const ACTION_COLORS: Record<string, string> = {
  CREATE: 'bg-green-100 text-green-700',
  UPDATE: 'bg-blue-100 text-blue-700',
  DELETE: 'bg-red-100 text-red-700',
  LOGIN: 'bg-purple-100 text-purple-700',
  EXECUTE: 'bg-orange-100 text-orange-700',
  APPROVE: 'bg-emerald-100 text-emerald-700',
  REJECT: 'bg-rose-100 text-rose-700',
};

function LogRow({
  log,
  isExpanded,
  onToggle,
}: {
  log: AuditLog;
  isExpanded: boolean;
  onToggle: () => void;
}) {
  const { t } = useTranslation('audit');
  const formattedTime = useMemo(() => {
    try {
      return new Date(log.timestamp).toLocaleString();
    } catch {
      return log.timestamp;
    }
  }, [log.timestamp]);

  return (
    <>
      <tr
        onClick={onToggle}
        className={cn('border-b cursor-pointer hover:bg-accent/50 transition-colors', isExpanded && 'bg-accent/30')}
      >
        <td className="py-2 px-3 text-muted-foreground">
          <span className={cn('inline-block transition-transform text-xs', isExpanded && 'rotate-90')}>
            &#9654;
          </span>
        </td>
        <td className="py-2 px-3 text-muted-foreground whitespace-nowrap">{formattedTime}</td>
        <td className="py-2 px-3">
          <span className={cn('text-xs px-2 py-0.5 rounded-full font-medium', ACTION_COLORS[log.actionType] ?? 'bg-muted text-muted-foreground')}>
            {log.actionType}
          </span>
        </td>
        <td className="py-2 px-3 text-muted-foreground">{log.actorType}</td>
        <td className="py-2 px-3 font-mono text-xs">{log.actorId}</td>
        <td className="py-2 px-3 text-muted-foreground">{log.resourceType}</td>
        <td className="py-2 px-3 font-mono text-xs">{log.resourceId}</td>
        <td className="py-2 px-3 max-w-xs truncate">{log.description}</td>
      </tr>
      {isExpanded && (
        <tr className="border-b">
          <td colSpan={8} className="p-4 bg-muted/30">
            <p className="text-xs font-medium text-muted-foreground mb-2">{t('logs.fullDetail')}</p>
            <pre className="text-xs bg-background border rounded-md p-3 overflow-x-auto max-h-64 overflow-y-auto">
              <code>{JSON.stringify(log.detail ?? log, null, 2)}</code>
            </pre>
          </td>
        </tr>
      )}
    </>
  );
}
