/**
 * TagSelector – pannello di selezione/creazione tag per messaggi.
 *
 * Modalità d'uso:
 *  - single: apre un Dialog per impostare i tag di un singolo messaggio
 *  - bulk:   apre un Dialog per aggiungere o rimuovere tag da più messaggi
 *
 * Funzionalità:
 *  - Lista tutti i tag del tenant con checkbox
 *  - Ricerca/filtro tag
 *  - Crea nuovi tag con nome e colore (solo per admin)
 *  - Mostra anteprima del badge colorato
 */
import { useState, useMemo } from 'react'
import { Plus, Search, Tag, Check, Trash2 } from 'lucide-react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'

import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/Dialog'
import { TagBadge } from './TagBadge'
import { labelsApi } from '@/api/labels.api'
import { getErrorMessage } from '@/api/client'
import { useAuth } from '@/hooks/useAuth'
import { cn } from '@/lib/utils'
import type { LabelResponse } from '@/types/api.types'

// ─── Tavolozza colori predefiniti ─────────────────────────────────────────────

const PRESET_COLORS = [
  '#ef4444', // rosso
  '#f97316', // arancione
  '#eab308', // giallo
  '#22c55e', // verde
  '#14b8a6', // teal
  '#3b82f6', // blu
  '#8b5cf6', // viola
  '#ec4899', // rosa
  '#6b7280', // grigio
  '#78716c', // marrone
]

// ─── Tipi ──────────────────────────────────────────────────────────────────────

interface TagSelectorSingleProps {
  mode: 'single'
  open: boolean
  onClose: () => void
  /** ID dei tag attualmente assegnati al messaggio */
  currentLabelIds: string[]
  /** Chiamata quando l'utente conferma la selezione */
  onApply: (labelIds: string[]) => void
  isApplying?: boolean
}

interface TagSelectorBulkProps {
  mode: 'bulk'
  open: boolean
  onClose: () => void
  /** Numero di messaggi selezionati (per info nell'UI) */
  messageCount: number
  /** Chiamata con i label selezionati e l'azione (add/remove) */
  onApply: (labelIds: string[], action: 'add' | 'remove') => void
  isApplying?: boolean
}

type TagSelectorProps = TagSelectorSingleProps | TagSelectorBulkProps

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

export function TagSelector(props: TagSelectorProps) {
  const { open, onClose, onApply, isApplying } = props
  const { user } = useAuth()
  const isAdmin = user?.role === 'admin' || user?.role === 'super_admin'
  const queryClient = useQueryClient()

  // Stato selezione (per single: IDs scelti; per bulk: IDs da applicare)
  const [selectedIds, setSelectedIds] = useState<Set<string>>(
    props.mode === 'single' ? new Set(props.currentLabelIds) : new Set(),
  )
  const [searchQuery, setSearchQuery] = useState('')
  const [showCreate, setShowCreate] = useState(false)
  const [newName, setNewName] = useState('')
  const [newColor, setNewColor] = useState(PRESET_COLORS[5]) // blu default

  // Reset dello stato all'apertura
  const handleOpenChange = (isOpen: boolean) => {
    if (!isOpen) {
      setSearchQuery('')
      setShowCreate(false)
      setNewName('')
      setNewColor(PRESET_COLORS[5])
      if (props.mode === 'bulk') {
        setSelectedIds(new Set())
      }
      onClose()
    } else if (props.mode === 'single') {
      setSelectedIds(new Set(props.currentLabelIds))
    }
  }

  // Carica lista tag del tenant
  const { data: allLabels = [], isLoading } = useQuery({
    queryKey: ['labels'],
    queryFn: labelsApi.list,
    staleTime: 5 * 60 * 1000,
    enabled: open,
  })

  // Tag filtrati per ricerca
  const filteredLabels = useMemo(() => {
    if (!searchQuery.trim()) return allLabels
    const q = searchQuery.toLowerCase()
    return allLabels.filter((l) => l.name.toLowerCase().includes(q))
  }, [allLabels, searchQuery])

  // Crea nuovo tag
  const createMutation = useMutation<LabelResponse, Error, void>({
    mutationFn: () => labelsApi.create({ name: newName.trim(), color: newColor }),
    onSuccess: (newLabel) => {
      queryClient.invalidateQueries({ queryKey: ['labels'] })
      setSelectedIds((prev) => new Set([...prev, newLabel.id]))
      setNewName('')
      setShowCreate(false)
      toast.success(`Tag "${newLabel.name}" creato`)
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

  // Elimina tag
  const deleteMutation = useMutation({
    mutationFn: (id: string) => labelsApi.delete(id),
    onSuccess: (_, deletedId) => {
      queryClient.invalidateQueries({ queryKey: ['labels'] })
      setSelectedIds((prev) => {
        const next = new Set(prev)
        next.delete(deletedId)
        return next
      })
      toast.success('Tag eliminato')
    },
    onError: (error) => toast.error(getErrorMessage(error)),
  })

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

  const handleApplySingle = () => {
    if (props.mode === 'single') {
      onApply(Array.from(selectedIds))
    }
  }

  const handleApplyBulk = (action: 'add' | 'remove') => {
    if (props.mode === 'bulk') {
      onApply(Array.from(selectedIds), action)
    }
  }

  const canConfirm = selectedIds.size > 0

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Tag className="h-5 w-5 text-primary" />
            {props.mode === 'single' ? 'Gestisci tag' : `Assegna tag a ${props.mode === 'bulk' ? props.messageCount : ''} messaggi`}
          </DialogTitle>
        </DialogHeader>

        <div className="space-y-4">
          {/* Ricerca tag */}
          <div className="relative">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Cerca tag…"
              className="pl-9 h-9"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              autoFocus
            />
          </div>

          {/* Lista tag */}
          <div className="max-h-60 overflow-y-auto space-y-1 rounded-lg border bg-muted/20 p-2">
            {isLoading ? (
              <div className="flex items-center justify-center py-4">
                <div className="h-5 w-5 animate-spin rounded-full border-2 border-primary border-t-transparent" />
              </div>
            ) : filteredLabels.length === 0 ? (
              <p className="text-xs text-muted-foreground text-center py-4">
                {searchQuery ? 'Nessun tag trovato' : 'Nessun tag disponibile'}
              </p>
            ) : (
              filteredLabels.map((label) => (
                <LabelRow
                  key={label.id}
                  label={label}
                  isSelected={selectedIds.has(label.id)}
                  onToggle={() => toggleLabel(label.id)}
                  onDelete={isAdmin ? () => deleteMutation.mutate(label.id) : undefined}
                  isDeleting={deleteMutation.isPending && deleteMutation.variables === label.id}
                />
              ))
            )}
          </div>

          {/* Crea nuovo tag (admin only) */}
          {isAdmin && (
            <div className="border rounded-lg overflow-hidden">
              <button
                type="button"
                onClick={() => setShowCreate(!showCreate)}
                className="w-full flex items-center gap-2 px-3 py-2 text-sm text-left hover:bg-muted/50 transition-colors"
              >
                <Plus className="h-4 w-4 text-primary flex-shrink-0" />
                <span className="text-primary font-medium">Crea nuovo tag</span>
              </button>

              {showCreate && (
                <div className="px-3 pb-3 pt-1 border-t bg-muted/10 space-y-3">
                  <Input
                    placeholder="Nome tag…"
                    value={newName}
                    onChange={(e) => setNewName(e.target.value)}
                    className="h-8 text-sm"
                    maxLength={100}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' && newName.trim()) createMutation.mutate()
                    }}
                  />

                  {/* Selettore colore */}
                  <div className="space-y-1.5">
                    <p className="text-xs text-muted-foreground">Colore</p>
                    <div className="flex items-center gap-2 flex-wrap">
                      {PRESET_COLORS.map((color) => (
                        <button
                          key={color}
                          type="button"
                          onClick={() => setNewColor(color)}
                          className={cn(
                            'h-6 w-6 rounded-full border-2 transition-all',
                            newColor === color
                              ? 'border-foreground scale-110'
                              : 'border-transparent hover:scale-105',
                          )}
                          style={{ backgroundColor: color }}
                          title={color}
                        />
                      ))}
                    </div>
                  </div>

                  {/* Anteprima badge */}
                  {newName.trim() && (
                    <div className="flex items-center gap-2">
                      <span className="text-xs text-muted-foreground">Anteprima:</span>
                      <TagBadge
                        label={{ id: 'preview', tenant_id: '', name: newName.trim(), color: newColor }}
                        size="sm"
                      />
                    </div>
                  )}

                  <Button
                    size="sm"
                    className="w-full h-8"
                    disabled={!newName.trim()}
                    onClick={() => createMutation.mutate()}
                    isLoading={createMutation.isPending}
                  >
                    Crea tag
                  </Button>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Footer azioni */}
        <DialogFooter className="flex-col gap-2 sm:flex-row">
          <Button variant="outline" onClick={() => handleOpenChange(false)} className="sm:order-first">
            Annulla
          </Button>

          {props.mode === 'single' ? (
            <Button
              onClick={handleApplySingle}
              isLoading={isApplying}
            >
              Applica tag
            </Button>
          ) : (
            <div className="flex gap-2 flex-1 sm:justify-end">
              <Button
                variant="outline"
                disabled={!canConfirm}
                onClick={() => handleApplyBulk('remove')}
                isLoading={isApplying}
                className="flex-1 sm:flex-none"
              >
                Rimuovi
              </Button>
              <Button
                disabled={!canConfirm}
                onClick={() => handleApplyBulk('add')}
                isLoading={isApplying}
                className="flex-1 sm:flex-none"
              >
                Aggiungi
              </Button>
            </div>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

// ─── Riga singolo label nella lista ──────────────────────────────────────────

interface LabelRowProps {
  label: LabelResponse
  isSelected: boolean
  onToggle: () => void
  onDelete?: () => void
  isDeleting?: boolean
}

function LabelRow({ label, isSelected, onToggle, onDelete, isDeleting }: LabelRowProps) {
  return (
    <div
      className={cn(
        'flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer hover:bg-muted/50 transition-colors group',
        isSelected && 'bg-primary/5',
      )}
      onClick={onToggle}
    >
      {/* Checkbox */}
      <div
        className={cn(
          'h-4 w-4 rounded border-2 flex items-center justify-center flex-shrink-0 transition-colors',
          isSelected
            ? 'bg-primary border-primary text-primary-foreground'
            : 'border-muted-foreground/40',
        )}
      >
        {isSelected && <Check className="h-3 w-3" />}
      </div>

      {/* Badge con colore */}
      <TagBadge label={label} size="sm" className="pointer-events-none" />

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

      {/* Pulsante elimina (solo admin, visibile su hover) */}
      {onDelete && (
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation()
            onDelete()
          }}
          className={cn(
            'p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-all',
            isDeleting ? 'opacity-50 pointer-events-none' : 'opacity-0 group-hover:opacity-100',
          )}
          title="Elimina tag"
          aria-label={`Elimina tag ${label.name}`}
        >
          <Trash2 className="h-3.5 w-3.5" />
        </button>
      )}
    </div>
  )
}
