'use client';

import { useCallback, useEffect, useState } from 'react';
import { RequireRole } from '@/lib/auth-context';
import { AuditLog, listAuditLogs } from '@/lib/services/audit';
import { listUsers, ManagedUser, ROLE_LABELS } from '@/lib/services/users';
import type { UserRole } from '@/lib/auth';
import {
  EmptyState,
  ErrorAlert,
  Loading,
  PageHeader,
  Pagination,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

export default function AuditoriaPage() {
  return (
    <RequireRole roles={['admin']}>
      <AuditView />
    </RequireRole>
  );
}

const PAGE_SIZE = 50;

const ENTITY_OPTIONS: [string, string][] = [
  ['', 'Todas as áreas'],
  ['auth', 'Acesso (login)'],
  ['patients', 'Pacientes'],
  ['appointments', 'Agenda'],
  ['treatment-plans', 'Tratamentos'],
  ['finance', 'Financeiro'],
  ['exams', 'Exames'],
  ['users', 'Usuários'],
  ['dentists', 'Dentistas'],
];

function statusClass(code: number | null): string {
  if (!code) return 'text-bg-light border';
  if (code >= 500) return 'text-bg-danger';
  if (code >= 400) return 'text-bg-warning';
  return 'text-bg-success';
}

function AuditView() {
  const [items, setItems] = useState<AuditLog[]>([]);
  const [users, setUsers] = useState<Map<number, ManagedUser>>(new Map());
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [page, setPage] = useState(1);
  const [action, setAction] = useState('');
  const [term, setTerm] = useState('');
  const [entityType, setEntityType] = useState('');
  const [userId, setUserId] = useState<number | ''>('');
  const [from, setFrom] = useState('');
  const [to, setTo] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    listUsers({ limit: 100 })
      .then((r) => setUsers(new Map(r.data.map((u) => [Number(u.id), u]))))
      .catch(() => undefined);
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await listAuditLogs({
        page,
        limit: PAGE_SIZE,
        search: term || undefined,
        entityType: entityType || undefined,
        userId: userId || undefined,
        from: from ? new Date(`${from}T00:00:00`).toISOString() : undefined,
        to: to ? new Date(`${to}T23:59:59`).toISOString() : undefined,
      });
      setItems(result.data);
      setTotal(result.total);
      setTotalPages(Math.max(result.totalPages, 1));
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, [page, term, entityType, userId, from, to]);

  useEffect(() => {
    load();
  }, [load]);

  return (
    <>
      <PageHeader
        title="Auditoria"
        subtitle="Quem fez o quê, e quando — sem conteúdo das requisições (LGPD)"
      />

      <form
        className="row g-2 mb-3"
        onSubmit={(e) => {
          e.preventDefault();
          setPage(1);
          setTerm(action.trim());
        }}
      >
        <div className="col-12 col-md-3">
          <input
            className="form-control"
            placeholder="Ação (ex.: medical_history)"
            value={action}
            onChange={(e) => setAction(e.target.value)}
            aria-label="Filtrar por ação"
          />
        </div>
        <div className="col-6 col-md-2">
          <select
            className="form-select"
            aria-label="Área"
            value={entityType}
            onChange={(e) => {
              setPage(1);
              setEntityType(e.target.value);
            }}
          >
            {ENTITY_OPTIONS.map(([value, label]) => (
              <option key={value} value={value}>
                {label}
              </option>
            ))}
          </select>
        </div>
        <div className="col-6 col-md-3">
          <select
            className="form-select"
            aria-label="Usuário"
            value={userId}
            onChange={(e) => {
              setPage(1);
              setUserId(e.target.value ? Number(e.target.value) : '');
            }}
          >
            <option value="">Todos os usuários</option>
            {[...users.values()].map((u) => (
              <option key={u.id} value={u.id}>
                {u.email}
              </option>
            ))}
          </select>
        </div>
        <div className="col-6 col-md-2">
          <input
            type="date"
            className="form-control"
            aria-label="De"
            value={from}
            onChange={(e) => {
              setPage(1);
              setFrom(e.target.value);
            }}
          />
        </div>
        <div className="col-6 col-md-2">
          <input
            type="date"
            className="form-control"
            aria-label="Até"
            value={to}
            onChange={(e) => {
              setPage(1);
              setTo(e.target.value);
            }}
          />
        </div>
      </form>

      {error && <ErrorAlert message={error} onRetry={load} />}

      {loading ? (
        <Loading />
      ) : items.length === 0 ? (
        <EmptyState icon="bi-journal-text" title="Nenhum registro encontrado" />
      ) : (
        <div className="card border-0 shadow-sm">
          <div className="table-responsive">
            <table className="table table-sm align-middle mb-0">
              <thead className="table-light">
                <tr>
                  <th scope="col">Quando</th>
                  <th scope="col">Usuário</th>
                  <th scope="col">Ação</th>
                  <th scope="col">Registro</th>
                  <th scope="col">Resultado</th>
                  <th scope="col">IP</th>
                </tr>
              </thead>
              <tbody>
                {items.map((log) => {
                  const u = log.userId ? users.get(Number(log.userId)) : undefined;
                  return (
                    <tr key={log.id}>
                      <td className="small table-nowrap">{formatDateTime(log.createdAt)}</td>
                      <td className="small">
                        {u?.email ?? (log.userId ? `#${log.userId}` : '—')}
                        {log.userRole && (
                          <span className="text-muted"> · {ROLE_LABELS[log.userRole as UserRole] ?? log.userRole}</span>
                        )}
                      </td>
                      <td>
                        <code className="small">{log.action}</code>
                        {log.metadata?.reason && (
                          <small className="d-block text-muted">{log.metadata.reason}</small>
                        )}
                      </td>
                      <td className="small">
                        {log.entityType ?? '—'}
                        {log.entityId && ` #${log.entityId}`}
                      </td>
                      <td>
                        <span className={`badge ${statusClass(log.statusCode)}`}>{log.statusCode ?? '—'}</span>
                      </td>
                      <td className="small text-muted">{log.ipAddress ?? '—'}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          <div className="card-body pt-0">
            <Pagination page={page} totalPages={totalPages} total={total} onChange={setPage} />
          </div>
        </div>
      )}
    </>
  );
}
