"use client"

import { useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { CheckCheck, ListChecks, Plus, RotateCcw, Trash2 } from "lucide-react"
import { toast } from "sonner"

import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import type { TicketChecklistItem, TicketWithDetails } from "@/lib/schemas/ticket"
import { useAuth } from "@/lib/auth-client"
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 { Progress } from "@/components/ui/progress"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

type ChecklistTemplateRow = {
  id: Id<"ticketChecklistTemplates">
  name: string
  company: { id: Id<"companies">; name: string } | null
}

function countRequiredPending(items: TicketChecklistItem[]) {
  return items.filter((item) => (item.required ?? true) && !item.done).length
}

function countRequiredDone(items: TicketChecklistItem[]) {
  return items.filter((item) => (item.required ?? true) && item.done).length
}

function countAllDone(items: TicketChecklistItem[]) {
  return items.filter((item) => item.done).length
}

export function TicketChecklistCard({
  ticket,
}: {
  ticket: Pick<TicketWithDetails, "id" | "tenantId" | "company" | "checklist" | "status">
}) {
  const { convexUserId, isAdmin, isStaff, role } = useAuth()
  const actorId = (convexUserId ?? null) as Id<"users"> | null
  const canEdit = Boolean(isAdmin || role === "agent")
  const canToggleDone = Boolean(isStaff)
  const isResolved = ticket.status === "RESOLVED"

  const checklist = useMemo(() => ticket.checklist ?? [], [ticket.checklist])
  const requiredTotal = useMemo(() => checklist.filter((item) => (item.required ?? true)).length, [checklist])
  const requiredDone = useMemo(() => countRequiredDone(checklist), [checklist])
  const requiredPending = useMemo(() => countRequiredPending(checklist), [checklist])
  const allDone = useMemo(() => countAllDone(checklist), [checklist])

  const totalItems = checklist.length
  const progress = totalItems > 0 ? Math.round((allDone / totalItems) * 100) : 0

  const addChecklistItem = useMutation(api.tickets.addChecklistItem)
  const updateChecklistItemText = useMutation(api.tickets.updateChecklistItemText)
  const setChecklistItemDone = useMutation(api.tickets.setChecklistItemDone)
  const setChecklistItemRequired = useMutation(api.tickets.setChecklistItemRequired)
  const setChecklistItemAnswer = useMutation(api.tickets.setChecklistItemAnswer)
  const removeChecklistItem = useMutation(api.tickets.removeChecklistItem)
  const completeAllChecklistItems = useMutation(api.tickets.completeAllChecklistItems)
  const uncompleteAllChecklistItems = useMutation(api.tickets.uncompleteAllChecklistItems)
  const applyChecklistTemplate = useMutation(api.tickets.applyChecklistTemplate)

  const templates = useQuery(
    api.checklistTemplates.listActive,
    actorId
      ? {
          tenantId: ticket.tenantId,
          viewerId: actorId,
          companyId: ticket.company?.id ? (ticket.company.id as Id<"companies">) : undefined,
        }
      : "skip"
  ) as ChecklistTemplateRow[] | undefined

  const templateNameById = useMemo(() => {
    const map = new Map<string, string>()
    for (const tpl of templates ?? []) {
      map.set(String(tpl.id), tpl.name)
    }
    return map
  }, [templates])

  const [newText, setNewText] = useState("")
  const [newRequired, setNewRequired] = useState(true)
  const [adding, setAdding] = useState(false)

  const [editingId, setEditingId] = useState<string | null>(null)
  const [editingText, setEditingText] = useState("")
  const [savingText, setSavingText] = useState(false)

  const [selectedTemplateId, setSelectedTemplateId] = useState<string>("")
  const [applyingTemplate, setApplyingTemplate] = useState(false)
  const [completingAll, setCompletingAll] = useState(false)
  const [onlyPending, setOnlyPending] = useState(false)
  const [deleteTarget, setDeleteTarget] = useState<TicketChecklistItem | null>(null)
  const [deleting, setDeleting] = useState(false)

  const handleAdd = async () => {
    if (!actorId || !canEdit || isResolved) return
    const text = newText.trim()
    if (!text) {
      toast.error("Informe o texto do item do checklist.")
      return
    }
    setAdding(true)
    try {
      await addChecklistItem({
        ticketId: ticket.id as Id<"tickets">,
        actorId,
        text,
        required: newRequired,
      })
      setNewText("")
      setNewRequired(true)
      toast.success("Item adicionado ao checklist.")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao adicionar item.")
    } finally {
      setAdding(false)
    }
  }

  const handleSaveText = async () => {
    if (!actorId || !canEdit || isResolved || !editingId) return
    const text = editingText.trim()
    if (!text) {
      toast.error("Informe o texto do item do checklist.")
      return
    }
    setSavingText(true)
    try {
      await updateChecklistItemText({
        ticketId: ticket.id as Id<"tickets">,
        actorId,
        itemId: editingId,
        text,
      })
      setEditingId(null)
      setEditingText("")
      toast.success("Item atualizado.")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao atualizar item.")
    } finally {
      setSavingText(false)
    }
  }

  const handleApplyTemplate = async () => {
    if (!actorId || !canEdit || isResolved) return
    const templateId = selectedTemplateId.trim()
    if (!templateId) return
    setApplyingTemplate(true)
    try {
      const result = await applyChecklistTemplate({
        ticketId: ticket.id as Id<"tickets">,
        actorId,
        templateId: templateId as Id<"ticketChecklistTemplates">,
      })
      const added = typeof result?.added === "number" ? result.added : 0
      toast.success(added > 0 ? `Checklist aplicado (${added} novo${added === 1 ? "" : "s"}).` : "Checklist já estava aplicado.")
      setSelectedTemplateId("")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao aplicar template.")
    } finally {
      setApplyingTemplate(false)
    }
  }

  const allItemsDone = checklist.length > 0 && allDone === totalItems

  const handleToggleAll = async () => {
    if (!actorId || !canEdit || isResolved) return
    setCompletingAll(true)
    try {
      if (allItemsDone) {
        await uncompleteAllChecklistItems({ ticketId: ticket.id as Id<"tickets">, actorId })
        toast.success("Itens desmarcados.")
      } else {
        await completeAllChecklistItems({ ticketId: ticket.id as Id<"tickets">, actorId })
        toast.success("Checklist concluído.")
      }
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Falha ao atualizar checklist.")
    } finally {
      setCompletingAll(false)
    }
  }

  const canToggleAll = checklist.length > 0 && canEdit && !isResolved
  const visibleChecklist = useMemo(() => {
    return onlyPending ? checklist.filter((item) => !item.done) : checklist
  }, [checklist, onlyPending])
  const isLargeChecklist = totalItems > 12

  return (
    <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
      <CardHeader className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
        <div className="space-y-1">
          <CardTitle className="flex items-center gap-2 text-base font-semibold text-neutral-900">
            <ListChecks className="size-5 text-neutral-700" />
            Checklist
          </CardTitle>
          <CardDescription className="text-sm text-neutral-600">
            {totalItems > 0 ? (
              <>
                {allDone}/{totalItems} itens concluídos
                {requiredTotal > 0 ? ` • ${requiredDone}/${requiredTotal} obrigatórios` : ""}
              </>
            ) : (
              "Nenhum item cadastrado."
            )}
          </CardDescription>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {allDone > 0 && !isResolved ? (
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => {
                setEditingId(null)
                setEditingText("")
                setOnlyPending((prev) => !prev)
              }}
            >
              {onlyPending ? "Ver todos" : "Somente pendentes"}
            </Button>
          ) : null}
          {canEdit && !isResolved && canToggleAll ? (
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="gap-2"
              onClick={handleToggleAll}
              disabled={completingAll}
              title={allItemsDone ? "Desmarcar todos os itens" : "Marcar todos os itens como concluídos"}
            >
              {allItemsDone ? (
                <>
                  <RotateCcw className="size-4" />
                  Desmarcar todos
                </>
              ) : (
                <>
                  <CheckCheck className="size-4" />
                  Concluir todos
                </>
              )}
            </Button>
          ) : null}
          {canEdit && !isResolved && (templates ?? []).length > 0 ? (
            <div className="flex items-center gap-2">
              <Select value={selectedTemplateId} onValueChange={setSelectedTemplateId}>
                <SelectTrigger size="sm" className="w-[220px]">
                  <SelectValue placeholder="Aplicar template..." />
                </SelectTrigger>
                <SelectContent className="rounded-xl">
                  {(templates ?? []).map((tpl) => (
                    <SelectItem key={tpl.id} value={String(tpl.id)}>
                      {tpl.name}
                      {tpl.company ? ` — ${tpl.company.name}` : ""}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Button
                type="button"
                onClick={handleApplyTemplate}
                disabled={!selectedTemplateId || applyingTemplate}
                size="sm"
              >
                Aplicar
              </Button>
            </div>
          ) : null}
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex items-center gap-3">
          <Progress value={progress} className="h-2 flex-1" indicatorClassName="bg-neutral-900" />
          <span className="text-xs font-semibold tabular-nums text-neutral-800">{progress}%</span>
        </div>

        {checklist.length === 0 ? (
          <div className="rounded-xl border border-dashed border-slate-200 p-4 text-sm text-neutral-600">
            {canEdit && !isResolved ? "Adicione itens para controlar o atendimento antes de encerrar." : "Nenhum checklist informado."}
          </div>
        ) : (
          <ScrollArea className={isLargeChecklist ? "max-h-[60vh] pr-1" : undefined}>
            <div className="space-y-2">
              {visibleChecklist.length === 0 ? (
                <div className="rounded-xl border border-dashed border-slate-200 bg-white p-4 text-sm text-neutral-600">
                  Nenhum item pendente.
                </div>
              ) : (
                visibleChecklist.map((item) => {
                  const required = item.required ?? true
                  const canToggle = canToggleDone && !isResolved
                  const templateLabel = item.templateId ? templateNameById.get(String(item.templateId)) ?? null : null
                  const isQuestion = item.type === "question"
                  const options = item.options ?? []

                  return (
                    <div key={item.id} className="flex items-center justify-between gap-3 rounded-xl border border-slate-200 bg-white px-4 py-3">
                      <div className="flex min-w-0 flex-1 items-start gap-3">
                        {isQuestion ? (
                          <div className="mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full bg-neutral-900/80 text-xs font-semibold text-white">
                            ?
                          </div>
                        ) : (
                          <Checkbox
                            checked={item.done}
                            disabled={!canToggle || !actorId}
                            onCheckedChange={async (checked) => {
                              if (!actorId || !canToggle) return
                              try {
                                await setChecklistItemDone({
                                  ticketId: ticket.id as Id<"tickets">,
                                  actorId,
                                  itemId: item.id,
                                  done: Boolean(checked),
                                })
                              } catch (error) {
                                toast.error(error instanceof Error ? error.message : "Falha ao atualizar checklist.")
                              }
                            }}
                            className="mt-0.5"
                          />
                        )}
                        <div className="min-w-0 flex-1 space-y-2">
                          {editingId === item.id && canEdit && !isResolved ? (
                            <div className="flex items-center gap-2">
                              <Input
                                value={editingText}
                                onChange={(e) => setEditingText(e.target.value)}
                                className="h-9"
                                autoFocus
                                onKeyDown={(e) => {
                                  if (e.key === "Enter") {
                                    e.preventDefault()
                                    handleSaveText()
                                  }
                                  if (e.key === "Escape") {
                                    setEditingId(null)
                                    setEditingText("")
                                  }
                                }}
                              />
                              <Button type="button" onClick={handleSaveText} disabled={savingText} className="h-9">
                                Salvar
                              </Button>
                              <Button
                                type="button"
                                variant="outline"
                                onClick={() => {
                                  setEditingId(null)
                                  setEditingText("")
                                }}
                                className="h-9"
                              >
                                Cancelar
                              </Button>
                            </div>
                          ) : (
                            <p
                              className={`text-sm ${item.done ? "text-neutral-500 line-through" : "text-neutral-900"}`}
                              title={item.text}
                              onDoubleClick={() => {
                                if (!canEdit || isResolved) return
                                setEditingId(item.id)
                                setEditingText(item.text)
                              }}
                            >
                              {item.text}
                            </p>
                          )}

                          {isQuestion && options.length > 0 && (
                            <div className="flex flex-wrap items-center gap-2">
                              {options.map((option) => {
                                const isSelected = item.answer === option
                                return (
                                  <button
                                    key={option}
                                    type="button"
                                    disabled={!canToggle || !actorId}
                                    onClick={async () => {
                                      if (!actorId || !canToggle) return
                                      try {
                                        await setChecklistItemAnswer({
                                          ticketId: ticket.id as Id<"tickets">,
                                          actorId,
                                          itemId: item.id,
                                          // Toggle: se já está selecionado, limpa; senão, seleciona
                                          answer: isSelected ? undefined : option,
                                        })
                                      } catch (error) {
                                        toast.error(error instanceof Error ? error.message : "Falha ao responder pergunta.")
                                      }
                                    }}
                                    className={`rounded-lg border px-3 py-1.5 text-sm transition-colors ${
                                      isSelected
                                        ? "border-neutral-900 bg-neutral-900 text-white"
                                        : "border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50"
                                    } ${!canToggle || !actorId ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`}
                                  >
                                    {option}
                                  </button>
                                )
                              })}
                            </div>
                          )}

                          <div className="flex flex-wrap items-center gap-2">
                            {required ? (
                              <Badge variant="secondary" className="rounded-full px-2.5 py-0.5 text-[11px] font-medium">
                                Obrigatório
                              </Badge>
                            ) : (
                              <Badge variant="outline" className="rounded-full px-2.5 py-0.5 text-[11px] font-medium">
                                Opcional
                              </Badge>
                            )}
                            {isQuestion && (
                              <Badge variant="outline" className="rounded-full border-slate-300 bg-slate-100 px-2.5 py-0.5 text-[11px] font-medium text-slate-600">
                                Pergunta
                              </Badge>
                            )}
                            {templateLabel ? (
                              <Badge variant="outline" className="rounded-full px-2.5 py-0.5 text-[11px] font-medium text-slate-500">
                                {templateLabel}
                              </Badge>
                            ) : null}
                          </div>
                          {(item.templateDescription || item.description) && (
                            <div className="space-y-0.5">
                              {item.templateDescription && (
                                <p className="text-xs italic text-slate-400">
                                  {item.templateDescription}
                                </p>
                              )}
                              {item.description && (
                                <p className="text-xs text-slate-500">
                                  {item.description}
                                </p>
                              )}
                            </div>
                          )}
                        </div>
                      </div>

                      {canEdit && !isResolved ? (
                        <div className="flex shrink-0 items-center gap-1">
                          <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={async () => {
                              if (!actorId) return
                              try {
                                await setChecklistItemRequired({
                                  ticketId: ticket.id as Id<"tickets">,
                                  actorId,
                                  itemId: item.id,
                                  required: !required,
                                })
                              } catch (error) {
                                toast.error(error instanceof Error ? error.message : "Falha ao atualizar item.")
                              }
                            }}
                          >
                            {required ? "Tornar opcional" : "Tornar obrigatório"}
                          </Button>
                          <Button
                            type="button"
                            variant="ghost"
                            size="icon"
                            className="h-9 w-9 text-slate-500 hover:bg-red-50 hover:text-red-700"
                            onClick={() => setDeleteTarget(item)}
                          >
                            <Trash2 className="size-4" />
                          </Button>
                        </div>
                      ) : null}
                    </div>
                  )
                })
              )}
            </div>
          </ScrollArea>
        )}

        {canEdit && !isResolved ? (
          <div className="flex flex-col gap-2 rounded-xl border border-slate-200 bg-slate-50 p-3 sm:flex-row sm:items-center sm:justify-between">
            <Input
              value={newText}
              onChange={(e) => setNewText(e.target.value)}
              placeholder="Adicionar item do checklist..."
              className="h-8 w-full bg-white sm:max-w-md"
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault()
                  handleAdd()
                }
              }}
            />
            <div className="flex items-center gap-4">
              <label className="flex h-8 items-center gap-2 text-sm text-neutral-700">
                <Checkbox checked={newRequired} onCheckedChange={(checked) => setNewRequired(Boolean(checked))} />
                Obrigatório
              </label>
              <Button type="button" size="sm" onClick={handleAdd} disabled={adding} className="gap-2">
                <Plus className="size-4" />
                Adicionar
              </Button>
            </div>
          </div>
        ) : null}
      </CardContent>

      <Dialog open={Boolean(deleteTarget)} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Remover item do checklist</DialogTitle>
            <DialogDescription>
              Tem certeza que deseja remover o item <strong>&quot;{deleteTarget?.text}&quot;</strong> do checklist?
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-3">
            <Button type="button" variant="outline" onClick={() => setDeleteTarget(null)} disabled={deleting}>
              Cancelar
            </Button>
            <Button
              type="button"
              variant="destructive"
              disabled={deleting}
              onClick={async () => {
                if (!actorId || !deleteTarget) return
                setDeleting(true)
                try {
                  await removeChecklistItem({
                    ticketId: ticket.id as Id<"tickets">,
                    actorId,
                    itemId: deleteTarget.id,
                  })
                  toast.success("Item removido.")
                  setDeleteTarget(null)
                } catch (error) {
                  toast.error(error instanceof Error ? error.message : "Falha ao remover item.")
                } finally {
                  setDeleting(false)
                }
              }}
            >
              {deleting ? "Removendo..." : "Remover"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  )
}
