/**
 * SearchPage – ricerca full-text avanzata tra tutti i messaggi PEC.
 *
 * Funzionalita':
 *  - Barra di ricerca full-text (usa FTS su search_vector PostgreSQL)
 *  - Pannello filtri avanzati collassabile:
 *    - Data da / Data a
 *    - Direzione (in arrivo / inviata)
 *    - Stato PEC
 *    - Tipo PEC
 *    - Casella specifica
 *  - Lista risultati ordinata per rilevanza
 *  - Paginazione
 */
import { useState, useEffect, useCallback } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import {
  Search,
  SlidersHorizontal,
  ChevronDown,
  ChevronUp,
  X,
  Inbox,
  Send,
  MailOpen,
  Mail,
  ChevronLeft,
  ChevronRight,
  FileText,
  Paperclip,
  AlignLeft,
} from 'lucide-react'
import { useQuery } from '@tanstack/react-query'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { PecStateBadge } from '@/components/PecBadge/PecBadge'
import { TagBadgeList } from '@/components/TagManager/TagBadge'
import { messagesApi } from '@/api/messages.api'
import { mailboxesApi } from '@/api/mailboxes.api'
import { formatRelative, truncate } from '@/lib/utils'
import { cn } from '@/lib/utils'
import type { MessageResponse } from '@/types/api.types'

// ─── Costanti ─────────────────────────────────────────────────────────────────

const PAGE_SIZE = 50

const PEC_STATES = [
  { value: '', label: 'Tutti gli stati' },
  { value: 'received', label: 'Ricevuta' },
  { value: 'sent', label: 'Inviata' },
  { value: 'accepted', label: 'Accettata' },
  { value: 'delivered', label: 'Consegnata' },
  { value: 'anomaly', label: 'Anomalia' },
  { value: 'failed', label: 'Fallita' },
]

const PEC_TYPES = [
  { value: '', label: 'Tutti i tipi' },
  { value: 'posta_certificata', label: 'Posta certificata' },
  { value: 'accettazione', label: 'Accettazione' },
  { value: 'avvenuta_consegna', label: 'Avvenuta consegna' },
  { value: 'mancata_consegna', label: 'Mancata consegna' },
  { value: 'non_accettazione', label: 'Non accettazione' },
  { value: 'presa_in_carico', label: 'Presa in carico' },
  { value: 'errore_consegna', label: 'Errore consegna' },
  { value: 'preavviso_mancata_consegna', label: 'Preavviso mancata consegna' },
  { value: 'rilevazione_virus', label: 'Rilevazione virus' },
]

const DIRECTIONS = [
  { value: '', label: 'Tutte le direzioni' },
  { value: 'inbound', label: 'In arrivo' },
  { value: 'outbound', label: 'Inviata' },
]

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

export function SearchPage() {
  const navigate = useNavigate()
  const [searchParams, setSearchParams] = useSearchParams()

  // Legge i parametri dall'URL (permette di condividere/bookmark la ricerca)
  const [searchInput, setSearchInput] = useState(searchParams.get('q') || '')
  const [committedSearch, setCommittedSearch] = useState(searchParams.get('q') || '')
  const [showFilters, setShowFilters] = useState(false)
  const [page, setPage] = useState(1)

  // Filtri avanzati
  const [dateFrom, setDateFrom] = useState(searchParams.get('date_from') || '')
  const [dateTo, setDateTo] = useState(searchParams.get('date_to') || '')
  const [direction, setDirection] = useState(searchParams.get('direction') || '')
  const [state, setState] = useState(searchParams.get('state') || '')
  const [pecType, setPecType] = useState(searchParams.get('pec_type') || '')
  const [mailboxId, setMailboxId] = useState(searchParams.get('mailbox_id') || '')

  // Caselle disponibili per il filtro
  const { data: mailboxesData } = useQuery({
    queryKey: ['mailboxes'],
    queryFn: () => mailboxesApi.list(),
    staleTime: 5 * 60 * 1000,
  })
  const mailboxes = mailboxesData?.items ?? []

  // Numero di filtri attivi
  const activeFiltersCount = [dateFrom, dateTo, direction, state, pecType, mailboxId].filter(Boolean).length

  // Sincronizza l'URL quando cambiano i filtri
  useEffect(() => {
    const params: Record<string, string> = {}
    if (committedSearch) params.q = committedSearch
    if (dateFrom) params.date_from = dateFrom
    if (dateTo) params.date_to = dateTo
    if (direction) params.direction = direction
    if (state) params.state = state
    if (pecType) params.pec_type = pecType
    if (mailboxId) params.mailbox_id = mailboxId
    setSearchParams(params, { replace: true })
  }, [committedSearch, dateFrom, dateTo, direction, state, pecType, mailboxId, setSearchParams])

  // Reset pagina quando cambiano i filtri
  useEffect(() => {
    setPage(1)
  }, [committedSearch, dateFrom, dateTo, direction, state, pecType, mailboxId])

  // Costruisce i filtri per l'API
  const filters = {
    search: committedSearch || undefined,
    date_from: dateFrom ? new Date(dateFrom).toISOString() : undefined,
    date_to: dateTo ? new Date(dateTo + 'T23:59:59').toISOString() : undefined,
    direction: direction as 'inbound' | 'outbound' | undefined || undefined,
    state: state || undefined,
    pec_type: pecType || undefined,
    mailbox_id: mailboxId || undefined,
    is_archived: undefined as boolean | undefined,
    is_trashed: false,
    page,
    page_size: PAGE_SIZE,
  }

  // Query messaggi
  const {
    data: messagesData,
    isLoading,
    isFetching,
  } = useQuery({
    queryKey: ['search', filters],
    queryFn: () => messagesApi.list(filters),
    enabled: !!(committedSearch || dateFrom || dateTo || direction || state || pecType || mailboxId),
  })

  const messages = messagesData?.items || []
  const total = messagesData?.total || 0
  const totalPages = Math.ceil(total / PAGE_SIZE)
  const hasQuery = !!(committedSearch || activeFiltersCount > 0)

  const handleSearch = useCallback(() => {
    setCommittedSearch(searchInput.trim())
    setPage(1)
  }, [searchInput])

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') handleSearch()
  }

  const handleClearAll = () => {
    setSearchInput('')
    setCommittedSearch('')
    setDateFrom('')
    setDateTo('')
    setDirection('')
    setState('')
    setPecType('')
    setMailboxId('')
    setPage(1)
  }

  const handleMessageClick = (message: MessageResponse) => {
    navigate(`/messages/${message.id}`)
  }

  return (
    <div className="flex flex-col h-full">
      {/* ── Header ricerca ── */}
      <div className="border-b bg-background px-6 py-4">
        <div className="mb-4">
          <h1 className="text-xl font-semibold flex items-center gap-2">
            <Search className="h-5 w-5 text-primary" />
            Ricerca avanzata
          </h1>
          <p className="text-sm text-muted-foreground mt-0.5">
            Ricerca full-text su oggetto, corpo del messaggio e allegati PDF/DOCX
          </p>
        </div>

        {/* Barra di ricerca principale */}
        <div className="flex gap-2 mb-3">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder='Cerca in tutti i messaggi… (es. "fattura gennaio" -spam)'
              className="pl-9 h-10 text-sm"
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              onKeyDown={handleKeyDown}
            />
            {searchInput && (
              <button
                onClick={() => { setSearchInput(''); setCommittedSearch('') }}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
              >
                <X className="h-4 w-4" />
              </button>
            )}
          </div>
          <Button onClick={handleSearch} className="h-10 px-5">
            <Search className="h-4 w-4 mr-2" />
            Cerca
          </Button>
          <Button
            variant="outline"
            className={cn('h-10', activeFiltersCount > 0 && 'border-primary text-primary')}
            onClick={() => setShowFilters(!showFilters)}
          >
            <SlidersHorizontal className="h-4 w-4 mr-2" />
            Filtri
            {activeFiltersCount > 0 && (
              <span className="ml-1.5 inline-flex items-center justify-center h-5 w-5 rounded-full bg-primary text-white text-xs font-bold">
                {activeFiltersCount}
              </span>
            )}
            {showFilters ? <ChevronUp className="h-3.5 w-3.5 ml-2" /> : <ChevronDown className="h-3.5 w-3.5 ml-2" />}
          </Button>
        </div>

        {/* Pannello filtri avanzati */}
        {showFilters && (
          <div className="bg-muted/40 rounded-lg border p-4 space-y-3">
            <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
              {/* Data da */}
              <div>
                <label className="text-xs font-medium text-muted-foreground mb-1 block">
                  Data da
                </label>
                <input
                  type="date"
                  className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                  value={dateFrom}
                  onChange={(e) => setDateFrom(e.target.value)}
                />
              </div>

              {/* Data a */}
              <div>
                <label className="text-xs font-medium text-muted-foreground mb-1 block">
                  Data a
                </label>
                <input
                  type="date"
                  className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                  value={dateTo}
                  onChange={(e) => setDateTo(e.target.value)}
                />
              </div>

              {/* Direzione */}
              <div>
                <label className="text-xs font-medium text-muted-foreground mb-1 block">
                  Direzione
                </label>
                <select
                  className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                  value={direction}
                  onChange={(e) => setDirection(e.target.value)}
                >
                  {DIRECTIONS.map((d) => (
                    <option key={d.value} value={d.value}>{d.label}</option>
                  ))}
                </select>
              </div>

              {/* Stato PEC */}
              <div>
                <label className="text-xs font-medium text-muted-foreground mb-1 block">
                  Stato PEC
                </label>
                <select
                  className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                  value={state}
                  onChange={(e) => setState(e.target.value)}
                >
                  {PEC_STATES.map((s) => (
                    <option key={s.value} value={s.value}>{s.label}</option>
                  ))}
                </select>
              </div>

              {/* Tipo PEC */}
              <div>
                <label className="text-xs font-medium text-muted-foreground mb-1 block">
                  Tipo PEC
                </label>
                <select
                  className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                  value={pecType}
                  onChange={(e) => setPecType(e.target.value)}
                >
                  {PEC_TYPES.map((t) => (
                    <option key={t.value} value={t.value}>{t.label}</option>
                  ))}
                </select>
              </div>

              {/* Casella */}
              {mailboxes.length > 0 && (
                <div>
                  <label className="text-xs font-medium text-muted-foreground mb-1 block">
                    Casella PEC
                  </label>
                  <select
                    className="w-full h-9 px-3 rounded-md border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                    value={mailboxId}
                    onChange={(e) => setMailboxId(e.target.value)}
                  >
                    <option value="">Tutte le caselle</option>
                    {mailboxes.map((m) => (
                      <option key={m.id} value={m.id}>
                        {m.display_name || m.email_address}
                      </option>
                    ))}
                  </select>
                </div>
              )}
            </div>

            {/* Pulsante reset filtri */}
            {activeFiltersCount > 0 && (
              <div className="flex justify-end">
                <Button variant="ghost" size="sm" onClick={handleClearAll} className="text-xs text-muted-foreground">
                  <X className="h-3.5 w-3.5 mr-1" />
                  Azzera tutti i filtri
                </Button>
              </div>
            )}
          </div>
        )}
      </div>

      {/* ── Risultati ── */}
      <div className="flex-1 overflow-y-auto">
        {!hasQuery ? (
          <div className="flex flex-col items-center justify-center h-64 text-center">
            <Search className="h-12 w-12 text-muted-foreground/30 mb-3" />
            <p className="text-muted-foreground font-medium">Inizia a cercare</p>
            <p className="text-sm text-muted-foreground/70 mt-1 max-w-xs">
              Digita un termine nella barra di ricerca o usa i filtri avanzati per trovare i messaggi
            </p>
          </div>
        ) : isLoading || isFetching ? (
          <div className="flex items-center justify-center h-64">
            <div className="flex flex-col items-center gap-3">
              <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
              <p className="text-sm text-muted-foreground">Ricerca in corso…</p>
            </div>
          </div>
        ) : messages.length === 0 ? (
          <div className="flex flex-col items-center justify-center h-64 text-center">
            <Search className="h-12 w-12 text-muted-foreground/30 mb-3" />
            <p className="text-muted-foreground font-medium">Nessun risultato</p>
            <p className="text-sm text-muted-foreground/70 mt-1">
              Prova a modificare i termini di ricerca o i filtri
            </p>
            {hasQuery && (
              <Button variant="ghost" size="sm" className="mt-3" onClick={handleClearAll}>
                <X className="h-3.5 w-3.5 mr-1" />
                Azzera ricerca
              </Button>
            )}
          </div>
        ) : (
          <>
            {/* Intestazione risultati */}
            <div className="px-6 py-2.5 bg-muted/20 border-b flex items-center justify-between">
              <p className="text-sm text-muted-foreground">
                <span className="font-medium text-foreground">{total}</span>{' '}
                {total === 1 ? 'risultato trovato' : 'risultati trovati'}
                {committedSearch && (
                  <> per <span className="font-medium text-foreground italic">"{committedSearch}"</span></>
                )}
              </p>
              {(isFetching) && (
                <div className="h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" />
              )}
            </div>

            {/* Lista risultati */}
            <div className="divide-y">
              {messages.map((message) => (
                <SearchResultRow
                  key={message.id}
                  message={message}
                  searchTerm={committedSearch}
                  mailboxName={
                    mailboxes.find((m) => m.id === message.mailbox_id)?.email_address
                  }
                  onClick={() => handleMessageClick(message)}
                />
              ))}
            </div>
          </>
        )}
      </div>

      {/* ── Paginazione ── */}
      {totalPages > 1 && (
        <div className="border-t px-6 py-3 flex items-center justify-between">
          <p className="text-sm text-muted-foreground">
            Pagina {page} di {totalPages} ({total} risultati)
          </p>
          <div className="flex gap-2">
            <Button
              variant="outline"
              size="sm"
              disabled={page <= 1}
              onClick={() => setPage((p) => p - 1)}
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <Button
              variant="outline"
              size="sm"
              disabled={page >= totalPages}
              onClick={() => setPage((p) => p + 1)}
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}

// ─── Riga singolo risultato ───────────────────────────────────────────────────

interface SearchResultRowProps {
  message: MessageResponse
  searchTerm: string
  mailboxName?: string
  onClick: () => void
}

function SearchResultRow({ message, searchTerm, mailboxName, onClick }: SearchResultRowProps) {
  const isUnread = !message.is_read && message.direction === 'inbound'

  // Evidenzia il termine cercato nel testo
  const highlight = (text: string | null | undefined, term: string): React.ReactNode => {
    if (!text || !term) return text || ''
    const idx = text.toLowerCase().indexOf(term.toLowerCase())
    if (idx === -1) return truncate(text, 150)
    const start = Math.max(0, idx - 60)
    const end = Math.min(text.length, idx + term.length + 90)
    const snippet = (start > 0 ? '…' : '') + text.slice(start, end) + (end < text.length ? '…' : '')
    const snipIdx = snippet.toLowerCase().indexOf(term.toLowerCase())
    if (snipIdx === -1) return snippet
    return (
      <>
        {snippet.slice(0, snipIdx)}
        <mark className="bg-yellow-200 dark:bg-yellow-800/60 rounded px-0.5 font-medium">
          {snippet.slice(snipIdx, snipIdx + term.length)}
        </mark>
        {snippet.slice(snipIdx + term.length)}
      </>
    )
  }

  return (
    <div
      className={cn(
        'flex items-start gap-3 px-6 py-3.5 cursor-pointer hover:bg-muted/50 transition-colors',
        isUnread && 'bg-blue-50/50 dark:bg-blue-950/20',
      )}
      onClick={onClick}
    >
      {/* Icona direzione */}
      <div className="flex-shrink-0 mt-0.5">
        {message.direction === 'inbound' ? (
          isUnread ? (
            <Mail className="h-5 w-5 text-blue-600" />
          ) : (
            <MailOpen className="h-5 w-5 text-muted-foreground" />
          )
        ) : (
          <Send className="h-5 w-5 text-muted-foreground" />
        )}
      </div>

      {/* Contenuto */}
      <div className="flex-1 min-w-0">
        {/* Riga 1: mittente + badge casella + stato + data */}
        <div className="flex items-center justify-between gap-2 mb-0.5">
          <div className="flex items-center gap-2 min-w-0">
            <span className={cn(
              'text-sm truncate',
              isUnread ? 'font-semibold' : 'font-medium',
            )}>
              {message.direction === 'inbound'
                ? (message.from_address || 'Mittente sconosciuto')
                : (message.to_addresses?.[0] || 'Destinatario sconosciuto')}
            </span>
            {mailboxName && (
              <span className="text-xs text-muted-foreground bg-muted px-1.5 py-0.5 rounded flex-shrink-0">
                {mailboxName}
              </span>
            )}
          </div>
          <div className="flex items-center gap-2 flex-shrink-0">
            <PecStateBadge state={message.state} />
            <span className="text-xs text-muted-foreground whitespace-nowrap">
              {formatRelative(message.received_at || message.sent_at || message.created_at)}
            </span>
          </div>
        </div>

        {/* Riga 2: oggetto */}
        <div className="flex items-center gap-1.5 mb-0.5">
          {isUnread && <span className="h-2 w-2 rounded-full bg-blue-600 flex-shrink-0" />}
          <p className={cn(
            'text-sm',
            isUnread ? 'font-medium text-foreground' : 'text-foreground',
          )}>
            {searchTerm
              ? highlight(message.subject || '(nessun oggetto)', searchTerm)
              : truncate(message.subject || '(nessun oggetto)', 100)}
          </p>
        </div>

        {/* Riga 3: snippet corpo */}
        {message.body_text && (
          <p className="text-xs text-muted-foreground line-clamp-2">
            {searchTerm ? highlight(message.body_text, searchTerm) : truncate(message.body_text, 150)}
          </p>
        )}

        {/* Riga 4: badge "Trovato in" (solo durante ricerca con match info) */}
        {searchTerm && message.search_match && (
          <div className="flex items-center flex-wrap gap-1 mt-1.5">
            <span className="text-xs text-muted-foreground mr-0.5">Trovato in:</span>
            {message.search_match.in_subject && (
              <span className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 font-medium">
                <FileText className="h-3 w-3" />
                Oggetto
              </span>
            )}
            {message.search_match.in_body && (
              <span className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300 font-medium">
                <AlignLeft className="h-3 w-3" />
                Corpo del messaggio
              </span>
            )}
            {message.search_match.in_attachments.map((att) => (
              <span
                key={att.id}
                className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300 font-medium max-w-[200px]"
                title={att.filename}
              >
                <Paperclip className="h-3 w-3 flex-shrink-0" />
                <span className="truncate">{att.filename}</span>
              </span>
            ))}
          </div>
        )}

        {/* Tag */}
        {message.labels && message.labels.length > 0 && (
          <div className="mt-1">
            <TagBadgeList labels={message.labels} maxVisible={4} size="sm" />
          </div>
        )}
      </div>

      {/* Indicatore allegati */}
      {message.has_attachments && (
        <span className="text-xs text-muted-foreground flex-shrink-0 mt-1"></span>
      )}
    </div>
  )
}
