import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Plus, Trash2, CheckCircle, XCircle, Settings2, ChevronDown, ChevronUp } 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 { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/Dialog'
import { routingRulesApi, type RoutingRuleResponse, type RoutingRuleCreate, type ConditionField, type ConditionOperator, type ActionType } from '@/api/routing_rules.api'
import { labelsApi } from '@/api/labels.api'
import type { LabelResponse, LabelTreeResponse } from '@/types/api.types'
import { RISK_LEVEL_OPTIONS, CONFIDENTIALITY_OPTIONS } from '@/components/RiskBadge/RiskBadge'
import { getErrorMessage } from '@/api/client'
import { formatDate } from '@/lib/utils'
import { cn } from '@/lib/utils'

const FIELD_LABELS: Record<ConditionField, string> = {
  from_address: 'Mittente',
  to_address: 'Destinatario',
  subject: 'Oggetto',
  mailbox_id: 'ID Casella',
  pec_type: 'Tipo PEC',
  has_label: 'Ha etichetta/classificazione',
  // Rischio e Riservatezza (N3)
  risk_level: 'Livello di rischio',
  confidentiality: 'Riservatezza',
}

const OPERATOR_LABELS: Record<ConditionOperator, string> = {
  contains: 'contiene',
  not_contains: 'non contiene',
  equals: 'uguale a',
  starts_with: 'inizia per',
  ends_with: 'finisce per',
  regex: 'regex',
}

const ACTION_LABELS: Record<ActionType, string> = {
  apply_label: 'Applica etichetta',
  assign_vbox: 'Assegna Virtual Box',
  mark_read: 'Segna come letto',
  mark_starred: 'Aggiungi ai preferiti',
  notify_webhook: 'Notifica webhook',
  apply_taxonomy: 'Applica classificazione tassonomica',
  // Rischio e Riservatezza (N3)
  set_risk_level: 'Imposta livello di rischio',
  set_confidentiality: 'Imposta riservatezza',
}

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

interface Condition {
  field: ConditionField
  operator: ConditionOperator
  value: string
}

interface Action {
  action_type: ActionType
  action_value: string
}

export function RoutingRulesPage() {
  const queryClient = useQueryClient()
  const [showForm, setShowForm] = useState(false)
  const [editing, setEditing] = useState<RoutingRuleResponse | null>(null)
  const [expandedRules, setExpandedRules] = useState<Set<string>>(new Set())

  // Form state
  const [formName, setFormName] = useState('')
  const [formDescription, setFormDescription] = useState('')
  const [formPriority, setFormPriority] = useState('100')
  const [formStopProcessing, setFormStopProcessing] = useState(true)
  const [formConditions, setFormConditions] = useState<Condition[]>([
    { field: 'from_address', operator: 'contains', value: '' }
  ])
  const [formActions, setFormActions] = useState<Action[]>([
    { action_type: 'mark_read', action_value: '' }
  ])

  const { data, isLoading } = useQuery({
    queryKey: ['routing-rules'],
    queryFn: () => routingRulesApi.list(),
  })

  const { data: labelsData } = useQuery({
    queryKey: ['labels'],
    queryFn: () => labelsApi.list(),
  })
  const labels = labelsData ?? []

  const createMutation = useMutation({
    mutationFn: (d: RoutingRuleCreate) => routingRulesApi.create(d),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['routing-rules'] })
      toast.success('Regola creata')
      closeForm()
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: RoutingRuleCreate }) =>
      routingRulesApi.update(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['routing-rules'] })
      toast.success('Regola aggiornata')
      closeForm()
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const deleteMutation = useMutation({
    mutationFn: (id: string) => routingRulesApi.delete(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['routing-rules'] })
      toast.success('Regola eliminata')
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const toggleMutation = useMutation({
    mutationFn: (id: string) => routingRulesApi.toggle(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['routing-rules'] }),
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const openCreate = () => {
    setEditing(null)
    setFormName('')
    setFormDescription('')
    setFormPriority('100')
    setFormStopProcessing(true)
    setFormConditions([{ field: 'from_address', operator: 'contains', value: '' }])
    setFormActions([{ action_type: 'mark_read', action_value: '' }])
    setShowForm(true)
  }

  const openEdit = (r: RoutingRuleResponse) => {
    setEditing(r)
    setFormName(r.name)
    setFormDescription(r.description ?? '')
    setFormPriority(String(r.priority))
    setFormStopProcessing(r.stop_processing)
    setFormConditions(r.conditions.map(c => ({ field: c.field as ConditionField, operator: c.operator as ConditionOperator, value: c.value })))
    setFormActions(r.actions.map(a => ({ action_type: a.action_type as ActionType, action_value: a.action_value ?? '' })))
    setShowForm(true)
  }

  const closeForm = () => {
    setShowForm(false)
    setEditing(null)
  }

  const handleSubmit = () => {
    if (!formName.trim()) return toast.error('Il nome e\' obbligatorio')
    if (formConditions.some(c => !c.value.trim())) return toast.error('Tutte le condizioni devono avere un valore')

    const payload: RoutingRuleCreate = {
      name: formName.trim(),
      description: formDescription.trim() || null,
      priority: parseInt(formPriority) || 100,
      stop_processing: formStopProcessing,
      is_active: true,
      conditions: formConditions.map(c => ({ field: c.field, operator: c.operator, value: c.value.trim() })),
      actions: formActions.map(a => ({ action_type: a.action_type, action_value: a.action_value.trim() || null })),
    }
    if (editing) {
      updateMutation.mutate({ id: editing.id, data: payload })
    } else {
      createMutation.mutate(payload)
    }
  }

  const items = data?.items ?? []

  const toggleExpand = (id: string) => {
    setExpandedRules(prev => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  return (
    <div className="flex flex-col h-full">
      <div className="border-b bg-background px-6 py-4 flex items-center justify-between">
        <div>
          <h1 className="text-xl font-semibold flex items-center gap-2">
            <Settings2 className="h-5 w-5 text-primary" />
            Regole di smistamento
          </h1>
          <p className="text-sm text-muted-foreground">
            Applica automaticamente etichette e azioni ai messaggi in arrivo
          </p>
        </div>
        <Button onClick={openCreate}>
          <Plus className="h-4 w-4 mr-2" />
          Nuova regola
        </Button>
      </div>

      <div className="flex-1 overflow-y-auto p-6 space-y-3">
        {isLoading ? (
          <div className="flex justify-center py-12">
            <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
          </div>
        ) : items.length === 0 ? (
          <div className="text-center py-12 text-muted-foreground">
            <Settings2 className="h-12 w-12 mx-auto mb-4 opacity-30" />
            <p className="text-lg font-medium">Nessuna regola configurata</p>
            <p className="text-sm mt-1">Le regole vengono valutate in ordine di priorita' su ogni messaggio inbound.</p>
          </div>
        ) : (
          items.map((rule) => (
            <div key={rule.id} className={cn('rounded-lg border bg-card', !rule.is_active && 'opacity-60')}>
              <div className="flex items-center gap-3 px-4 py-3">
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2">
                    <span className="font-medium">{rule.name}</span>
                    <span className="text-xs text-muted-foreground">P:{rule.priority}</span>
                    <span className={cn('text-xs px-2 py-0.5 rounded-full', rule.is_active ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600')}>
                      {rule.is_active ? 'Attiva' : 'Inattiva'}
                    </span>
                    {rule.stop_processing && (
                      <span className="text-xs px-2 py-0.5 rounded-full bg-amber-100 text-amber-700">Stop</span>
                    )}
                  </div>
                  {rule.description && <p className="text-xs text-muted-foreground mt-0.5">{rule.description}</p>}
                  <p className="text-xs text-muted-foreground mt-0.5">
                    {rule.conditions.length} condizioni / {rule.actions.length} azioni
                  </p>
                </div>
                <div className="flex items-center gap-1">
                  <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => openEdit(rule)} title="Modifica">
                    <Settings2 className="h-4 w-4" />
                  </Button>
                  <Button
                    variant="ghost" size="icon" className="h-8 w-8"
                    onClick={() => toggleMutation.mutate(rule.id)}
                    title={rule.is_active ? 'Disattiva' : 'Attiva'}
                  >
                    {rule.is_active
                      ? <XCircle className="h-4 w-4 text-amber-500" />
                      : <CheckCircle className="h-4 w-4 text-green-500" />
                    }
                  </Button>
                  <Button
                    variant="ghost" size="icon" className="h-8 w-8"
                    onClick={() => { if (confirm(`Eliminare la regola "${rule.name}"?`)) deleteMutation.mutate(rule.id) }}
                    title="Elimina"
                  >
                    <Trash2 className="h-4 w-4 text-destructive" />
                  </Button>
                  <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => toggleExpand(rule.id)}>
                    {expandedRules.has(rule.id) ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
                  </Button>
                </div>
              </div>
              {expandedRules.has(rule.id) && (
                <div className="border-t px-4 py-3 space-y-3">
                  <div>
                    <p className="text-xs font-semibold text-muted-foreground uppercase mb-2">Condizioni (AND)</p>
                    {rule.conditions.map((c, i) => (
                      <div key={i} className="flex items-center gap-2 text-xs bg-muted/40 rounded px-3 py-1.5 mb-1">
                        <span className="font-medium">{FIELD_LABELS[c.field as ConditionField] ?? c.field}</span>
                        <span className="text-muted-foreground">{OPERATOR_LABELS[c.operator as ConditionOperator] ?? c.operator}</span>
                        <span className="font-mono bg-background border rounded px-1.5 py-0.5">{c.value}</span>
                      </div>
                    ))}
                  </div>
                  <div>
                    <p className="text-xs font-semibold text-muted-foreground uppercase mb-2">Azioni</p>
                    {rule.actions.map((a, i) => (
                      <div key={i} className="flex items-center gap-2 text-xs bg-blue-50 rounded px-3 py-1.5 mb-1">
                        <span className="font-medium text-blue-700">{ACTION_LABELS[a.action_type as ActionType] ?? a.action_type}</span>
                        {a.action_value && <span className="font-mono text-blue-600">{a.action_value}</span>}
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          ))
        )}
      </div>

      <Dialog open={showForm} onOpenChange={(o) => !o && closeForm()}>
        <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editing ? 'Modifica regola' : 'Nuova regola di smistamento'}</DialogTitle>
          </DialogHeader>

          <div className="space-y-5 mt-4">
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2 col-span-2">
                <Label>Nome *</Label>
                <Input value={formName} onChange={e => setFormName(e.target.value)} placeholder="Es. Multe comune Roma" />
              </div>
              <div className="space-y-2">
                <Label>Priorita' (1=alta, 999=bassa)</Label>
                <Input type="number" value={formPriority} onChange={e => setFormPriority(e.target.value)} min={1} max={999} />
              </div>
              <div className="space-y-2">
                <Label>Descrizione</Label>
                <Input value={formDescription} onChange={e => setFormDescription(e.target.value)} placeholder="Descrizione opzionale" />
              </div>
            </div>

            <label className="flex items-center gap-2 cursor-pointer">
              <input type="checkbox" checked={formStopProcessing} onChange={e => setFormStopProcessing(e.target.checked)} className="rounded" />
              <span className="text-sm">Interrompi elaborazione dopo questa regola (stop processing)</span>
            </label>

            {/* Condizioni */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label>Condizioni (tutte devono essere soddisfatte - AND)</Label>
                <Button type="button" variant="outline" size="sm" onClick={() => setFormConditions(prev => [...prev, { field: 'from_address', operator: 'contains', value: '' }])}>
                  <Plus className="h-3.5 w-3.5 mr-1" />Aggiungi
                </Button>
              </div>
              {formConditions.map((cond, i) => (
                <div key={i} className="flex items-center gap-2 p-3 border rounded-lg bg-muted/20">
                  <select
                    className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                    value={cond.field}
                    onChange={e => setFormConditions(prev => prev.map((c, idx) => idx === i ? { ...c, field: e.target.value as ConditionField } : c))}
                  >
                    {(Object.entries(FIELD_LABELS) as [ConditionField, string][]).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                  </select>
                  <select
                    className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                    value={cond.operator}
                    onChange={e => setFormConditions(prev => prev.map((c, idx) => idx === i ? { ...c, operator: e.target.value as ConditionOperator } : c))}
                  >
                    {(Object.entries(OPERATOR_LABELS) as [ConditionOperator, string][]).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                  </select>
                  {cond.field === 'has_label' ? (
                    <select
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                      value={cond.value}
                      onChange={e => setFormConditions(prev => prev.map((c, idx) => idx === i ? { ...c, value: e.target.value } : c))}
                    >
                      <option value="">-- Seleziona etichetta --</option>
                      {labels.map(l => (
                        <option key={l.id} value={l.id}>
                          {buildLabelPath(l.id, labels) || l.name}
                        </option>
                      ))}
                    </select>
                  ) : (
                    <Input
                      className="flex-1"
                      value={cond.value}
                      onChange={e => setFormConditions(prev => prev.map((c, idx) => idx === i ? { ...c, value: e.target.value } : c))}
                      placeholder="Valore..."
                    />
                  )}
                  <button type="button" onClick={() => setFormConditions(prev => prev.filter((_, idx) => idx !== i))} className="p-1 text-destructive hover:bg-destructive/10 rounded">
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>
              ))}
            </div>

            {/* Azioni */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label>Azioni da eseguire</Label>
                <Button type="button" variant="outline" size="sm" onClick={() => setFormActions(prev => [...prev, { action_type: 'mark_read', action_value: '' }])}>
                  <Plus className="h-3.5 w-3.5 mr-1" />Aggiungi
                </Button>
              </div>
              {formActions.map((action, i) => (
                <div key={i} className="flex items-center gap-2 p-3 border rounded-lg bg-blue-50">
                  <select
                    className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                    value={action.action_type}
                    onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_type: e.target.value as ActionType, action_value: '' } : a))}
                  >
                    {(Object.entries(ACTION_LABELS) as [ActionType, string][]).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                  </select>
                  {(action.action_type === 'apply_label') && (
                    <select
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                      value={action.action_value}
                      onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_value: e.target.value } : a))}
                    >
                      <option value="">-- Seleziona etichetta --</option>
                      {labels.map((l: LabelResponse) => <option key={l.id} value={l.id}>{l.name}</option>)}
                    </select>
                  )}
                  {(action.action_type === 'apply_taxonomy') && (
                    <select
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                      value={action.action_value}
                      onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_value: e.target.value } : a))}
                    >
                      <option value="">-- Seleziona classificazione --</option>
                      {labels.map((l: LabelResponse) => (
                        <option key={l.id} value={l.id}>
                          {buildLabelPath(l.id, labels) || l.name}
                        </option>
                      ))}
                    </select>
                  )}
                  {(action.action_type === 'notify_webhook') && (
                    <Input
                      className="flex-1"
                      value={action.action_value}
                      onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_value: e.target.value } : a))}
                      placeholder="https://..."
                    />
                  )}
                  {/* Rischio e Riservatezza (N3) */}
                  {(action.action_type === 'set_risk_level') && (
                    <select
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                      value={action.action_value}
                      onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_value: e.target.value } : a))}
                    >
                      <option value="">-- Seleziona livello --</option>
                      {RISK_LEVEL_OPTIONS.map((o) => (
                        <option key={o.value} value={o.value}>{o.label}</option>
                      ))}
                    </select>
                  )}
                  {(action.action_type === 'set_confidentiality') && (
                    <select
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm flex-1"
                      value={action.action_value}
                      onChange={e => setFormActions(prev => prev.map((a, idx) => idx === i ? { ...a, action_value: e.target.value } : a))}
                    >
                      <option value="">-- Seleziona riservatezza --</option>
                      {CONFIDENTIALITY_OPTIONS.map((o) => (
                        <option key={o.value} value={o.value}>{o.label}</option>
                      ))}
                    </select>
                  )}
                  <button type="button" onClick={() => setFormActions(prev => prev.filter((_, idx) => idx !== i))} className="p-1 text-destructive hover:bg-destructive/10 rounded">
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>
              ))}
            </div>
          </div>

          <DialogFooter className="mt-4">
            <Button variant="outline" onClick={closeForm}>Annulla</Button>
            <Button onClick={handleSubmit} isLoading={createMutation.isPending || updateMutation.isPending}>
              {editing ? 'Salva modifiche' : 'Crea regola'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
