"use client"

import { useEffect, useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { HelpCircle, Plus, Trash2, X } from "lucide-react"
import { toast } from "sonner"

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 { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"
import { Switch } from "@/components/ui/switch"
import { Skeleton } from "@/components/ui/skeleton"
import { Textarea } from "@/components/ui/textarea"

type ChecklistItemType = "checkbox" | "question"

type ChecklistTemplateRow = {
  id: Id<"ticketChecklistTemplates">
  name: string
  description: string
  company: { id: Id<"companies">; name: string } | null
  items: Array<{
    id: string
    text: string
    description?: string
    type?: ChecklistItemType
    options?: string[]
    required: boolean
  }>
  isArchived: boolean
  updatedAt: number
}

type CompanyRow = { id: Id<"companies">; name: string }

type DraftItem = {
  id: string
  text: string
  description: string
  type: ChecklistItemType
  options: string[]
  required: boolean
}

const NO_COMPANY_VALUE = "__global__"

function normalizeTemplateItems(items: DraftItem[]) {
  const normalized = items
    .map((item) => ({
      ...item,
      text: item.text.trim(),
      description: item.description.trim(),
      options: item.type === "question" ? item.options.map((o) => o.trim()).filter((o) => o.length > 0) : [],
    }))
    .filter((item) => item.text.length > 0)

  if (normalized.length === 0) {
    throw new Error("Adicione pelo menos um item no checklist.")
  }
  const invalid = normalized.find((item) => item.text.length > 240)
  if (invalid) {
    throw new Error("Item do checklist muito longo (máx. 240 caracteres).")
  }
  const invalidQuestion = normalized.find((item) => item.type === "question" && item.options.length < 2)
  if (invalidQuestion) {
    throw new Error(`A pergunta "${invalidQuestion.text}" precisa ter pelo menos 2 opções.`)
  }
  return normalized
}

function createEmptyItem(): DraftItem {
  return {
    id: crypto.randomUUID(),
    text: "",
    description: "",
    type: "checkbox",
    options: [],
    required: true,
  }
}

function TemplateEditorDialog({
  open,
  onOpenChange,
  template,
  companies,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  template: ChecklistTemplateRow | null
  companies: CompanyRow[]
}) {
  const { convexUserId, session } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const actorId = convexUserId as Id<"users"> | null

  const createTemplate = useMutation(api.checklistTemplates.create)
  const updateTemplate = useMutation(api.checklistTemplates.update)

  const [saving, setSaving] = useState(false)
  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [companyValue, setCompanyValue] = useState<string>(NO_COMPANY_VALUE)
  const [items, setItems] = useState<DraftItem[]>([createEmptyItem()])
  const [archived, setArchived] = useState<boolean>(false)

  const companyComboboxOptions = useMemo<SearchableComboboxOption[]>(() => {
    const sortedCompanies = [...companies].sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))

    return [
      { value: NO_COMPANY_VALUE, label: "Global (todas)" },
      ...sortedCompanies.map((company) => ({ value: String(company.id), label: company.name })),
    ]
  }, [companies])

  useEffect(() => {
    if (!open) return
    setName(template?.name ?? "")
    setDescription(template?.description ?? "")
    setCompanyValue(template?.company?.id ? String(template.company.id) : NO_COMPANY_VALUE)
    setItems(
      template?.items?.length
        ? template.items.map((item) => ({
            id: item.id,
            text: item.text,
            description: item.description ?? "",
            type: (item.type ?? "checkbox") as ChecklistItemType,
            options: item.options ?? [],
            required: item.required,
          }))
        : [createEmptyItem()]
    )
    setArchived(template?.isArchived ?? false)
  }, [open, template])

  const handleSave = async () => {
    if (!actorId) return
    const trimmedName = name.trim()
    if (trimmedName.length < 3) {
      toast.error("Informe um nome com pelo menos 3 caracteres.")
      return
    }
    let normalizedItems: DraftItem[]
    try {
      normalizedItems = normalizeTemplateItems(items)
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Itens do checklist inválidos.")
      return
    }

    const payload = {
      tenantId,
      actorId,
      name: trimmedName,
      description: description.trim().length > 0 ? description.trim() : undefined,
      companyId: companyValue !== NO_COMPANY_VALUE ? (companyValue as Id<"companies">) : undefined,
      items: normalizedItems.map((item) => ({
        id: item.id,
        text: item.text,
        description: item.description.length > 0 ? item.description : undefined,
        type: item.type,
        options: item.type === "question" && item.options.length > 0 ? item.options : undefined,
        required: item.required,
      })),
      isArchived: archived,
    }

    setSaving(true)
    try {
      if (template) {
        await updateTemplate({ templateId: template.id, ...payload })
        toast.success("Template atualizado.")
      } else {
        await createTemplate(payload)
        toast.success("Template criado.")
      }
      onOpenChange(false)
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao salvar template.")
    } finally {
      setSaving(false)
    }
  }

  const canSave = Boolean(actorId) && !saving

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl">
        <DialogHeader className="gap-1">
          <DialogTitle>{template ? "Editar template de checklist" : "Novo template de checklist"}</DialogTitle>
        </DialogHeader>

        <div className="space-y-5">
          <div className="grid gap-4 md:grid-cols-2">
            <div className="space-y-2">
              <Label>Nome</Label>
              <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Ex.: Checklist de instalação" />
            </div>
            <div className="space-y-2">
              <Label>Empresa</Label>
              <SearchableCombobox
                value={companyValue}
                onValueChange={(nextValue) => setCompanyValue(nextValue ?? NO_COMPANY_VALUE)}
                options={companyComboboxOptions}
                placeholder="Selecionar empresa"
                searchPlaceholder="Buscar empresa..."
                triggerClassName="h-9 rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm font-medium text-neutral-800 shadow-sm"
                contentClassName="rounded-xl"
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Descrição (opcional)</Label>
            <Textarea value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Quando usar este checklist?" />
          </div>

          <div className="space-y-3">
            <div className="flex items-center justify-between gap-2">
              <div className="space-y-0.5">
                <p className="text-sm font-semibold text-neutral-900">Itens</p>
                <p className="text-xs text-muted-foreground">Defina o que precisa ser feito. Itens obrigatórios bloqueiam o encerramento.</p>
              </div>
              <Button
                type="button"
                variant="outline"
                className="gap-2"
                onClick={() => setItems((prev) => [...prev, createEmptyItem()])}
              >
                <Plus className="size-4" />
                Novo item
              </Button>
            </div>

            <div className="space-y-3">
              {items.map((item) => (
                <div key={item.id} className="space-y-2 rounded-xl border border-slate-200 bg-white p-3">
                  <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                    <Input
                      value={item.text}
                      onChange={(e) =>
                        setItems((prev) => prev.map((row) => (row.id === item.id ? { ...row, text: e.target.value } : row)))
                      }
                      placeholder={item.type === "question" ? "Ex.: Emprestou algum equipamento?" : "Ex.: Validar backup"}
                      className="h-9 flex-1"
                    />
                    <label className="flex items-center gap-2 text-sm text-neutral-700">
                      <Checkbox
                        checked={item.required}
                        onCheckedChange={(checked) =>
                          setItems((prev) => prev.map((row) => (row.id === item.id ? { ...row, required: Boolean(checked) } : row)))
                        }
                      />
                      Obrigatório
                    </label>
                    <label className="flex items-center gap-2 text-sm text-neutral-700">
                      <Checkbox
                        checked={item.type === "question"}
                        onCheckedChange={(checked) =>
                          setItems((prev) =>
                            prev.map((row) =>
                              row.id === item.id
                                ? {
                                    ...row,
                                    type: checked ? "question" : "checkbox",
                                    options: checked ? (row.options.length > 0 ? row.options : ["Sim", "Não"]) : [],
                                  }
                                : row
                            )
                          )
                        }
                      />
                      <HelpCircle className="size-4" />
                      Pergunta
                    </label>
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      className="h-9 w-9 text-slate-500 hover:bg-red-50 hover:text-red-700"
                      onClick={() => setItems((prev) => prev.filter((row) => row.id !== item.id))}
                      title="Remover"
                    >
                      <Trash2 className="size-4" />
                    </Button>
                  </div>

                  <Input
                    value={item.description}
                    onChange={(e) =>
                      setItems((prev) => prev.map((row) => (row.id === item.id ? { ...row, description: e.target.value } : row)))
                    }
                    placeholder="Descrição (opcional)"
                    className="h-8 text-xs"
                  />

                  {item.type === "question" && (
                    <div className="space-y-2 rounded-lg border border-dashed border-cyan-200 bg-cyan-50/50 p-2">
                      <div className="flex items-center justify-between gap-2">
                        <p className="text-xs font-medium text-cyan-700">Opções de resposta</p>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          className="h-7 gap-1 text-xs text-cyan-700 hover:bg-cyan-100 hover:text-cyan-800"
                          onClick={() =>
                            setItems((prev) =>
                              prev.map((row) => (row.id === item.id ? { ...row, options: [...row.options, ""] } : row))
                            )
                          }
                        >
                          <Plus className="size-3" />
                          Adicionar
                        </Button>
                      </div>
                      <div className="flex flex-wrap gap-2">
                        {item.options.map((option, optIdx) => (
                          <div key={optIdx} className="flex items-center gap-1">
                            <Input
                              value={option}
                              onChange={(e) =>
                                setItems((prev) =>
                                  prev.map((row) =>
                                    row.id === item.id
                                      ? { ...row, options: row.options.map((o, i) => (i === optIdx ? e.target.value : o)) }
                                      : row
                                  )
                                )
                              }
                              placeholder={`Opcao ${optIdx + 1}`}
                              className="h-7 w-24 text-xs"
                            />
                            <Button
                              type="button"
                              variant="ghost"
                              size="icon"
                              className="h-7 w-7 text-slate-400 hover:bg-red-50 hover:text-red-600"
                              onClick={() =>
                                setItems((prev) =>
                                  prev.map((row) =>
                                    row.id === item.id ? { ...row, options: row.options.filter((_, i) => i !== optIdx) } : row
                                  )
                                )
                              }
                            >
                              <X className="size-3" />
                            </Button>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>

          <div className="flex items-center justify-between gap-3">
            <div className="flex items-center gap-3">
              <span className="text-sm font-medium text-neutral-700">Arquivado</span>
              <Switch checked={archived} onCheckedChange={setArchived} className="data-[state=checked]:bg-black data-[state=unchecked]:bg-slate-300" />
            </div>
            <div className="flex items-center gap-2">
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
                Cancelar
              </Button>
              <Button type="button" onClick={handleSave} disabled={!canSave}>
                Salvar
              </Button>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  )
}

export function ChecklistTemplatesManager() {
  const { convexUserId, session } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const viewerId = convexUserId as Id<"users"> | null

  const [includeArchived, setIncludeArchived] = useState(false)
  const [editorOpen, setEditorOpen] = useState(false)
  const [editing, setEditing] = useState<ChecklistTemplateRow | null>(null)
  const [deleteTarget, setDeleteTarget] = useState<ChecklistTemplateRow | null>(null)
  const [deleting, setDeleting] = useState(false)

  const templates = useQuery(
    api.checklistTemplates.list,
    viewerId ? { tenantId, viewerId, includeArchived } : "skip"
  ) as ChecklistTemplateRow[] | undefined

  const companies = useQuery(
    api.companies.list,
    viewerId ? { tenantId, viewerId } : "skip"
  ) as Array<{ id: Id<"companies">; name: string }> | undefined

  const updateTemplate = useMutation(api.checklistTemplates.update)
  const removeTemplate = useMutation(api.checklistTemplates.remove)

  const companyOptions = useMemo<CompanyRow[]>(
    () => (companies ?? []).map((c) => ({ id: c.id, name: c.name })).sort((a, b) => a.name.localeCompare(b.name, "pt-BR")),
    [companies]
  )

  const orderedTemplates = useMemo(() => (templates ?? []).slice().sort((a, b) => b.updatedAt - a.updatedAt), [templates])

  const handleNew = () => {
    setEditing(null)
    setEditorOpen(true)
  }

  const handleEdit = (tpl: ChecklistTemplateRow) => {
    setEditing(tpl)
    setEditorOpen(true)
  }

  const handleToggleArchived = async (tpl: ChecklistTemplateRow) => {
    if (!viewerId) return
    try {
      await updateTemplate({
        tenantId,
        actorId: viewerId,
        templateId: tpl.id,
        name: tpl.name,
        description: tpl.description || undefined,
        companyId: tpl.company?.id ?? undefined,
        items: tpl.items.map((item) => ({
          id: item.id,
          text: item.text,
          description: item.description,
          type: item.type ?? "checkbox",
          options: item.options,
          required: item.required,
        })),
        isArchived: !tpl.isArchived,
      })
      toast.success(tpl.isArchived ? "Template restaurado." : "Template arquivado.")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao atualizar template.")
    }
  }

  const handleDeleteConfirm = async () => {
    if (!viewerId || !deleteTarget) return
    setDeleting(true)
    try {
      await removeTemplate({
        tenantId,
        actorId: viewerId,
        templateId: deleteTarget.id,
      })
      toast.success("Template excluído.")
      setDeleteTarget(null)
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao excluir template.")
    } finally {
      setDeleting(false)
    }
  }

  return (
    <div className="space-y-6">
      <Card className="border border-slate-200">
        <CardHeader className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div className="space-y-1">
            <CardTitle className="text-xl font-semibold text-neutral-900">Templates de checklist</CardTitle>
            <CardDescription className="text-sm text-neutral-600">
              Crie modelos globais ou por empresa para padronizar tarefas de atendimento.
            </CardDescription>
          </div>
          <div className="flex flex-wrap items-center gap-3">
            <label className="flex items-center gap-2 text-sm text-neutral-700">
              <Switch
                checked={includeArchived}
                onCheckedChange={setIncludeArchived}
                className="data-[state=checked]:bg-black data-[state=unchecked]:bg-slate-300"
              />
              Exibir arquivados
            </label>
            <Button type="button" size="sm" onClick={handleNew} className="gap-2">
              <Plus className="size-4" />
              Novo template
            </Button>
          </div>
        </CardHeader>
        <CardContent>
          {!templates ? (
            <div className="space-y-3">
              {Array.from({ length: 4 }).map((_, index) => (
                <div key={`template-skeleton-${index}`} className="rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
                  <div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
                    <div className="min-w-0 space-y-2">
                      <div className="flex flex-wrap items-center gap-2">
                        <Skeleton className="h-5 w-40" />
                        <Skeleton className="h-5 w-16 rounded-full" />
                        <Skeleton className="h-5 w-14 rounded-full" />
                      </div>
                      <Skeleton className="h-4 w-64" />
                    </div>
                    <div className="flex items-center gap-2">
                      <Skeleton className="h-8 w-16 rounded-md" />
                      <Skeleton className="h-8 w-20 rounded-md" />
                      <Skeleton className="h-8 w-8 rounded-md" />
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : orderedTemplates.length === 0 ? (
            <div className="rounded-xl border border-dashed border-slate-200 p-6 text-sm text-neutral-600">
              Nenhum template cadastrado.
            </div>
          ) : (
            <div className="space-y-3">
              {orderedTemplates.map((tpl) => (
                <div key={tpl.id} className="rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
                  <div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
                    <div className="min-w-0">
                      <div className="flex flex-wrap items-center gap-2">
                        <p className="truncate text-sm font-semibold text-neutral-900">{tpl.name}</p>
                        {tpl.isArchived ? (
                          <Badge variant="outline" className="rounded-full text-[11px]">
                            Arquivado
                          </Badge>
                        ) : null}
                        {tpl.company ? (
                          <Badge variant="secondary" className="rounded-full text-[11px]">
                            {tpl.company.name}
                          </Badge>
                        ) : (
                          <Badge variant="outline" className="rounded-full text-[11px]">
                            Global
                          </Badge>
                        )}
                        <Badge variant="outline" className="rounded-full text-[11px]">
                          {tpl.items.length} item{tpl.items.length === 1 ? "" : "s"}
                        </Badge>
                      </div>
                      {tpl.description ? (
                        <p className="mt-1 text-xs text-neutral-500">{tpl.description}</p>
                      ) : null}
                    </div>
                    <div className="flex items-center gap-2">
                      <Button type="button" variant="outline" size="sm" onClick={() => handleEdit(tpl)}>
                        Editar
                      </Button>
                      <Button type="button" variant="outline" size="sm" onClick={() => handleToggleArchived(tpl)}>
                        {tpl.isArchived ? "Restaurar" : "Arquivar"}
                      </Button>
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        className="text-slate-500 hover:bg-red-50 hover:text-red-700"
                        onClick={() => setDeleteTarget(tpl)}
                        title="Excluir template"
                      >
                        <Trash2 className="size-4" />
                      </Button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      <TemplateEditorDialog
        open={editorOpen}
        onOpenChange={setEditorOpen}
        template={editing}
        companies={companyOptions}
      />

      <Dialog open={Boolean(deleteTarget)} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Excluir template</DialogTitle>
            <DialogDescription>
              Tem certeza que deseja excluir o template <strong>&quot;{deleteTarget?.name}&quot;</strong>? Esta ação não pode ser desfeita.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-3">
            <Button type="button" variant="outline" onClick={() => setDeleteTarget(null)} disabled={deleting}>
              Cancelar
            </Button>
            <Button type="button" variant="destructive" onClick={handleDeleteConfirm} disabled={deleting}>
              {deleting ? "Excluindo..." : "Excluir"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
