import { useState, useRef, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  ArrowLeft,
  Star,
  Archive,
  ArchiveX,
  Download,
  Reply,
  ReplyAll,
  Forward,
  Paperclip,
  Mail,
  Send,
  Tag,
  Tags,
  Trash2,
  RotateCcw,
  MailX,
  PackageOpen,
  Printer,
  Calendar,
  Eye,
  MessageSquare,
  X,
  ChevronDown,
  FolderOpen,
  Plus,
} from 'lucide-react'
import toast from 'react-hot-toast'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { Label } from '@/components/ui/Label'
import { PecStateBadge, PecTypeBadge } from '@/components/PecBadge/PecBadge'
import { ReceiptTree } from '@/components/ReceiptTree/ReceiptTree'
import { TagBadge } from '@/components/TagManager/TagBadge'
import { TagSelector } from '@/components/TagManager/TagSelector'
import { RiskLevelBadge, ConfidentialityBadge, RISK_LEVEL_OPTIONS, CONFIDENTIALITY_OPTIONS } from '@/components/RiskBadge/RiskBadge'
import { messagesApi } from '@/api/messages.api'
import { labelsApi } from '@/api/labels.api'
import { deadlinesApi } from '@/api/deadlines.api'
import { fascicoliApi, type FascicoloResponse } from '@/api/fascicoli.api'
import type { LabelResponse, MessageResponse } from '@/types/api.types'
import { formatDate, formatBytes } from '@/lib/utils'
import { getErrorMessage } from '@/api/client'
import apiClient from '@/api/client'
import { useComposeStore } from '@/store/compose.store'

// ─── Thread section (Feature 3) ──────────────────────────────────────────────

function ThreadSection({ messageId, currentId, navigate }: { messageId: string; currentId: string; navigate: (to: string) => void }) {
  const { data: thread = [] } = useQuery({
    queryKey: ['thread', messageId],
    queryFn: () => messagesApi.getThread(messageId),
  })

  // Mostra solo se ci sono piu' di 1 messaggio nel thread
  if (thread.length <= 1) return null

  return (
    <div className="space-y-2">
      <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
        <MessageSquare className="h-4 w-4" />
        Conversazione ({thread.length} messaggi)
      </h3>
      <div className="space-y-1.5 rounded-lg border bg-background p-3">
        {thread.map((msg) => {
          const isCurrent = msg.id === currentId
          return (
            <button
              key={msg.id}
              type="button"
              onClick={() => !isCurrent && navigate(`/messages/${msg.id}`)}
              className={`w-full flex items-center gap-3 px-3 py-2 rounded-md text-left transition-colors ${
                isCurrent
                  ? 'bg-primary/10 border border-primary/30 cursor-default'
                  : 'hover:bg-muted/60 cursor-pointer'
              }`}
            >
              <div className={`w-2 h-2 rounded-full flex-shrink-0 ${msg.direction === 'inbound' ? 'bg-blue-500' : 'bg-green-500'}`} />
              <div className="flex-1 min-w-0">
                <p className={`text-sm truncate ${isCurrent ? 'font-semibold' : 'font-medium'}`}>
                  {msg.subject || '(nessun oggetto)'}
                </p>
                <p className="text-xs text-muted-foreground">
                  {msg.direction === 'inbound' ? msg.from_address : `A: ${(msg.to_addresses || []).join(', ')}`}
                  {' · '}
                  {formatDate(msg.received_at || msg.sent_at || msg.created_at)}
                </p>
              </div>
              {isCurrent && <span className="text-xs text-primary flex-shrink-0">Questo</span>}
            </button>
          )
        })}
      </div>
    </div>
  )
}

// ─── Attachment preview modal ─────────────────────────────────────────────────

interface AttachmentPreviewProps {
  messageId: string
  attachmentId: string
  filename: string
  contentType: string
  onClose: () => void
}

function AttachmentPreviewModal({ messageId, attachmentId, filename, contentType, onClose }: AttachmentPreviewProps) {
  const isPreviewable = contentType.startsWith('image/') || contentType === 'application/pdf'

  const { data: blobUrl, isLoading, isError } = useQuery({
    queryKey: ['attachment-inline', messageId, attachmentId],
    queryFn: async () => {
      const response = await apiClient.get(
        `/messages/${messageId}/attachments/${attachmentId}/inline`,
        { responseType: 'blob' },
      )
      return window.URL.createObjectURL(new Blob([response.data], { type: contentType }))
    },
    enabled: isPreviewable,
    staleTime: 5 * 60 * 1000,
  })

  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/80">
      <div className="relative bg-background rounded-xl shadow-2xl w-full max-w-4xl max-h-[90vh] flex flex-col">
        <div className="flex items-center justify-between px-4 py-3 border-b">
          <span className="font-medium truncate">{filename}</span>
          <button onClick={onClose} className="p-1 rounded hover:bg-muted">
            <X className="h-5 w-5" />
          </button>
        </div>
        <div className="flex-1 overflow-auto p-2 min-h-[400px] flex items-center justify-center">
          {isLoading && (
            <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
          )}
          {isError && (
            <div className="text-center text-muted-foreground">
              <Eye className="h-12 w-12 mx-auto mb-3 opacity-30" />
              <p>Errore nel caricamento del file.</p>
            </div>
          )}
          {!isLoading && !isError && blobUrl && (
            <>
              {contentType.startsWith('image/') ? (
                <img src={blobUrl} alt={filename} className="max-w-full max-h-full object-contain" />
              ) : contentType === 'application/pdf' ? (
                <iframe src={blobUrl} className="w-full h-[70vh]" title={filename} />
              ) : null}
            </>
          )}
          {!isLoading && !isError && !isPreviewable && (
            <div className="text-center text-muted-foreground">
              <Eye className="h-12 w-12 mx-auto mb-3 opacity-30" />
              <p>Anteprima non disponibile per questo tipo di file.</p>
            </div>
          )}
        </div>
      </div>
    </div>
  )
}

// ─── Widget Fascicoli nel dettaglio messaggio (N1) ────────────────────────────

function FascicoliWidget({ messageId, navigate }: { messageId: string; navigate: (to: string) => void }) {
  const queryClient = useQueryClient()
  const [showAddModal, setShowAddModal] = useState(false)

  const { data: fascicoli = [] } = useQuery({
    queryKey: ['message-fascicoli', messageId],
    queryFn: () => fascicoliApi.getMessageFascicoli(messageId),
  })

  // Lista di tutti i fascicoli del tenant per il dropdown di aggiunta
  const { data: allFascicoli = [] } = useQuery({
    queryKey: ['fascicoli'],
    queryFn: () => fascicoliApi.list(),
    enabled: showAddModal,
  })

  const addMutation = useMutation({
    mutationFn: (fascicoloId: string) =>
      fascicoliApi.addMessages(fascicoloId, [messageId]),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['message-fascicoli', messageId] })
      queryClient.invalidateQueries({ queryKey: ['fascicoli'] })
      toast.success('Messaggio aggiunto al fascicolo')
      setShowAddModal(false)
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const alreadyInIds = new Set(fascicoli.map((f) => f.id))
  const available = (allFascicoli as FascicoloResponse[]).filter((f) => !alreadyInIds.has(f.id) && f.stato !== 'archiviato')

  return (
    <div className="space-y-2">
      <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
        <FolderOpen className="h-4 w-4" />
        Fascicoli ({fascicoli.length})
      </h3>
      <div className="rounded-lg border bg-background p-3">
        {fascicoli.length === 0 ? (
          <p className="text-sm text-muted-foreground">Questo messaggio non appartiene a nessun fascicolo.</p>
        ) : (
          <div className="flex flex-wrap gap-2 mb-2">
            {fascicoli.map((f) => (
              <button
                key={f.id}
                type="button"
                onClick={() => navigate(`/fascicoli/${f.id}`)}
                className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm bg-primary/10 text-primary border border-primary/20 hover:bg-primary/20 transition-colors"
              >
                <FolderOpen className="h-3.5 w-3.5" />
                {f.titolo}
                {f.numero_pratica && (
                  <span className="text-xs opacity-70">#{f.numero_pratica}</span>
                )}
              </button>
            ))}
          </div>
        )}
        <button
          type="button"
          onClick={() => setShowAddModal(true)}
          className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs text-muted-foreground border border-dashed border-muted-foreground/40 hover:border-primary hover:text-primary transition-colors"
        >
          <Plus className="h-3.5 w-3.5" />
          Aggiungi a fascicolo
        </button>
      </div>

      {/* Modal selezione fascicolo */}
      {showAddModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-background rounded-xl shadow-2xl w-full max-w-md">
            <div className="flex items-center justify-between px-5 py-4 border-b">
              <h3 className="text-base font-semibold flex items-center gap-2">
                <FolderOpen className="h-4 w-4 text-primary" />
                Aggiungi a fascicolo
              </h3>
              <button onClick={() => setShowAddModal(false)} className="p-1 rounded hover:bg-muted">
                <X className="h-4 w-4" />
              </button>
            </div>
            <div className="px-5 py-3 max-h-72 overflow-y-auto space-y-1">
              {available.length === 0 ? (
                <div className="text-center py-6 text-muted-foreground">
                  <FolderOpen className="h-8 w-8 mx-auto mb-2 opacity-20" />
                  <p className="text-sm">
                    {allFascicoli.length === 0
                      ? 'Nessun fascicolo disponibile. Creane uno dalla pagina Fascicoli.'
                      : 'Il messaggio e gia\' in tutti i fascicoli aperti.'}
                  </p>
                </div>
              ) : (
                available.map((f) => (
                  <button
                    key={f.id}
                    type="button"
                    onClick={() => addMutation.mutate(f.id)}
                    disabled={addMutation.isPending}
                    className="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-muted transition-colors text-left"
                  >
                    <FolderOpen className="h-4 w-4 text-green-600 flex-shrink-0" />
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium truncate">{f.titolo}</p>
                      {f.numero_pratica && (
                        <p className="text-xs text-muted-foreground">#{f.numero_pratica}</p>
                      )}
                    </div>
                  </button>
                ))
              )}
            </div>
            <div className="flex justify-between items-center px-5 py-3 border-t">
              <button
                type="button"
                onClick={() => navigate('/fascicoli')}
                className="text-xs text-primary hover:underline"
              >
                Gestisci fascicoli
              </button>
              <Button variant="outline" size="sm" onClick={() => setShowAddModal(false)}>
                Chiudi
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

// ─── Widget Tassonomia nel dettaglio messaggio (N2) ───────────────────────────

function TaxonomyWidget({ messageId, messageLabels }: { messageId: string; messageLabels: LabelResponse[] }) {
  const queryClient = useQueryClient()
  const [showAddModal, setShowAddModal] = useState(false)
  const [selectedLabelId, setSelectedLabelId] = useState('')

  // Lista flat di tutte le label del tenant (per costruire i percorsi)
  const { data: allLabels = [] } = useQuery({
    queryKey: ['labels'],
    queryFn: () => labelsApi.list(),
  })

  // Le label tassonomiche del messaggio sono quelle con parent_id != null
  const taxonomyLabels = messageLabels.filter((l) => l.parent_id !== null)

  // Costruisce il percorso completo di una label: "Ambito > Processo > Classificazione"
  function buildPath(labelId: string): string {
    const map = new Map<string, LabelResponse>(allLabels.map((l: LabelResponse) => [l.id, l]))
    const parts: string[] = []
    let current: LabelResponse | undefined = map.get(labelId)
    while (current) {
      parts.unshift(current.name)
      const parentId = current.parent_id
      if (parentId) {
        current = map.get(parentId)
      } else {
        break
      }
    }
    return parts.join(' > ')
  }

  // Label disponibili per l'aggiunta (non ancora assegnate)
  const alreadyAssignedIds = new Set(messageLabels.map((l) => l.id))
  const availableForAdd = allLabels.filter((l: LabelResponse) => !alreadyAssignedIds.has(l.id))

  const addMutation = useMutation({
    mutationFn: (labelId: string) =>
      labelsApi.addMessageLabels(messageId, { label_ids: [labelId] }),
    onSuccess: (updatedLabels: LabelResponse[]) => {
      queryClient.setQueryData(['message', messageId], (old: any) => {
        if (!old) return old
        return { ...old, labels: updatedLabels }
      })
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      setShowAddModal(false)
      setSelectedLabelId('')
      toast.success('Classificazione aggiunta')
    },
    onError: (e: unknown) => toast.error(getErrorMessage(e)),
  })

  const removeMutation = useMutation({
    mutationFn: (labelId: string) =>
      labelsApi.removeMessageLabels(messageId, { label_ids: [labelId] }),
    onSuccess: (updatedLabels: LabelResponse[]) => {
      queryClient.setQueryData(['message', messageId], (old: any) => {
        if (!old) return old
        return { ...old, labels: updatedLabels }
      })
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Classificazione rimossa')
    },
    onError: (e: unknown) => toast.error(getErrorMessage(e)),
  })

  return (
    <div className="space-y-2">
      <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
        <Tags className="h-4 w-4" />
        Classificazione tassonomica ({taxonomyLabels.length})
      </h3>
      <div className="rounded-lg border bg-background p-3">
        {taxonomyLabels.length === 0 ? (
          <p className="text-sm text-muted-foreground">
            Nessuna classificazione tassonomica assegnata a questo messaggio.
          </p>
        ) : (
          <div className="flex flex-wrap gap-2 mb-2">
            {taxonomyLabels.map((lbl) => {
              const path = buildPath(lbl.id)
              return (
                <span
                  key={lbl.id}
                  className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm border bg-background"
                  style={
                    lbl.color
                      ? {
                          backgroundColor: lbl.color + '20',
                          borderColor: lbl.color + '60',
                          color: lbl.color,
                        }
                      : {}
                  }
                >
                  {lbl.color && (
                    <span
                      className="h-2 w-2 rounded-full flex-shrink-0"
                      style={{ backgroundColor: lbl.color }}
                    />
                  )}
                  <span className="font-medium">{path || lbl.name}</span>
                  <button
                    type="button"
                    onClick={() => removeMutation.mutate(lbl.id)}
                    disabled={removeMutation.isPending}
                    className="ml-1 opacity-50 hover:opacity-100 transition-opacity"
                    title="Rimuovi classificazione"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </span>
              )
            })}
          </div>
        )}
        <button
          type="button"
          onClick={() => { setSelectedLabelId(''); setShowAddModal(true) }}
          className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs text-muted-foreground border border-dashed border-muted-foreground/40 hover:border-primary hover:text-primary transition-colors"
        >
          <Plus className="h-3.5 w-3.5" />
          Aggiungi classificazione
        </button>
      </div>

      {/* Modal selezione classificazione */}
      {showAddModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-background rounded-xl shadow-2xl w-full max-w-md">
            <div className="flex items-center justify-between px-5 py-4 border-b">
              <h3 className="text-base font-semibold flex items-center gap-2">
                <Tags className="h-4 w-4 text-primary" />
                Aggiungi classificazione tassonomica
              </h3>
              <button onClick={() => setShowAddModal(false)} className="p-1 rounded hover:bg-muted">
                <X className="h-4 w-4" />
              </button>
            </div>
            <div className="px-5 py-4 space-y-3">
              <p className="text-sm text-muted-foreground">
                Seleziona un nodo della tassonomia da assegnare a questo messaggio.
                Il percorso mostra: Ambito &gt; Processo &gt; Classificazione.
              </p>
              <select
                className="w-full h-9 rounded-md border border-input bg-background px-2 text-sm"
                value={selectedLabelId}
                onChange={(e) => setSelectedLabelId(e.target.value)}
              >
                <option value="">-- Seleziona classificazione --</option>
                {availableForAdd.map((l: LabelResponse) => (
                  <option key={l.id} value={l.id}>
                    {buildPath(l.id) || l.name}
                  </option>
                ))}
              </select>
            </div>
            <div className="flex justify-end gap-3 px-5 py-3 border-t">
              <Button variant="outline" size="sm" onClick={() => setShowAddModal(false)}>
                Annulla
              </Button>
              <Button
                size="sm"
                disabled={!selectedLabelId}
                isLoading={addMutation.isPending}
                onClick={() => selectedLabelId && addMutation.mutate(selectedLabelId)}
              >
                Assegna
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

// ─── Widget Rischio e Riservatezza (N3) ──────────────────────────────────────

function RiskConfidentialityWidget({
  message,
  onUpdate,
}: {
  message: MessageResponse
  onUpdate: (updated: MessageResponse) => void
}) {
  const [riskLevel, setRiskLevel] = useState<string>(message.risk_level ?? '')
  const [confidentiality, setConfidentiality] = useState<string>(message.confidentiality ?? '')
  const [isSaving, setIsSaving] = useState(false)

  // Sincronizza stato locale quando il messaggio cambia
  useEffect(() => {
    setRiskLevel(message.risk_level ?? '')
    setConfidentiality(message.confidentiality ?? '')
  }, [message.risk_level, message.confidentiality])

  const hasCurrent = message.risk_level || message.confidentiality
  const hasChanges =
    riskLevel !== (message.risk_level ?? '') ||
    confidentiality !== (message.confidentiality ?? '')

  const handleSave = async () => {
    setIsSaving(true)
    try {
      const updated = await messagesApi.update(message.id, {
        risk_level: riskLevel || '',
        confidentiality: confidentiality || '',
      })
      onUpdate(updated)
      toast.success('Rischio e riservatezza salvati')
    } catch (e) {
      toast.error(getErrorMessage(e))
    } finally {
      setIsSaving(false)
    }
  }

  return (
    <div className="space-y-2">
      <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
        <span className="inline-block h-4 w-4 text-orange-500">
          {/* icona shield */}
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round">
            <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
          </svg>
        </span>
        Rischio e Riservatezza
      </h3>
      <div className="rounded-lg border bg-background p-4 space-y-4">
        {/* Badge correnti */}
        {hasCurrent && (
          <div className="flex items-center gap-2 flex-wrap">
            {message.risk_level && (
              <RiskLevelBadge level={message.risk_level} />
            )}
            {message.confidentiality && (
              <ConfidentialityBadge level={message.confidentiality} />
            )}
          </div>
        )}

        {/* Form di modifica */}
        <div className="grid grid-cols-2 gap-3">
          <div className="space-y-1">
            <label className="text-xs font-medium text-muted-foreground">Livello di rischio</label>
            <select
              className="w-full h-9 rounded-md border border-input bg-background px-2 text-sm"
              value={riskLevel}
              onChange={(e) => setRiskLevel(e.target.value)}
            >
              <option value="">-- Nessun rischio --</option>
              {RISK_LEVEL_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>{o.label}</option>
              ))}
            </select>
          </div>
          <div className="space-y-1">
            <label className="text-xs font-medium text-muted-foreground">Riservatezza</label>
            <select
              className="w-full h-9 rounded-md border border-input bg-background px-2 text-sm"
              value={confidentiality}
              onChange={(e) => setConfidentiality(e.target.value)}
            >
              <option value="">-- Nessuna riservatezza --</option>
              {CONFIDENTIALITY_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>{o.label}</option>
              ))}
            </select>
          </div>
        </div>

        {hasChanges && (
          <div className="flex justify-end">
            <Button
              size="sm"
              isLoading={isSaving}
              onClick={handleSave}
            >
              Salva
            </Button>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Pagina principale ────────────────────────────────────────────────────────

export function MessageDetailPage() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const openCompose = useComposeStore((s) => s.openCompose)

  const [showTagSelector, setShowTagSelector] = useState(false)
  const [isDownloadingPackage, setIsDownloadingPackage] = useState(false)
  const [isPrinting, setIsPrinting] = useState(false)

  // Dropdown "Rispondi / Rispondi a tutti"
  const [showReplyDropdown, setShowReplyDropdown] = useState(false)
  const replyDropdownRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!showReplyDropdown) return
    const handler = (e: MouseEvent) => {
      if (replyDropdownRef.current && !replyDropdownRef.current.contains(e.target as Node)) {
        setShowReplyDropdown(false)
      }
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [showReplyDropdown])

  // Feature 4: Deadline
  const [showDeadlineForm, setShowDeadlineForm] = useState(false)
  const [deadlineDate, setDeadlineDate] = useState('')
  const [deadlineNote, setDeadlineNote] = useState('')

  // Feature 7: Preview allegati
  const [previewAtt, setPreviewAtt] = useState<{ id: string; filename: string; contentType: string } | null>(null)

  // Modal stampa con allegati
  const [showPrintModal, setShowPrintModal] = useState(false)
  const [printBody, setPrintBody] = useState(true)
  const [printAttIds, setPrintAttIds] = useState<Set<string>>(new Set())
  const [printModalPreviewAtt, setPrintModalPreviewAtt] = useState<{ id: string; filename: string; contentType: string } | null>(null)

  // Carica messaggio
  const {
    data: message,
    isLoading,
    error,
  } = useQuery({
    queryKey: ['message', id],
    queryFn: () => messagesApi.get(id!),
    enabled: !!id,
  })

  // Carica allegati
  const { data: attachments = [] } = useQuery({
    queryKey: ['attachments', id],
    queryFn: () => messagesApi.getAttachments(id!),
    enabled: !!id && !!message?.has_attachments,
  })

  // Carica ricevute (solo per messaggi outbound)
  const { data: receipts = [] } = useQuery({
    queryKey: ['receipts', id],
    queryFn: () => messagesApi.getReceipts(id!),
    enabled: !!id && message?.direction === 'outbound',
  })

  // Toggle stella
  const toggleStarMutation = useMutation({
    mutationFn: (starred: boolean) => messagesApi.toggleStar(id!, starred),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success(updated.is_starred ? 'Aggiunto ai preferiti' : 'Rimosso dai preferiti')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Archivia
  const archiveMutation = useMutation({
    mutationFn: () => messagesApi.archive(id!),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Messaggio archiviato')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Ripristina dall'archivio
  const unarchiveMutation = useMutation({
    mutationFn: () => messagesApi.unarchive(id!),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Messaggio ripristinato dalla posta')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Segna come da leggere
  const markUnreadMutation = useMutation({
    mutationFn: () => messagesApi.markUnread(id!),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Messaggio segnato come da leggere')
      navigate(-1)
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Sposta nel cestino
  const trashMutation = useMutation({
    mutationFn: () => messagesApi.trash(id!),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Messaggio spostato nel cestino')
      navigate(-1)
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Ripristina dal cestino
  const untrashMutation = useMutation({
    mutationFn: () => messagesApi.untrash(id!),
    onSuccess: (updated) => {
      queryClient.setQueryData(['message', id], updated)
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      toast.success('Messaggio ripristinato dal cestino')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Stampa diretta (senza modal)
  const handlePrintDirect = async () => {
    if (!message) return
    setIsPrinting(true)
    try {
      const response = await apiClient.get(`/messages/${message.id}/print`, { responseType: 'blob' })
      const html = await response.data.text()
      const w = window.open('', '_blank')
      if (w) {
        w.document.write(html)
        w.document.close()
        setTimeout(() => w.print(), 500)
      }
    } catch (e) {
      toast.error('Errore apertura stampa')
    } finally {
      setIsPrinting(false)
    }
  }

  // Stampa con selezione dal modal
  const handlePrintFromModal = async () => {
    if (!message) return
    setShowPrintModal(false)
    setIsPrinting(true)
    try {
      // 1. Stampa corpo email se selezionato
      if (printBody) {
        const response = await apiClient.get(`/messages/${message.id}/print`, { responseType: 'blob' })
        const html = await response.data.text()
        const w = window.open('', '_blank')
        if (w) {
          w.document.write(html)
          w.document.close()
          setTimeout(() => w.print(), 500)
        }
      }

      // 2. Per ogni allegato selezionato, apre in nuova finestra tramite blob URL
      const selectedAtts = attachments.filter((a) => printAttIds.has(a.id))
      for (const att of selectedAtts) {
        const isPrintable = att.content_type?.startsWith('image/') || att.content_type === 'application/pdf'
        if (!isPrintable) {
          toast(`Allegato "${att.filename}" non stampabile direttamente: scaricarlo e stamparlo manualmente.`, { icon: 'i' })
          continue
        }
        try {
          const resp = await apiClient.get(
            `/messages/${message.id}/attachments/${att.id}/inline`,
            { responseType: 'blob' },
          )
          const blobUrl = window.URL.createObjectURL(new Blob([resp.data], { type: att.content_type || 'application/octet-stream' }))
          const attWin = window.open(blobUrl, '_blank')
          if (attWin) {
            setTimeout(() => {
              try { attWin.print() } catch (_) { /* ignora */ }
              window.URL.revokeObjectURL(blobUrl)
            }, 1500)
          } else {
            window.URL.revokeObjectURL(blobUrl)
            toast.error(`Impossibile aprire "${att.filename}": controlla che i popup non siano bloccati.`)
          }
        } catch (_) {
          toast.error(`Errore apertura allegato "${att.filename}"`)
        }
      }
    } catch (e) {
      toast.error('Errore apertura stampa')
    } finally {
      setIsPrinting(false)
    }
  }

  // Download allegato autenticato
  const handleDownloadAttachment = async (att: { id: string; filename: string }) => {
    try {
      await messagesApi.downloadAttachment(message?.id ?? id!, att.id, att.filename)
    } catch (error) {
      toast.error(getErrorMessage(error))
    }
  }

  // Download pacchetto completo ZIP
  const handleDownloadPackage = async () => {
    if (!message) return
    setIsDownloadingPackage(true)
    try {
      await messagesApi.downloadPackage(message.id, message.subject)
      toast.success('Pacchetto scaricato')
    } catch (error) {
      toast.error(getErrorMessage(error))
    } finally {
      setIsDownloadingPackage(false)
    }
  }

  // Imposta tag del messaggio
  const setLabelsMutation = useMutation({
    mutationFn: (labelIds: string[]) =>
      labelsApi.setMessageLabels(id!, { label_ids: labelIds }),
    onSuccess: (updatedLabels) => {
      queryClient.setQueryData(['message', id], (old: typeof message) => {
        if (!old) return old
        return { ...old, labels: updatedLabels }
      })
      queryClient.invalidateQueries({ queryKey: ['messages'] })
      setShowTagSelector(false)
      toast.success('Tag aggiornati')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Rimuove singolo tag
  const removeLabelMutation = useMutation({
    mutationFn: (labelId: string) =>
      labelsApi.removeMessageLabels(id!, { label_ids: [labelId] }),
    onSuccess: (updatedLabels) => {
      queryClient.setQueryData(['message', id], (old: typeof message) => {
        if (!old) return old
        return { ...old, labels: updatedLabels }
      })
      queryClient.invalidateQueries({ queryKey: ['messages'] })
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    )
  }

  if (error || !message) {
    return (
      <div className="flex flex-col items-center justify-center h-64 gap-4">
        <p className="text-muted-foreground">Messaggio non trovato</p>
        <Button variant="outline" onClick={() => navigate('/inbox')}>
          <ArrowLeft className="h-4 w-4 mr-2" />
          Torna alla posta
        </Button>
      </div>
    )
  }

  const currentLabelIds = (message.labels || []).map((l) => l.id)

  return (
    <div className="flex flex-col h-full">
      {/* Toolbar */}
      <div className="border-b bg-background px-6 py-3 flex items-center justify-between">
        <div className="flex items-center gap-2">
          <Button variant="ghost" size="icon" onClick={() => navigate(-1)}>
            <ArrowLeft className="h-5 w-5" />
          </Button>
          <span className="text-sm text-muted-foreground">
            {message.direction === 'inbound' ? 'Posta in arrivo' : 'Posta inviata'}
          </span>
        </div>

        <div className="flex items-center gap-2">
          {/* Gestisci tag */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => setShowTagSelector(true)}
            title="Gestisci tag"
          >
            <Tag className="h-4 w-4 mr-1 text-primary" />
            Tag
            {message.labels && message.labels.length > 0 && (
              <span className="ml-1 text-xs bg-primary text-primary-foreground rounded-full px-1.5 py-0.5">
                {message.labels.length}
              </span>
            )}
          </Button>

          {/* Stella / Preferito */}
          <Button
            variant="ghost"
            size="icon"
            onClick={() => toggleStarMutation.mutate(!message.is_starred)}
            title={message.is_starred ? 'Rimuovi dai preferiti' : 'Aggiungi ai preferiti'}
            isLoading={toggleStarMutation.isPending}
          >
            <Star
              className={`h-5 w-5 ${message.is_starred ? 'text-yellow-500 fill-yellow-500' : 'text-muted-foreground'}`}
            />
          </Button>

          {/* Segna come da leggere (solo se gia' letto) */}
          {message.is_read && !message.is_trashed && (
            <Button
              variant="ghost"
              size="icon"
              onClick={() => markUnreadMutation.mutate()}
              title="Segna come da leggere"
              isLoading={markUnreadMutation.isPending}
            >
              <MailX className="h-5 w-5 text-muted-foreground" />
            </Button>
          )}

          {/* Archivia (se non ancora archiviato e non nel cestino) */}
          {!message.is_archived && !message.is_trashed && (
            <Button
              variant="ghost"
              size="icon"
              onClick={() => archiveMutation.mutate()}
              title="Archivia"
              isLoading={archiveMutation.isPending}
            >
              <Archive className="h-5 w-5 text-muted-foreground" />
            </Button>
          )}

          {/* Ripristina dall'archivio (se archiviato) */}
          {message.is_archived && !message.is_trashed && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => unarchiveMutation.mutate()}
              title="Ripristina dalla posta"
              isLoading={unarchiveMutation.isPending}
            >
              <ArchiveX className="h-4 w-4 mr-1" />
              Ripristina
            </Button>
          )}

          {/* Sposta nel cestino (se non gia' nel cestino) */}
          {!message.is_trashed && (
            <Button
              variant="ghost"
              size="icon"
              onClick={() => trashMutation.mutate()}
              title="Sposta nel cestino"
              isLoading={trashMutation.isPending}
            >
              <Trash2 className="h-5 w-5 text-muted-foreground" />
            </Button>
          )}

          {/* Ripristina dal cestino (se nel cestino) */}
          {message.is_trashed && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => untrashMutation.mutate()}
              title="Ripristina dal cestino"
              isLoading={untrashMutation.isPending}
            >
              <RotateCcw className="h-4 w-4 mr-1" />
              Ripristina
            </Button>
          )}

          {/* Rispondi / Rispondi a tutti (solo per messaggi inbound PEC certificata, non nel cestino) */}
          {message.direction === 'inbound' && message.pec_type === 'posta_certificata' && !message.is_trashed && (() => {
            const hasMultipleRecipients =
              (message.to_addresses?.length ?? 0) > 1 ||
              (message.cc_addresses?.length ?? 0) > 0
            return hasMultipleRecipients ? (
              /* Split button con dropdown */
              <div ref={replyDropdownRef} className="relative flex">
                {/* Parte sinistra: "Rispondi" */}
                <button
                  type="button"
                  onClick={() => { openCompose({ replyTo: message }); setShowReplyDropdown(false) }}
                  className="inline-flex items-center h-8 px-3 text-sm border border-input bg-background rounded-l-md hover:bg-muted transition-colors"
                >
                  <Reply className="h-4 w-4 mr-1" />
                  Rispondi
                </button>
                {/* Parte destra: freccia dropdown */}
                <button
                  type="button"
                  onClick={() => setShowReplyDropdown((v) => !v)}
                  className="inline-flex items-center h-8 px-1.5 text-sm border border-l-0 border-input bg-background rounded-r-md hover:bg-muted transition-colors"
                  title="Altre opzioni di risposta"
                >
                  <ChevronDown className={`h-3.5 w-3.5 text-muted-foreground transition-transform ${showReplyDropdown ? 'rotate-180' : ''}`} />
                </button>
                {/* Dropdown */}
                {showReplyDropdown && (
                  <div className="absolute right-0 top-full mt-1 z-30 min-w-[180px] rounded-md border bg-background shadow-lg overflow-hidden">
                    <button
                      type="button"
                      onClick={() => { openCompose({ replyTo: message }); setShowReplyDropdown(false) }}
                      className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted transition-colors text-left"
                    >
                      <Reply className="h-4 w-4 text-muted-foreground" />
                      Rispondi
                    </button>
                    <button
                      type="button"
                      onClick={() => { openCompose({ replyTo: message, replyAll: true }); setShowReplyDropdown(false) }}
                      className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted transition-colors text-left"
                    >
                      <ReplyAll className="h-4 w-4 text-muted-foreground" />
                      Rispondi a tutti
                    </button>
                  </div>
                )}
              </div>
            ) : (
              /* Pulsante semplice senza tendina */
              <Button
                variant="outline"
                size="sm"
                onClick={() => openCompose({ replyTo: message })}
              >
                <Reply className="h-4 w-4 mr-1" />
                Rispondi
              </Button>
            )
          })()}

          {/* Inoltra (disponibile per qualsiasi messaggio PEC certificata, non nel cestino) */}
          {message.pec_type === 'posta_certificata' && !message.is_trashed && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => openCompose({ forwardOf: message })}
            >
              <Forward className="h-4 w-4 mr-1" />
              Inoltra
            </Button>
          )}

          {/* Scarica pacchetto completo ZIP (sempre visibile) */}
          <Button
            variant="outline"
            size="sm"
            onClick={handleDownloadPackage}
            disabled={isDownloadingPackage}
            title="Scarica pacchetto completo (ZIP con tutti i file originali)"
          >
            {isDownloadingPackage ? (
              <div className="h-4 w-4 mr-1 animate-spin rounded-full border-2 border-current border-t-transparent" />
            ) : (
              <PackageOpen className="h-4 w-4 mr-1" />
            )}
            Scarica
          </Button>

          {/* Stampa (Feature 8) */}
          <Button
            variant="outline"
            size="sm"
            isLoading={isPrinting}
            onClick={() => {
              if (!message) return
              if (attachments.length > 0) {
                // Apre modal di selezione stampa
                setPrintBody(true)
                setPrintAttIds(new Set())
                setPrintModalPreviewAtt(null)
                setShowPrintModal(true)
              } else {
                // Nessun allegato: stampa direttamente come prima
                handlePrintDirect()
              }
            }}
            title="Stampa / Salva come PDF"
          >
            <Printer className="h-4 w-4 mr-1" />
            Stampa
          </Button>

          {/* Scadenza (Feature 4) */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              const dl = (message as any).deadline_at
              setDeadlineDate(dl ? dl.substring(0, 16) : '')
              setDeadlineNote((message as any).deadline_note ?? '')
              setShowDeadlineForm(true)
            }}
            title="Imposta scadenza"
            className={(message as any).deadline_at ? 'border-amber-400 text-amber-600' : ''}
          >
            <Calendar className="h-4 w-4 mr-1" />
            {(message as any).deadline_at ? 'Scadenza' : 'Scadenza'}
          </Button>
        </div>
      </div>

      {/* Banner "Nel Cestino" */}
      {message.is_trashed && (
        <div className="bg-red-50 border-b border-red-200 px-6 py-2.5 flex items-center justify-between">
          <div className="flex items-center gap-2 text-sm text-red-700">
            <Trash2 className="h-4 w-4" />
            <span>Questo messaggio si trova nel cestino.</span>
          </div>
          <Button
            variant="outline"
            size="sm"
            className="h-7 text-xs border-red-300 hover:bg-red-100 text-red-700"
            onClick={() => untrashMutation.mutate()}
            isLoading={untrashMutation.isPending}
          >
            <RotateCcw className="h-3.5 w-3.5 mr-1" />
            Ripristina
          </Button>
        </div>
      )}

      {/* Banner "Archiviato" */}
      {message.is_archived && !message.is_trashed && (
        <div className="bg-amber-50 border-b border-amber-200 px-6 py-2.5 flex items-center justify-between">
          <div className="flex items-center gap-2 text-sm text-amber-700">
            <Archive className="h-4 w-4" />
            <span>Questo messaggio si trova nell'archivio.</span>
          </div>
          <Button
            variant="outline"
            size="sm"
            className="h-7 text-xs border-amber-300 hover:bg-amber-100 text-amber-700"
            onClick={() => unarchiveMutation.mutate()}
            isLoading={unarchiveMutation.isPending}
          >
            <ArchiveX className="h-3.5 w-3.5 mr-1" />
            Ripristina nella posta
          </Button>
        </div>
      )}

      {/* Contenuto */}
      <div className="flex-1 overflow-y-auto">
        <div className="max-w-4xl mx-auto px-6 py-8 space-y-6">
          {/* Intestazione messaggio */}
          <div className="space-y-4">
            <div className="flex items-start justify-between gap-4">
              <h1 className="text-2xl font-semibold text-foreground leading-tight">
                {message.subject || '(nessun oggetto)'}
              </h1>
              <div className="flex items-center gap-2 flex-shrink-0">
                <PecStateBadge state={message.state} />
                {message.pec_type !== 'posta_certificata' && (
                  <PecTypeBadge type={message.pec_type} />
                )}
              </div>
            </div>

            {/* Tag badges */}
            {message.labels && message.labels.length > 0 && (
              <div className="flex items-center gap-2 flex-wrap">
                {message.labels.map((label) => (
                  <TagBadge
                    key={label.id}
                    label={label}
                    size="md"
                    onRemove={() => removeLabelMutation.mutate(label.id)}
                  />
                ))}
                <button
                  type="button"
                  onClick={() => setShowTagSelector(true)}
                  className="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-sm text-muted-foreground border border-dashed border-muted-foreground/40 hover:border-primary hover:text-primary transition-colors"
                >
                  <Tag className="h-3.5 w-3.5" />
                  Modifica
                </button>
              </div>
            )}

            {/* Dettagli busta */}
            <div className="rounded-lg border bg-muted/30 p-4 space-y-2">
              <div className="grid grid-cols-[auto,1fr] gap-x-4 gap-y-1.5 text-sm">
                <span className="font-medium text-muted-foreground">
                  {message.direction === 'inbound' ? 'Da:' : 'A:'}
                </span>
                <span className="text-foreground font-medium">
                  {message.direction === 'inbound'
                    ? message.from_address
                    : message.to_addresses?.join(', ')}
                </span>

                {message.direction === 'outbound' && message.from_address && (
                  <>
                    <span className="font-medium text-muted-foreground">Da:</span>
                    <span>{message.from_address}</span>
                  </>
                )}

                {message.direction === 'inbound' && message.to_addresses?.length > 0 && (
                  <>
                    <span className="font-medium text-muted-foreground">A:</span>
                    <span>{message.to_addresses.join(', ')}</span>
                  </>
                )}

                {message.cc_addresses?.length > 0 && (
                  <>
                    <span className="font-medium text-muted-foreground">Cc:</span>
                    <span>{message.cc_addresses.join(', ')}</span>
                  </>
                )}

                <span className="font-medium text-muted-foreground">Data:</span>
                <span>{formatDate(message.received_at || message.sent_at || message.created_at)}</span>

                {message.size_bytes && (
                  <>
                    <span className="font-medium text-muted-foreground">Dimensione:</span>
                    <span>{formatBytes(message.size_bytes)}</span>
                  </>
                )}

                <span className="font-medium text-muted-foreground">Cartella:</span>
                <span className="font-mono text-xs">{message.imap_folder}</span>
              </div>
            </div>
          </div>

          {/* Corpo del messaggio */}
          {(message.body_html || message.body_text) && (
            <div className="space-y-2">
              <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">
                Contenuto
              </h3>
              <div className="rounded-lg border bg-background p-6">
                {message.body_html ? (
                  <div
                    className="prose prose-sm max-w-none"
                    dangerouslySetInnerHTML={{ __html: message.body_html }}
                  />
                ) : (
                  <pre className="whitespace-pre-wrap text-sm font-sans text-foreground">
                    {message.body_text}
                  </pre>
                )}
              </div>
            </div>
          )}

          {/* Allegati */}
          {attachments.length > 0 && (
            <div className="space-y-2">
              <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
                <Paperclip className="h-4 w-4" />
                Allegati ({attachments.length})
              </h3>
              <div className="grid gap-2 sm:grid-cols-2">
                {attachments.map((att) => {
                  const isPreviewable = att.content_type?.startsWith('image/') || att.content_type === 'application/pdf'
                  return (
                    <div key={att.id} className="flex items-center gap-2 rounded-lg border bg-background p-3">
                      <button
                        type="button"
                        onClick={() => handleDownloadAttachment(att)}
                        className="flex items-center gap-3 flex-1 min-w-0 text-left hover:opacity-80"
                      >
                        <div className="h-10 w-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0">
                          <Paperclip className="h-5 w-5 text-primary" />
                        </div>
                        <div className="flex-1 min-w-0">
                          <p className="text-sm font-medium truncate">{att.filename}</p>
                          <p className="text-xs text-muted-foreground">
                            {att.content_type || 'Tipo sconosciuto'} • {formatBytes(att.size_bytes)}
                          </p>
                        </div>
                        <Download className="h-4 w-4 text-muted-foreground flex-shrink-0" />
                      </button>
                      {isPreviewable && (
                        <button
                          type="button"
                          onClick={() => setPreviewAtt({ id: att.id, filename: att.filename, contentType: att.content_type || '' })}
                          className="p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-primary flex-shrink-0"
                          title="Anteprima"
                        >
                          <Eye className="h-4 w-4" />
                        </button>
                      )}
                    </div>
                  )
                })}
              </div>
            </div>
          )}

          {/* Ricevute (solo per outbound) */}
          {message.direction === 'outbound' && (
            <div className="space-y-2">
              <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
                <Send className="h-4 w-4" />
                Tracciamento invio
              </h3>
              <div className="rounded-lg border bg-background p-4">
                <ReceiptTree message={message} receipts={receipts} />
              </div>
            </div>
          )}

          {/* Scadenza (Feature 4) */}
          {(message as any).deadline_at && (
            <div className="rounded-lg border border-amber-200 bg-amber-50 p-4">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2 text-sm text-amber-700">
                  <Calendar className="h-4 w-4" />
                  <span>
                    <strong>Scadenza:</strong> {formatDate((message as any).deadline_at)}
                  </span>
                  {(message as any).deadline_note && (
                    <span className="text-amber-600 italic">— {(message as any).deadline_note}</span>
                  )}
                </div>
                <button
                  onClick={() => {
                    setDeadlineDate('')
                    setDeadlineNote('')
                    deadlinesApi.setDeadline(message.id, { deadline_at: null }).then(() => {
                      queryClient.invalidateQueries({ queryKey: ['message', id] })
                      toast.success('Scadenza rimossa')
                    })
                  }}
                  className="text-xs text-amber-600 hover:text-amber-800"
                >
                  Rimuovi
                </button>
              </div>
            </div>
          )}

          {/* Thread (Feature 3) */}
          {message.pec_type === 'posta_certificata' && (
            <ThreadSection messageId={message.id} currentId={message.id} navigate={navigate} />
          )}

          {/* Fascicoli (N1) */}
          <FascicoliWidget messageId={message.id} navigate={navigate} />

          {/* Classificazione Tassonomica (N2) */}
          <TaxonomyWidget messageId={message.id} messageLabels={message.labels || []} />

          {/* Rischio e Riservatezza (N3) */}
          <RiskConfidentialityWidget message={message} onUpdate={(updated) => {
            queryClient.setQueryData(['message', id], updated)
            queryClient.invalidateQueries({ queryKey: ['messages'] })
          }} />

          {/* Messaggio originale per ricevute */}
          {message.direction === 'inbound' && message.pec_type !== 'posta_certificata' && (
            <div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
              <div className="flex items-center gap-2 text-sm text-blue-700">
                <Mail className="h-4 w-4" />
                <span>
                  Questo e un messaggio automatico di tipo{' '}
                  <strong>
                    <PecTypeBadge type={message.pec_type} />
                  </strong>
                </span>
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Modali */}

      {/* Deadline form (Feature 4) */}
      {showDeadlineForm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-background rounded-xl shadow-2xl p-6 w-96 space-y-4">
            <h3 className="text-lg font-semibold flex items-center gap-2">
              <Calendar className="h-5 w-5 text-amber-500" />
              Imposta scadenza
            </h3>
            <div className="space-y-2">
              <Label>Data e ora scadenza</Label>
              <Input
                type="datetime-local"
                value={deadlineDate}
                onChange={e => setDeadlineDate(e.target.value)}
              />
            </div>
            <div className="space-y-2">
              <Label>Nota (opzionale)</Label>
              <Input
                value={deadlineNote}
                onChange={e => setDeadlineNote(e.target.value)}
                placeholder="Es. Termine per impugnare, entro 30 giorni..."
              />
            </div>
            <div className="flex justify-end gap-3 pt-2">
              <Button variant="outline" onClick={() => setShowDeadlineForm(false)}>Annulla</Button>
              <Button
                onClick={async () => {
                  await deadlinesApi.setDeadline(message.id, {
                    deadline_at: deadlineDate ? new Date(deadlineDate).toISOString() : null,
                    deadline_note: deadlineNote || null,
                  })
                  queryClient.invalidateQueries({ queryKey: ['message', id] })
                  toast.success(deadlineDate ? 'Scadenza impostata' : 'Scadenza rimossa')
                  setShowDeadlineForm(false)
                }}
              >
                Salva
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* Attachment preview (Feature 7) */}
      {previewAtt && (
        <AttachmentPreviewModal
          messageId={message.id}
          attachmentId={previewAtt.id}
          filename={previewAtt.filename}
          contentType={previewAtt.contentType}
          onClose={() => setPreviewAtt(null)}
        />
      )}

      {/* Modal stampa con selezione allegati */}
      {showPrintModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-background rounded-xl shadow-2xl w-full max-w-lg">
            {/* Header */}
            <div className="flex items-center justify-between px-5 py-4 border-b">
              <h3 className="text-lg font-semibold flex items-center gap-2">
                <Printer className="h-5 w-5 text-primary" />
                Stampa messaggio
              </h3>
              <button
                onClick={() => setShowPrintModal(false)}
                className="p-1 rounded hover:bg-muted"
              >
                <X className="h-5 w-5" />
              </button>
            </div>

            {/* Body */}
            <div className="px-5 py-4 space-y-4">
              <p className="text-sm text-muted-foreground">Seleziona cosa includere nella stampa:</p>

              {/* Checkbox corpo email */}
              <label className="flex items-center gap-3 cursor-pointer group">
                <input
                  type="checkbox"
                  checked={printBody}
                  onChange={(e) => setPrintBody(e.target.checked)}
                  className="h-4 w-4 rounded border-gray-300 accent-primary"
                />
                <div className="flex-1">
                  <span className="text-sm font-medium">Corpo della email</span>
                  <p className="text-xs text-muted-foreground">Intestazione, mittente, destinatari e testo del messaggio</p>
                </div>
              </label>

              {/* Separatore */}
              <div className="border-t pt-3 space-y-1">
                <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-1.5">
                  <Paperclip className="h-3.5 w-3.5" />
                  Allegati ({attachments.length})
                </p>
                <div className="space-y-2 mt-2 max-h-60 overflow-y-auto pr-1">
                  {attachments.map((att) => {
                    const isPreviewable = att.content_type?.startsWith('image/') || att.content_type === 'application/pdf'
                    const isPrintable = isPreviewable
                    return (
                      <div
                        key={att.id}
                        className="flex items-center gap-3 rounded-lg border bg-muted/30 px-3 py-2"
                      >
                        <input
                          type="checkbox"
                          checked={printAttIds.has(att.id)}
                          onChange={(e) => {
                            setPrintAttIds((prev) => {
                              const next = new Set(prev)
                              if (e.target.checked) next.add(att.id)
                              else next.delete(att.id)
                              return next
                            })
                          }}
                          className="h-4 w-4 rounded border-gray-300 accent-primary flex-shrink-0"
                        />
                        <div className="flex-1 min-w-0">
                          <p className="text-sm font-medium truncate">{att.filename}</p>
                          <p className="text-xs text-muted-foreground">
                            {att.content_type || 'Tipo sconosciuto'} &bull; {formatBytes(att.size_bytes)}
                            {!isPrintable && (
                              <span className="ml-1.5 text-amber-600">(stampa non diretta)</span>
                            )}
                          </p>
                        </div>
                        {/* Pulsante anteprima all'interno del modal */}
                        {isPreviewable && (
                          <button
                            type="button"
                            onClick={() => setPrintModalPreviewAtt({ id: att.id, filename: att.filename, contentType: att.content_type || '' })}
                            className="p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-primary flex-shrink-0"
                            title="Visualizza allegato"
                          >
                            <Eye className="h-4 w-4" />
                          </button>
                        )}
                      </div>
                    )
                  })}
                </div>
              </div>

              {/* Nota per allegati non stampabili */}
              {attachments.some((a) => !a.content_type?.startsWith('image/') && a.content_type !== 'application/pdf') && (
                <p className="text-xs text-amber-700 bg-amber-50 border border-amber-200 rounded-md px-3 py-2">
                  Gli allegati contrassegnati con "stampa non diretta" (es. .eml, .xml) non possono essere aperti direttamente dal browser. Scaricali e stampali manualmente.
                </p>
              )}
            </div>

            {/* Footer */}
            <div className="flex justify-end gap-3 px-5 py-4 border-t">
              <Button variant="outline" onClick={() => setShowPrintModal(false)}>
                Annulla
              </Button>
              <Button
                onClick={handlePrintFromModal}
                disabled={!printBody && printAttIds.size === 0}
              >
                <Printer className="h-4 w-4 mr-1" />
                Stampa
              </Button>
            </div>
          </div>

          {/* Anteprima allegato aperta dall'interno del modal (z-index superiore) */}
          {printModalPreviewAtt && (
            <AttachmentPreviewModal
              messageId={message.id}
              attachmentId={printModalPreviewAtt.id}
              filename={printModalPreviewAtt.filename}
              contentType={printModalPreviewAtt.contentType}
              onClose={() => setPrintModalPreviewAtt(null)}
            />
          )}
        </div>
      )}

      {/* Dialog gestione tag */}
      {showTagSelector && (
        <TagSelector
          mode="single"
          open={showTagSelector}
          onClose={() => setShowTagSelector(false)}
          currentLabelIds={currentLabelIds}
          onApply={(labelIds) => setLabelsMutation.mutate(labelIds)}
          isApplying={setLabelsMutation.isPending}
        />
      )}
    </div>
  )
}
