/**
 * Pagina Audit Log – visualizzazione ed esportazione eventi di sistema.
 *
 * Accessibile solo ad admin e super_admin.
 * Mostra una tabella paginata con filtri per data, azione ed esito.
 * Permette di esportare i risultati in CSV o PDF.
 */

import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { format } from 'date-fns'
import { it } from 'date-fns/locale'
import { ShieldCheck, AlertCircle, Search, RotateCcw, Download, FileText } from 'lucide-react'
import { auditLogApi } from '@/api/audit_log.api'
import type { AuditLogParams } from '@/api/audit_log.api'
import { cn } from '@/lib/utils'
import toast from 'react-hot-toast'

// ─── Lista completa degli eventi monitorati ───────────────────────────────────

const ACTION_OPTIONS: { value: string; label: string; group: string }[] = [
  // Auth
  { value: 'auth.login', label: 'Login', group: 'Autenticazione' },
  { value: 'auth.password_changed', label: 'Cambio password', group: 'Autenticazione' },
  // Utenti
  { value: 'user.created', label: 'Utente creato', group: 'Utenti' },
  { value: 'user.updated', label: 'Utente modificato', group: 'Utenti' },
  { value: 'user.deleted', label: 'Utente eliminato', group: 'Utenti' },
  // Caselle
  { value: 'mailbox.created', label: 'Casella creata', group: 'Caselle PEC' },
  { value: 'mailbox.updated', label: 'Casella modificata', group: 'Caselle PEC' },
  { value: 'mailbox.deleted', label: 'Casella eliminata', group: 'Caselle PEC' },
  // Messaggi - invio
  { value: 'message.sent', label: 'PEC inviata', group: 'Messaggi' },
  // Messaggi - stato
  { value: 'message.read', label: 'Messaggio letto', group: 'Messaggi' },
  { value: 'message.unread', label: 'Segnato non letto', group: 'Messaggi' },
  { value: 'message.opened', label: 'Messaggio aperto', group: 'Messaggi' },
  { value: 'message.starred', label: 'Aggiunto ai preferiti', group: 'Messaggi' },
  { value: 'message.unstarred', label: 'Rimosso dai preferiti', group: 'Messaggi' },
  { value: 'message.archived', label: 'Archiviato', group: 'Messaggi' },
  { value: 'message.unarchived', label: 'Ripristinato da archivio', group: 'Messaggi' },
  { value: 'message.trashed', label: 'Spostato nel cestino', group: 'Messaggi' },
  { value: 'message.restored', label: 'Ripristinato dal cestino', group: 'Messaggi' },
  { value: 'message.bulk_updated', label: 'Aggiornamento massivo', group: 'Messaggi' },
  // Messaggi - allegati
  { value: 'message.attachment_downloaded', label: 'Allegato scaricato', group: 'Messaggi' },
  { value: 'message.package_downloaded', label: 'Pacchetto PEC scaricato', group: 'Messaggi' },
  // Conservazione
  { value: 'message.pending_conservation', label: 'Messa in conservazione', group: 'Conservazione' },
  { value: 'message.conserved', label: 'Conservata', group: 'Conservazione' },
  { value: 'message.conservation_cancelled', label: 'Conservazione annullata', group: 'Conservazione' },
  { value: 'message.conservation_removed', label: 'Rimossa dalla conservazione', group: 'Conservazione' },
]

// Raggruppamento per group
const ACTION_GROUPS = Array.from(new Set(ACTION_OPTIONS.map((o) => o.group)))

// ─── Badge esito ──────────────────────────────────────────────────────────────

function OutcomeBadge({ outcome }: { outcome: string }) {
  const isSuccess = outcome === 'success'
  return (
    <span
      className={cn(
        'inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium',
        isSuccess
          ? 'bg-green-100 text-green-800'
          : 'bg-red-100 text-red-800',
      )}
    >
      {isSuccess ? (
        <ShieldCheck className="h-3 w-3" />
      ) : (
        <AlertCircle className="h-3 w-3" />
      )}
      {isSuccess ? 'Successo' : 'Fallito'}
    </span>
  )
}

// ─── Etichetta azione leggibile ───────────────────────────────────────────────

function actionLabel(action: string): string {
  return ACTION_OPTIONS.find((o) => o.value === action)?.label ?? action
}

// ─── Helper download ─────────────────────────────────────────────────────────

function triggerDownload(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

// ─── Componente principale ────────────────────────────────────────────────────

export function AuditLogPage() {
  const [page, setPage] = useState(1)
  const PAGE_SIZE = 25

  // Filtri
  const [filterAction, setFilterAction] = useState('')
  const [filterOutcome, setFilterOutcome] = useState<'' | 'success' | 'failure'>('')
  const [filterDateFrom, setFilterDateFrom] = useState('')
  const [filterDateTo, setFilterDateTo] = useState('')

  // Parametri query attivi (applicati al click su "Cerca")
  const [activeParams, setActiveParams] = useState<AuditLogParams>({})

  // Stato export
  const [exportingCsv, setExportingCsv] = useState(false)
  const [exportingPdf, setExportingPdf] = useState(false)

  const { data, isLoading, isError } = useQuery({
    queryKey: ['audit-log', page, activeParams],
    queryFn: () =>
      auditLogApi.list({
        page,
        page_size: PAGE_SIZE,
        ...activeParams,
      }),
    staleTime: 30_000,
  })

  const handleSearch = () => {
    setPage(1)
    const params: AuditLogParams = {}
    if (filterAction) params.action = filterAction
    if (filterOutcome) params.outcome = filterOutcome
    if (filterDateFrom) params.date_from = new Date(filterDateFrom).toISOString()
    if (filterDateTo) params.date_to = new Date(filterDateTo + 'T23:59:59').toISOString()
    setActiveParams(params)
  }

  const handleReset = () => {
    setFilterAction('')
    setFilterOutcome('')
    setFilterDateFrom('')
    setFilterDateTo('')
    setActiveParams({})
    setPage(1)
  }

  const handleExport = async (format: 'csv' | 'pdf') => {
    const setter = format === 'csv' ? setExportingCsv : setExportingPdf
    setter(true)
    try {
      const blob = await auditLogApi.export(format, activeParams)
      const ext = format === 'csv' ? 'csv' : 'pdf'
      const suffix = activeParams.date_from
        ? `_dal_${activeParams.date_from.slice(0, 10).replace(/-/g, '')}`
        : ''
      triggerDownload(blob, `audit_log${suffix}.${ext}`)
    } catch {
      toast.error(`Errore durante l'esportazione ${format.toUpperCase()}`)
    } finally {
      setter(false)
    }
  }

  const items = data?.items ?? []
  const total = data?.total ?? 0
  const pages = data?.pages ?? 1

  return (
    <div className="p-6 space-y-6">
      {/* Intestazione */}
      <div>
        <h1 className="text-2xl font-bold text-gray-900">Audit Log</h1>
        <p className="text-sm text-gray-500 mt-1">
          Registro cronologico degli eventi di sistema e delle operazioni degli utenti.
        </p>
      </div>

      {/* Filtri */}
      <div className="bg-white rounded-lg border border-gray-200 p-4">
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
          {/* Azione */}
          <div>
            <label className="block text-xs font-medium text-gray-700 mb-1">Azione</label>
            <select
              value={filterAction}
              onChange={(e) => setFilterAction(e.target.value)}
              className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              <option value="">Tutte le azioni</option>
              {ACTION_GROUPS.map((group) => (
                <optgroup key={group} label={group}>
                  {ACTION_OPTIONS.filter((o) => o.group === group).map((o) => (
                    <option key={o.value} value={o.value}>
                      {o.label}
                    </option>
                  ))}
                </optgroup>
              ))}
            </select>
          </div>

          {/* Esito */}
          <div>
            <label className="block text-xs font-medium text-gray-700 mb-1">Esito</label>
            <select
              value={filterOutcome}
              onChange={(e) => setFilterOutcome(e.target.value as '' | 'success' | 'failure')}
              className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              <option value="">Tutti</option>
              <option value="success">Successo</option>
              <option value="failure">Fallito</option>
            </select>
          </div>

          {/* Data da */}
          <div>
            <label className="block text-xs font-medium text-gray-700 mb-1">Dal</label>
            <input
              type="date"
              value={filterDateFrom}
              onChange={(e) => setFilterDateFrom(e.target.value)}
              className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {/* Data a */}
          <div>
            <label className="block text-xs font-medium text-gray-700 mb-1">Al</label>
            <input
              type="date"
              value={filterDateTo}
              onChange={(e) => setFilterDateTo(e.target.value)}
              className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>
        </div>

        {/* Bottoni */}
        <div className="flex flex-wrap gap-2 mt-4">
          <button
            onClick={handleSearch}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 transition-colors"
          >
            <Search className="h-4 w-4" />
            Cerca
          </button>
          <button
            onClick={handleReset}
            className="flex items-center gap-2 px-4 py-2 border border-gray-300 text-gray-700 text-sm font-medium rounded-md hover:bg-gray-50 transition-colors"
          >
            <RotateCcw className="h-4 w-4" />
            Reimposta
          </button>

          {/* Separatore */}
          <div className="flex-1" />

          {/* Export CSV */}
          <button
            onClick={() => handleExport('csv')}
            disabled={exportingCsv}
            className="flex items-center gap-2 px-4 py-2 border border-green-600 text-green-700 text-sm font-medium rounded-md hover:bg-green-50 transition-colors disabled:opacity-50"
          >
            <Download className="h-4 w-4" />
            {exportingCsv ? 'Esportazione...' : 'Esporta CSV'}
          </button>

          {/* Export PDF */}
          <button
            onClick={() => handleExport('pdf')}
            disabled={exportingPdf}
            className="flex items-center gap-2 px-4 py-2 border border-red-600 text-red-700 text-sm font-medium rounded-md hover:bg-red-50 transition-colors disabled:opacity-50"
          >
            <FileText className="h-4 w-4" />
            {exportingPdf ? 'Esportazione...' : 'Esporta PDF'}
          </button>
        </div>
      </div>

      {/* Tabella */}
      <div className="bg-white rounded-lg border border-gray-200 overflow-hidden">
        {/* Header tabella con count */}
        <div className="px-4 py-3 border-b border-gray-200 flex items-center justify-between">
          <span className="text-sm text-gray-500">
            {isLoading ? 'Caricamento...' : `${total.toLocaleString('it-IT')} eventi trovati`}
          </span>
          {total > 0 && (
            <span className="text-sm text-gray-400">
              Pagina {page} di {pages}
            </span>
          )}
        </div>

        {/* Stato errore */}
        {isError && (
          <div className="p-8 text-center text-red-600">
            <AlertCircle className="h-8 w-8 mx-auto mb-2" />
            <p className="text-sm">Errore nel caricamento dei dati.</p>
          </div>
        )}

        {/* Stato vuoto */}
        {!isLoading && !isError && items.length === 0 && (
          <div className="p-8 text-center text-gray-500">
            <ShieldCheck className="h-8 w-8 mx-auto mb-2 text-gray-300" />
            <p className="text-sm">Nessun evento trovato.</p>
          </div>
        )}

        {/* Dati */}
        {items.length > 0 && (
          <div className="overflow-x-auto">
            <table className="min-w-full divide-y divide-gray-200">
              <thead className="bg-gray-50">
                <tr>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Data / Ora
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Azione
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Esito
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Risorsa
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    IP
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Utente
                  </th>
                </tr>
              </thead>
              <tbody className="bg-white divide-y divide-gray-100">
                {items.map((entry) => (
                  <tr key={entry.id} className="hover:bg-gray-50 transition-colors">
                    {/* Data/ora */}
                    <td className="px-4 py-3 text-sm text-gray-600 whitespace-nowrap">
                      {format(new Date(entry.occurred_at), 'dd/MM/yyyy HH:mm:ss', { locale: it })}
                    </td>

                    {/* Azione */}
                    <td className="px-4 py-3 text-sm whitespace-nowrap">
                      <span className="font-medium text-gray-900">
                        {actionLabel(entry.action)}
                      </span>
                      <span className="ml-1 text-gray-400 font-mono text-xs">
                        ({entry.action})
                      </span>
                    </td>

                    {/* Esito */}
                    <td className="px-4 py-3 whitespace-nowrap">
                      <OutcomeBadge outcome={entry.outcome} />
                    </td>

                    {/* Risorsa */}
                    <td className="px-4 py-3 text-sm text-gray-500 whitespace-nowrap">
                      {entry.resource_type ? (
                        <span>
                          {entry.resource_type}
                          {entry.resource_id && (
                            <span className="ml-1 text-gray-400 font-mono text-xs">
                              {entry.resource_id.split('-')[0]}...
                            </span>
                          )}
                        </span>
                      ) : (
                        <span className="text-gray-300">—</span>
                      )}
                    </td>

                    {/* IP */}
                    <td className="px-4 py-3 text-sm text-gray-500 whitespace-nowrap font-mono">
                      {entry.ip_address ?? <span className="text-gray-300">—</span>}
                    </td>

                    {/* Utente: mostra nome, poi email, poi UUID abbreviato */}
                    <td className="px-4 py-3 text-sm text-gray-600 whitespace-nowrap">
                      {entry.user_full_name ? (
                        <span title={entry.user_email ?? entry.user_id ?? ''}>
                          {entry.user_full_name}
                          {entry.user_email && (
                            <span className="ml-1 text-gray-400 text-xs">
                              ({entry.user_email})
                            </span>
                          )}
                        </span>
                      ) : entry.user_email ? (
                        <span title={entry.user_id ?? ''}>{entry.user_email}</span>
                      ) : entry.user_id ? (
                        <span className="font-mono text-xs text-gray-400" title={entry.user_id}>
                          {entry.user_id.split('-')[0]}...
                        </span>
                      ) : (
                        <span className="text-gray-300">—</span>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* Paginazione */}
        {pages > 1 && (
          <div className="px-4 py-3 border-t border-gray-200 flex items-center justify-between">
            <button
              disabled={page <= 1}
              onClick={() => setPage((p) => p - 1)}
              className="px-3 py-1.5 text-sm border border-gray-300 rounded-md disabled:opacity-40 hover:bg-gray-50 transition-colors"
            >
              Precedente
            </button>
            <span className="text-sm text-gray-500">
              {page} / {pages}
            </span>
            <button
              disabled={page >= pages}
              onClick={() => setPage((p) => p + 1)}
              className="px-3 py-1.5 text-sm border border-gray-300 rounded-md disabled:opacity-40 hover:bg-gray-50 transition-colors"
            >
              Successiva
            </button>
          </div>
        )}
      </div>
    </div>
  )
}
