"use client"

import { useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { IconAdjustments, IconForms, IconListDetails, IconTypography } from "@tabler/icons-react"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { useAuth } from "@/lib/auth-client"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Checkbox } from "@/components/ui/checkbox"
import { Badge } from "@/components/ui/badge"
import { Skeleton } from "@/components/ui/skeleton"
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"

type FieldOption = { value: string; label: string }

type Field = {
  id: string
  key: string
  label: string
  description: string
  type: "text" | "number" | "select" | "date" | "boolean"
  required: boolean
  options: FieldOption[]
  order: number
}

const TYPE_LABELS: Record<Field["type"], string> = {
  text: "Texto",
  number: "Número",
  select: "Seleção",
  date: "Data",
  boolean: "Verdadeiro/Falso",
}

export function FieldsManager() {
  const { session, convexUserId } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID

  const fields = useQuery(
    api.fields.list,
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as Field[] | undefined

  const createField = useMutation(api.fields.create)
  const updateField = useMutation(api.fields.update)
  const removeField = useMutation(api.fields.remove)
  const reorderFields = useMutation(api.fields.reorder)

  const [label, setLabel] = useState("")
  const [description, setDescription] = useState("")
  const [type, setType] = useState<Field["type"]>("text")
  const [required, setRequired] = useState(false)
  const [options, setOptions] = useState<FieldOption[]>([])
  const [saving, setSaving] = useState(false)
  const [editingField, setEditingField] = useState<Field | null>(null)

  const totals = useMemo(() => {
    if (!fields) return { total: 0, required: 0, select: 0 }
    return {
      total: fields.length,
      required: fields.filter((field) => field.required).length,
      select: fields.filter((field) => field.type === "select").length,
    }
  }, [fields])

  const resetForm = () => {
    setLabel("")
    setDescription("")
    setType("text")
    setRequired(false)
    setOptions([])
  }

  const normalizeOptions = (source: FieldOption[]) =>
    source
      .map((option) => ({
        label: option.label.trim(),
        value: option.value.trim() || option.label.trim().toLowerCase().replace(/\s+/g, "_"),
      }))
      .filter((option) => option.label.length > 0)

  const handleCreate = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    if (!label.trim()) {
      toast.error("Informe o rótulo do campo")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    const preparedOptions = type === "select" ? normalizeOptions(options) : undefined
    setSaving(true)
    toast.loading("Criando campo...", { id: "field" })
    try {
      await createField({
        tenantId,
        actorId: convexUserId as Id<"users">,
        label: label.trim(),
        description: description.trim() || undefined,
        type,
        required,
        options: preparedOptions,
      })
      toast.success("Campo criado", { id: "field" })
      resetForm()
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar o campo", { id: "field" })
    } finally {
      setSaving(false)
    }
  }

  const handleRemove = async (field: Field) => {
    const confirmed = window.confirm(`Excluir o campo ${field.label}?`)
    if (!confirmed) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    toast.loading("Removendo campo...", { id: `field-remove-${field.id}` })
    try {
      await removeField({
        tenantId,
        fieldId: field.id as Id<"ticketFields">,
        actorId: convexUserId as Id<"users">,
      })
      toast.success("Campo removido", { id: `field-remove-${field.id}` })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover o campo", { id: `field-remove-${field.id}` })
    }
  }

  const openEdit = (field: Field) => {
    setEditingField(field)
    setLabel(field.label)
    setDescription(field.description)
    setType(field.type)
    setRequired(field.required)
    setOptions(field.options)
  }

  const handleUpdate = async () => {
    if (!editingField) return
    if (!label.trim()) {
      toast.error("Informe o rótulo do campo")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    const preparedOptions = type === "select" ? normalizeOptions(options) : undefined
    setSaving(true)
    toast.loading("Atualizando campo...", { id: "field-edit" })
    try {
      await updateField({
        tenantId,
        fieldId: editingField.id as Id<"ticketFields">,
        actorId: convexUserId as Id<"users">,
        label: label.trim(),
        description: description.trim() || undefined,
        type,
        required,
        options: preparedOptions,
      })
      toast.success("Campo atualizado", { id: "field-edit" })
      setEditingField(null)
      resetForm()
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível atualizar o campo", { id: "field-edit" })
    } finally {
      setSaving(false)
    }
  }

  const moveField = async (field: Field, direction: "up" | "down") => {
    if (!fields) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    const index = fields.findIndex((item) => item.id === field.id)
    const targetIndex = direction === "up" ? index - 1 : index + 1
    if (targetIndex < 0 || targetIndex >= fields.length) return
    const reordered = [...fields]
    const [removed] = reordered.splice(index, 1)
    reordered.splice(targetIndex, 0, removed)
    try {
      await reorderFields({
        tenantId,
        actorId: convexUserId as Id<"users">,
        orderedIds: reordered.map((item) => item.id as Id<"ticketFields">),
      })
      toast.success("Ordem atualizada")
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível reordenar os campos")
    }
  }

  const addOption = () => {
    setOptions((current) => [...current, { label: "", value: "" }])
  }

  const updateOption = (index: number, key: keyof FieldOption, value: string) => {
    setOptions((current) => {
      const copy = [...current]
      copy[index] = { ...copy[index], [key]: value }
      return copy
    })
  }

  const removeOption = (index: number) => {
    setOptions((current) => current.filter((_, optIndex) => optIndex !== index))
  }

  return (
    <div className="space-y-8">
      <div className="grid gap-4 md:grid-cols-3">
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconForms className="size-4" /> Campos personalizados
            </CardTitle>
            <CardDescription>Metadados adicionais disponíveis nos tickets.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {fields ? totals.total : <Skeleton className="h-8 w-16" />}
          </CardContent>
        </Card>
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconTypography className="size-4" /> Campos obrigatórios
            </CardTitle>
            <CardDescription>Informações exigidas na abertura.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {fields ? totals.required : <Skeleton className="h-8 w-16" />}
          </CardContent>
        </Card>
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconListDetails className="size-4" /> Campos de seleção
            </CardTitle>
            <CardDescription>Usados para listas e múltipla escolha.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {fields ? totals.select : <Skeleton className="h-8 w-16" />}
          </CardContent>
        </Card>
      </div>

      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-lg font-semibold text-neutral-900">
            <IconAdjustments className="size-5 text-neutral-500" /> Novo campo
          </CardTitle>
          <CardDescription>Capture informações específicas do seu fluxo de atendimento.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleCreate} className="grid gap-4 lg:grid-cols-[minmax(0,280px)_minmax(0,1fr)]">
            <div className="space-y-3">
              <div className="space-y-2">
                <Label htmlFor="field-label">Rótulo</Label>
                <Input
                  id="field-label"
                  placeholder="Ex.: Número do contrato"
                  value={label}
                  onChange={(event) => setLabel(event.target.value)}
                  required
                />
              </div>
              <div className="space-y-2">
                <Label>Tipo de dado</Label>
                <Select value={type} onValueChange={(value) => setType(value as Field["type"])}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="text">Texto curto</SelectItem>
                    <SelectItem value="number">Número</SelectItem>
                    <SelectItem value="select">Seleção</SelectItem>
                    <SelectItem value="date">Data</SelectItem>
                    <SelectItem value="boolean">Verdadeiro/Falso</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="flex items-center gap-2">
                <Checkbox id="field-required" checked={required} onCheckedChange={(value) => setRequired(Boolean(value))} />
                <Label htmlFor="field-required" className="text-sm font-normal text-neutral-600">
                  Campo obrigatório na abertura
                </Label>
              </div>
            </div>
            <div className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="field-description">Descrição</Label>
                <textarea
                  id="field-description"
                  className="min-h-[96px] w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-neutral-700 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900/10"
                  placeholder="Como este campo será utilizado"
                  value={description}
                  onChange={(event) => setDescription(event.target.value)}
                />
              </div>
              {type === "select" ? (
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <Label>Opções</Label>
                    <Button type="button" variant="outline" size="sm" onClick={addOption}>
                      Adicionar opção
                    </Button>
                  </div>
                  {options.length === 0 ? (
                    <p className="rounded-lg border border-dashed border-slate-200 p-4 text-sm text-neutral-500">
                      Adicione pelo menos uma opção para este campo de seleção.
                    </p>
                  ) : (
                    <div className="space-y-3">
                      {options.map((option, index) => (
                        <div key={index} className="grid gap-3 rounded-lg border border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,200px)_auto]">
                          <Input
                            placeholder="Rótulo"
                            value={option.label}
                            onChange={(event) => updateOption(index, "label", event.target.value)}
                          />
                          <Input
                            placeholder="Valor"
                            value={option.value}
                            onChange={(event) => updateOption(index, "value", event.target.value)}
                          />
                          <Button variant="ghost" type="button" onClick={() => removeOption(index)}>
                            Remover
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              ) : null}
              <div className="flex justify-end">
                <Button type="submit" disabled={saving}>
                  Criar campo
                </Button>
              </div>
            </div>
          </form>
        </CardContent>
      </Card>

      <div className="space-y-4">
        {fields === undefined ? (
          <div className="space-y-4">
            {Array.from({ length: 4 }).map((_, index) => (
              <Skeleton key={index} className="h-28 rounded-2xl" />
            ))}
          </div>
        ) : fields.length === 0 ? (
          <Card className="border-dashed border-slate-300 bg-slate-50/80">
            <CardHeader>
              <CardTitle className="text-lg font-semibold text-neutral-900">Nenhum campo cadastrado</CardTitle>
              <CardDescription className="text-neutral-600">
                Crie campos personalizados para enriquecer os tickets com informações importantes.
              </CardDescription>
            </CardHeader>
          </Card>
        ) : (
          fields.map((field, index) => (
            <Card key={field.id} className="border-slate-200">
              <CardHeader>
                <div className="flex items-start justify-between gap-4">
                  <div className="space-y-2">
                    <div className="flex items-center gap-3">
                      <CardTitle className="text-xl font-semibold text-neutral-900">{field.label}</CardTitle>
                      <Badge variant="outline" className="rounded-full border-neutral-300 text-neutral-600">
                        {TYPE_LABELS[field.type]}
                      </Badge>
                      {field.required ? (
                        <Badge variant="outline" className="rounded-full border-neutral-300 text-neutral-600">
                          obrigatório
                        </Badge>
                      ) : null}
                    </div>
                    <CardDescription className="text-neutral-600">Identificador: {field.key}</CardDescription>
                    {field.description ? (
                      <p className="text-sm text-neutral-600">{field.description}</p>
                    ) : null}
                  </div>
                  <div className="flex flex-col items-end gap-2">
                    <div className="flex gap-2">
                      <Button variant="outline" size="sm" onClick={() => openEdit(field)}>
                        Editar
                      </Button>
                      <Button variant="destructive" size="sm" onClick={() => handleRemove(field)}>
                        Excluir
                      </Button>
                    </div>
                    <div className="flex gap-2 text-xs text-neutral-500">
                      <Button
                        type="button"
                        size="sm"
                        variant="ghost"
                        className="px-2"
                        disabled={index === 0}
                        onClick={() => moveField(field, "up")}
                      >
                        Subir
                      </Button>
                      <Button
                        type="button"
                        size="sm"
                        variant="ghost"
                        className="px-2"
                        disabled={index === fields.length - 1}
                        onClick={() => moveField(field, "down")}
                      >
                        Descer
                      </Button>
                    </div>
                  </div>
                </div>
              </CardHeader>
              {field.type === "select" && field.options.length > 0 ? (
                <CardContent>
                  <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-neutral-500">Opções cadastradas</p>
                  <div className="flex flex-wrap gap-2">
                    {field.options.map((option) => (
                      <Badge key={option.value} variant="outline" className="rounded-full border-neutral-300 text-neutral-600">
                        {option.label} ({option.value})
                      </Badge>
                    ))}
                  </div>
                </CardContent>
              ) : null}
            </Card>
          ))
        )}
      </div>

      <Dialog open={Boolean(editingField)} onOpenChange={(value) => (!value ? setEditingField(null) : null)}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>Editar campo</DialogTitle>
          </DialogHeader>
          <div className="grid gap-4 py-2 lg:grid-cols-[minmax(0,260px)_minmax(0,1fr)]">
            <div className="space-y-3">
              <div className="space-y-2">
                <Label htmlFor="edit-field-label">Rótulo</Label>
                <Input
                  id="edit-field-label"
                  value={label}
                  onChange={(event) => setLabel(event.target.value)}
                  autoFocus
                />
              </div>
              <div className="space-y-2">
                <Label>Tipo de dado</Label>
                <Select value={type} onValueChange={(value) => setType(value as Field["type"])}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="text">Texto curto</SelectItem>
                    <SelectItem value="number">Número</SelectItem>
                    <SelectItem value="select">Seleção</SelectItem>
                    <SelectItem value="date">Data</SelectItem>
                    <SelectItem value="boolean">Verdadeiro/Falso</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="flex items-center gap-2">
                <Checkbox id="edit-field-required" checked={required} onCheckedChange={(value) => setRequired(Boolean(value))} />
                <Label htmlFor="edit-field-required" className="text-sm font-normal text-neutral-600">
                  Campo obrigatório na abertura
                </Label>
              </div>
            </div>
            <div className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="edit-field-description">Descrição</Label>
                <textarea
                  id="edit-field-description"
                  className="min-h-[96px] w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-neutral-700 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900/10"
                  value={description}
                  onChange={(event) => setDescription(event.target.value)}
                />
              </div>
              {type === "select" ? (
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <Label>Opções</Label>
                    <Button type="button" variant="outline" size="sm" onClick={addOption}>
                      Adicionar opção
                    </Button>
                  </div>
                  {options.length === 0 ? (
                    <p className="rounded-lg border border-dashed border-slate-200 p-4 text-sm text-neutral-500">
                      Inclua ao menos uma opção para salvar este campo.
                    </p>
                  ) : (
                    <div className="space-y-3">
                      {options.map((option, index) => (
                        <div key={index} className="grid gap-3 rounded-lg border border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,200px)_auto]">
                          <Input
                            placeholder="Rótulo"
                            value={option.label}
                            onChange={(event) => updateOption(index, "label", event.target.value)}
                          />
                          <Input
                            placeholder="Valor"
                            value={option.value}
                            onChange={(event) => updateOption(index, "value", event.target.value)}
                          />
                          <Button variant="ghost" type="button" onClick={() => removeOption(index)}>
                            Remover
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              ) : null}
            </div>
          </div>
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setEditingField(null)}>
              Cancelar
            </Button>
            <Button onClick={handleUpdate} disabled={saving}>
              Salvar alterações
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
