"use client"

import { useEffect, useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { Plus, Trash2 } 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, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { Textarea } from "@/components/ui/textarea"

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

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

type DraftItem = { id: string; text: string; required: boolean }

const NO_COMPANY_VALUE = "__global__"

function normalizeTemplateItems(items: DraftItem[]) {
  const normalized = items
    .map((item) => ({ ...item, text: item.text.trim() }))
    .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).")
  }
  return normalized
}

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[]>([{ id: crypto.randomUUID(), text: "", required: true }])
  const [archived, setArchived] = useState<boolean>(false)

  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, required: item.required }))
        : [{ id: crypto.randomUUID(), text: "", required: true }]
    )
    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, 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>
              <Select value={companyValue} onValueChange={setCompanyValue}>
                <SelectTrigger>
                  <SelectValue placeholder="Global" />
                </SelectTrigger>
                <SelectContent className="rounded-xl">
                  <SelectItem value={NO_COMPANY_VALUE}>Global (todas)</SelectItem>
                  {companies.map((company) => (
                    <SelectItem key={company.id} value={String(company.id)}>
                      {company.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </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, { id: crypto.randomUUID(), text: "", required: true }])}
              >
                <Plus className="size-4" />
                Novo item
              </Button>
            </div>

            <div className="space-y-2">
              {items.map((item) => (
                <div key={item.id} className="flex flex-col gap-2 rounded-xl border border-slate-200 bg-white p-3 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="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>
                  <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>
              ))}
            </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 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 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, 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.")
    }
  }

  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" onClick={handleNew} className="gap-2">
              <Plus className="size-4" />
              Novo template
            </Button>
          </div>
        </CardHeader>
        <CardContent>
          {!templates ? (
            <p className="text-sm text-neutral-600">Carregando templates...</p>
          ) : 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" onClick={() => handleEdit(tpl)}>
                        Editar
                      </Button>
                      <Button type="button" variant="outline" onClick={() => handleToggleArchived(tpl)}>
                        {tpl.isArchived ? "Restaurar" : "Arquivar"}
                      </Button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

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