"use client"

import { useEffect, useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import type { TicketStatus } from "@/lib/schemas/ticket"
import { useAuth } from "@/lib/auth-client"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Spinner } from "@/components/ui/spinner"
import { RichTextEditor } from "@/components/ui/rich-text-editor"
import { toast } from "sonner"
import { cn } from "@/lib/utils"
import { sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
import { ChevronDown } from "lucide-react"

type StatusKey = TicketStatus | "NEW" | "OPEN" | "ON_HOLD";

const STATUS_OPTIONS: TicketStatus[] = ["PENDING", "AWAITING_ATTENDANCE", "PAUSED", "RESOLVED"];

const statusStyles: Record<StatusKey, { label: string; badgeClass: string }> = {
  PENDING: { label: "Pendente", badgeClass: "bg-slate-100 text-slate-700" },
  AWAITING_ATTENDANCE: { label: "Aguardando atendimento", badgeClass: "bg-[#dff1fb] text-[#0a4760]" },
  PAUSED: { label: "Pausado", badgeClass: "bg-[#ede8ff] text-[#4f2f96]" },
  RESOLVED: { label: "Resolvido", badgeClass: "bg-[#dcf4eb] text-[#1f6a45]" },
  NEW: { label: "Pendente", badgeClass: "bg-slate-100 text-slate-700" },
  OPEN: { label: "Aguardando atendimento", badgeClass: "bg-[#dff1fb] text-[#0a4760]" },
  ON_HOLD: { label: "Pausado", badgeClass: "bg-[#ede8ff] text-[#4f2f96]" },
};

const triggerClass =
  "group inline-flex h-auto w-auto items-center justify-center rounded-full border border-transparent bg-transparent p-0 shadow-none ring-0 ring-offset-0 ring-offset-transparent focus-visible:outline-none focus-visible:border-transparent focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:shadow-none hover:bg-transparent data-[state=open]:bg-transparent data-[state=open]:border-transparent data-[state=open]:shadow-none data-[state=open]:ring-0 data-[state=open]:ring-offset-0 data-[state=open]:ring-offset-transparent [&>*:last-child]:hidden"
const itemClass = "rounded-md px-2 py-2 text-sm text-neutral-800 transition hover:bg-slate-100 data-[state=checked]:bg-[#00e8ff]/15 data-[state=checked]:text-neutral-900 focus:bg-[#00e8ff]/10"
const baseBadgeClass =
  "inline-flex h-9 items-center gap-2 rounded-full border border-slate-200 px-3 text-sm font-semibold transition hover:border-slate-300"

type ClosingTemplate = {
  id: string
  title: string
  body: string
}

const DEFAULT_PHONE_NUMBER = "(11) 4173-5368"

const DEFAULT_CLOSING_TEMPLATES: ClosingTemplate[] = [
  {
    id: "default-standard",
    title: "Encerramento padrão",
    body: sanitizeEditorHtml(`
      <p>Olá {{cliente}},</p>
      <p>A equipe da Raven agradece o contato. Este ticket está sendo encerrado.</p>
      <p>Se surgirem novas questões, você pode reabrir o ticket em até 7 dias ou nos contatar pelo número <strong>${DEFAULT_PHONE_NUMBER}</strong>. Obrigado.</p>
      <p>👍 👀 🙌<br />Gabriel Henrique · Raven</p>
    `),
  },
  {
    id: "default-no-contact",
    title: "Tentativa de contato sem sucesso",
    body: sanitizeEditorHtml(`
      <p>Prezado(a) {{cliente}},</p>
      <p>Realizamos uma tentativa de contato, mas não obtivemos sucesso.</p>
      <p>Por favor, retorne assim que possível para seguirmos com as verificações necessárias.</p>
      <p>Este ticket será encerrado após 3 tentativas realizadas sem sucesso.</p>
      <p>Telefone para contato: <strong>${DEFAULT_PHONE_NUMBER}</strong>.</p>
      <p>👍 👀 🙌<br />Gabriel Henrique · Raven</p>
    `),
  },
  {
    id: "default-closed-after-attempts",
    title: "Encerramento após 3 tentativas",
    body: sanitizeEditorHtml(`
      <p>Prezado(a) {{cliente}},</p>
      <p>Esse ticket está sendo encerrado pois realizamos 3 tentativas sem retorno.</p>
      <p>Você pode reabrir este ticket em até 7 dias ou entrar em contato pelo telefone <strong>${DEFAULT_PHONE_NUMBER}</strong> quando preferir.</p>
      <p>👍 👀 🙌<br />Gabriel Henrique · Raven</p>
    `),
  },
]

function applyTemplatePlaceholders(html: string, customerName?: string | null) {
  const normalizedName = customerName?.trim()
  const fallback = normalizedName && normalizedName.length > 0 ? normalizedName : "cliente"
  return html.replace(/{{\s*(cliente|customer|customername|nome|nomecliente)\s*}}/gi, fallback)
}

export function StatusSelect({
  ticketId,
  value,
  tenantId,
  requesterName,
}: {
  ticketId: string
  value: TicketStatus
  tenantId: string
  requesterName?: string | null
}) {
  const updateStatus = useMutation(api.tickets.updateStatus)
  const { convexUserId } = useAuth()
  const actorId = (convexUserId ?? null) as Id<"users"> | null
  const [status, setStatus] = useState<TicketStatus>(value)
  const [closeDialogOpen, setCloseDialogOpen] = useState(false)

  useEffect(() => {
    setStatus(value)
  }, [value])

  const handleStatusChange = async (selected: string) => {
    const next = selected as TicketStatus
    if (next === "RESOLVED") {
      setCloseDialogOpen(true)
      return
    }

    const previous = status
    setStatus(next)
    toast.loading("Atualizando status...", { id: "status" })
    try {
      if (!actorId) {
        throw new Error("missing user")
      }
      await updateStatus({ ticketId: ticketId as unknown as Id<"tickets">, status: next, actorId })
      toast.success("Status alterado para " + (statusStyles[next]?.label ?? next) + ".", { id: "status" })
    } catch (error) {
      console.error(error)
      setStatus(previous)
      toast.error("Não foi possível atualizar o status.", { id: "status" })
    }
  }

  return (
    <>
      <Select value={status} onValueChange={handleStatusChange}>
        <SelectTrigger className={triggerClass} aria-label="Atualizar status">
          <SelectValue asChild>
            <Badge className={cn(baseBadgeClass, statusStyles[status]?.badgeClass ?? statusStyles.PENDING.badgeClass)}>
              {statusStyles[status]?.label ?? statusStyles.PENDING.label}
              <ChevronDown className="size-3 text-current transition group-data-[state=open]:rotate-180" />
            </Badge>
          </SelectValue>
        </SelectTrigger>
        <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
          {STATUS_OPTIONS.map((option) => (
            <SelectItem key={option} value={option} className={itemClass}>
              {statusStyles[option].label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
      <CloseTicketDialog
        open={closeDialogOpen}
        onOpenChange={(open) => {
          if (!open) setCloseDialogOpen(false)
        }}
        ticketId={ticketId}
        tenantId={tenantId}
        actorId={actorId}
        requesterName={requesterName}
        onSuccess={() => {
          setStatus("RESOLVED")
          setCloseDialogOpen(false)
        }}
      />
    </>
  )
}

type CloseTicketDialogProps = {
  open: boolean
  onOpenChange: (open: boolean) => void
  ticketId: string
  tenantId: string
  actorId: Id<"users"> | null
  requesterName?: string | null
  onSuccess: () => void
}

function CloseTicketDialog({ open, onOpenChange, ticketId, tenantId, actorId, requesterName, onSuccess }: CloseTicketDialogProps) {
  const updateStatus = useMutation(api.tickets.updateStatus)
  const addComment = useMutation(api.tickets.addComment)

  const closingTemplates = useQuery(
    actorId && open ? api.commentTemplates.list : "skip",
    actorId && open ? { tenantId, viewerId: actorId, kind: "closing" as const } : "skip"
  ) as { id: string; title: string; body: string }[] | undefined

  const templatesLoading = Boolean(actorId && open && closingTemplates === undefined)

  const templates = useMemo<ClosingTemplate[]>(() => {
    if (closingTemplates && closingTemplates.length > 0) {
      return closingTemplates.map((template) => ({ id: template.id, title: template.title, body: template.body }))
    }
    return DEFAULT_CLOSING_TEMPLATES
  }, [closingTemplates])

  const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null)
  const [message, setMessage] = useState<string>("")
  const [isSubmitting, setIsSubmitting] = useState(false)

  useEffect(() => {
    if (!open) {
      setSelectedTemplateId(null)
      setMessage("")
      setIsSubmitting(false)
      return
    }
    if (templates.length > 0 && !selectedTemplateId && !message) {
      const first = templates[0]
      const hydrated = sanitizeEditorHtml(applyTemplatePlaceholders(first.body, requesterName))
      setSelectedTemplateId(first.id)
      setMessage(hydrated)
    }
  }, [open, templates, requesterName, selectedTemplateId, message])

  const handleTemplateSelect = (template: ClosingTemplate) => {
    setSelectedTemplateId(template.id)
    const filled = sanitizeEditorHtml(applyTemplatePlaceholders(template.body, requesterName))
    setMessage(filled)
  }

  const handleSubmit = async () => {
    if (!actorId) {
      toast.error("É necessário estar autenticado para encerrar o ticket.")
      return
    }
    setIsSubmitting(true)
    toast.loading("Encerrando ticket...", { id: "close-ticket" })
    try {
      await updateStatus({ ticketId: ticketId as unknown as Id<"tickets">, status: "RESOLVED", actorId })
      const withPlaceholders = applyTemplatePlaceholders(message, requesterName)
      const sanitized = sanitizeEditorHtml(withPlaceholders)
      const hasContent = sanitized.replace(/<[^>]*>/g, "").trim().length > 0
      if (hasContent) {
        await addComment({
          ticketId: ticketId as unknown as Id<"tickets">,
          authorId: actorId,
          visibility: "PUBLIC",
          body: sanitized,
          attachments: [],
        })
      }
      toast.success("Ticket encerrado com sucesso!", { id: "close-ticket" })
      onOpenChange(false)
      onSuccess()
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível encerrar o ticket.", { id: "close-ticket" })
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Encerrar ticket</DialogTitle>
          <DialogDescription>
            Confirme a mensagem de encerramento que será enviada ao cliente. Você pode personalizar o texto antes de concluir.
          </DialogDescription>
        </DialogHeader>
        <div className="space-y-4">
          <div className="space-y-2">
            <p className="text-sm font-medium text-neutral-800">Modelos rápidos</p>
            {templatesLoading ? (
              <div className="flex items-center gap-2 text-sm text-neutral-600">
                <Spinner className="size-4" /> Carregando templates...
              </div>
            ) : (
              <div className="flex flex-wrap gap-2">
                {templates.map((template) => (
                  <Button
                    key={template.id}
                    type="button"
                    variant={selectedTemplateId === template.id ? "default" : "outline"}
                    size="sm"
                    onClick={() => handleTemplateSelect(template)}
                  >
                    {template.title}
                  </Button>
                ))}
              </div>
            )}
            <p className="text-xs text-neutral-500">
              Use <code className="rounded bg-slate-100 px-1 py-0.5">{"{{cliente}}"}</code> dentro do template para inserir automaticamente o nome do solicitante.
            </p>
          </div>
          <div className="space-y-2">
            <p className="text-sm font-medium text-neutral-800">Mensagem de encerramento</p>
            <RichTextEditor
              value={message}
              onChange={setMessage}
              minHeight={220}
              placeholder="Escreva uma mensagem final para o cliente..."
            />
            <p className="text-xs text-neutral-500">Você pode editar o conteúdo antes de enviar. Deixe em branco para encerrar sem comentário adicional.</p>
          </div>
        </div>
        <DialogFooter className="flex flex-wrap justify-between gap-3 pt-4">
          <div className="text-xs text-neutral-500">
            O comentário será público e ficará registrado no histórico do ticket.
          </div>
          <div className="flex items-center gap-2">
            <Button
              type="button"
              variant="outline"
              onClick={() => {
                setMessage("")
                setSelectedTemplateId(null)
              }}
              disabled={isSubmitting}
            >
              Limpar mensagem
            </Button>
            <Button type="button" onClick={handleSubmit} disabled={isSubmitting || !actorId}>
              {isSubmitting ? <Spinner className="size-4 text-white" /> : "Encerrar ticket"}
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
