"use client"

import { useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { useMutation } from "convex/react"
import { toast } from "sonner"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import type { TicketPriority } from "@/lib/schemas/ticket"
import { sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
import { useAuth } from "@/lib/auth-client"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { CategorySelectFields } from "@/components/tickets/category-select"
import { Dropzone } from "@/components/ui/dropzone"
import { RichTextEditor } from "@/components/ui/rich-text-editor"

const DEFAULT_PRIORITY: TicketPriority = "MEDIUM"

function toHtml(text: string) {
  const escaped = text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;")
  return `<p>${escaped.replace(/\n/g, "<br />")}</p>`
}

export function PortalTicketForm() {
  const router = useRouter()
  const { convexUserId, session, machineContext, machineContextError, machineContextLoading } = useAuth()
  const createTicket = useMutation(api.tickets.create)
  const addComment = useMutation(api.tickets.addComment)

  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const viewerId = (convexUserId ?? machineContext?.assignedUserId ?? null) as Id<"users"> | null

  const [subject, setSubject] = useState("")
  const [summary, setSummary] = useState("")
  const [description, setDescription] = useState("")
  const [categoryId, setCategoryId] = useState<string | null>(null)
  const [subcategoryId, setSubcategoryId] = useState<string | null>(null)
  const [attachments, setAttachments] = useState<Array<{ storageId: string; name: string; size?: number; type?: string }>>([])
  const attachmentsTotalBytes = useMemo(
    () => attachments.reduce((acc, item) => acc + (item.size ?? 0), 0),
    [attachments]
  )
  const [isSubmitting, setIsSubmitting] = useState(false)
  const machineInactive = machineContext?.isActive === false
  const isFormValid = useMemo(() => {
    return Boolean(subject.trim() && description.trim() && categoryId && subcategoryId && !machineInactive)
  }, [subject, description, categoryId, subcategoryId, machineInactive])
  const isViewerReady = Boolean(viewerId)
  const viewerErrorMessage = useMemo(() => {
    if (!machineContextError) return null
    const suffix = machineContextError.status ? ` (status ${machineContextError.status})` : ""
    return `${machineContextError.message}${suffix}`
  }, [machineContextError])

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault()
    if (isSubmitting || !isFormValid) return
    if (machineInactive) {
      toast.error("Esta máquina está desativada no momento. Reative-a para abrir novos chamados.", { id: "portal-new-ticket" })
      return
    }
    if (!viewerId) {
      const detail = viewerErrorMessage ? ` Detalhes: ${viewerErrorMessage}` : ""
      toast.error(
        `Não foi possível identificar o colaborador vinculado a esta máquina. Tente abrir novamente o portal ou contate o suporte.${detail}`,
        { id: "portal-new-ticket" }
      )
      return
    }

    const trimmedSubject = subject.trim()
    const trimmedSummary = summary.trim()
    const sanitizedDescription = sanitizeEditorHtml(description || "")
    const plainDescription = sanitizedDescription.replace(/<[^>]*>/g, "").trim()
    if (plainDescription.length === 0) {
      toast.error("Descreva o que aconteceu para que possamos ajudar melhor.", { id: "portal-new-ticket" })
      return
    }

    setIsSubmitting(true)
    toast.loading("Abrindo chamado...", { id: "portal-new-ticket" })
    try {
      const id = await createTicket({
        actorId: viewerId,
        tenantId,
        subject: trimmedSubject,
        summary: trimmedSummary || undefined,
        priority: DEFAULT_PRIORITY,
        channel: "MANUAL",
        queueId: undefined,
        requesterId: viewerId,
        categoryId: categoryId as Id<"ticketCategories">,
        subcategoryId: subcategoryId as Id<"ticketSubcategories">,
      })

      if (plainDescription.length > 0) {
        const htmlBody = sanitizedDescription || toHtml(trimmedSummary || trimmedSubject)

        const typedAttachments = attachments.map((file) => ({
          storageId: file.storageId as Id<"_storage">,
          name: file.name,
          size: file.size,
          type: file.type,
        }))
        await addComment({
          ticketId: id as Id<"tickets">,
          authorId: viewerId,
          visibility: "PUBLIC",
          body: htmlBody,
          attachments: typedAttachments,
        })
      }

      toast.success("Chamado criado com sucesso!", { id: "portal-new-ticket" })
      setAttachments([])
      router.replace(`/portal/tickets/${id}`)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível abrir o chamado.", { id: "portal-new-ticket" })
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
      <CardHeader className="px-5 py-5">
        <CardTitle className="text-xl font-semibold text-neutral-900">Abrir novo chamado</CardTitle>
      </CardHeader>
      <CardContent className="space-y-6 px-5 pb-6">
        {machineInactive ? (
          <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700">
            Esta máquina foi desativada pelos administradores e não pode abrir novos chamados até ser reativada.
          </div>
        ) : null}
        {!isViewerReady ? (
          <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700">
            Vincule esta máquina a um colaborador na aplicação desktop para enviar chamados em nome dele.
            {machineContextLoading ? (
              <p className="mt-2 text-xs text-amber-600">Carregando informa��es da m�quina...</p>
            ) : null}
            {viewerErrorMessage ? (
              <p className="mt-2 text-xs text-amber-600">
                Detalhes do erro: {viewerErrorMessage}
              </p>
            ) : null}
          </div>
        ) : null}
        <form onSubmit={handleSubmit} className="space-y-6">
          <div className="space-y-3">
            <div className="space-y-1">
              <label htmlFor="subject" className="flex items-center gap-1 text-sm font-medium text-neutral-800">
                Assunto <span className="text-red-500">*</span>
              </label>
              <Input
                id="subject"
                value={subject}
                onChange={(event) => setSubject(event.target.value)}
                placeholder="Ex.: Problema de acesso ao sistema"
                disabled={machineInactive || isSubmitting}
                required
              />
            </div>
            <div className="space-y-1">
              <label htmlFor="summary" className="text-sm font-medium text-neutral-800">
                Resumo (opcional)
              </label>
              <Input
                id="summary"
                value={summary}
                onChange={(event) => setSummary(event.target.value)}
                placeholder="Descreva rapidamente o que está acontecendo"
                disabled={machineInactive || isSubmitting}
              />
            </div>
            <div className="space-y-1">
              <label htmlFor="description" className="flex items-center gap-1 text-sm font-medium text-neutral-800">
                Detalhes <span className="text-red-500">*</span>
              </label>
              <RichTextEditor
                value={description}
                onChange={(html) => setDescription(html)}
                placeholder="Compartilhe passos para reproduzir, mensagens de erro ou informações adicionais."
                className="rounded-2xl border border-slate-200 shadow-sm focus-within:border-neutral-900 focus-within:ring-neutral-900/20"
                disabled={machineInactive || isSubmitting}
              />
            </div>
          </div>

          <div className="space-y-4">
            <CategorySelectFields
              tenantId={tenantId}
              categoryId={categoryId}
              subcategoryId={subcategoryId}
              onCategoryChange={setCategoryId}
              onSubcategoryChange={setSubcategoryId}
              layout="stacked"
              categoryLabel="Categoria *"
              subcategoryLabel="Subcategoria *"
              secondaryEmptyLabel="Selecione uma categoria"
            />
            <div className="space-y-1">
              <span className="text-sm font-medium text-neutral-800">Anexos (opcional)</span>
              <Dropzone
                onUploaded={(files) => setAttachments((prev) => [...prev, ...files])}
                className="rounded-xl border border-dashed border-slate-300 bg-slate-50 px-3 py-4 text-sm text-neutral-600 shadow-inner"
                currentFileCount={attachments.length}
                currentTotalBytes={attachmentsTotalBytes}
                disabled={!isViewerReady || machineInactive || isSubmitting}
              />
              <p className="text-xs text-neutral-500">
                Formatos comuns de imagens e documentos são aceitos.
              </p>
            </div>
          </div>

          <div className="flex justify-end gap-3">
            <Button
              type="button"
              variant="outline"
              onClick={() => router.push("/portal/tickets")}
              className="rounded-full border-slate-300 px-6 text-sm font-semibold text-neutral-700 hover:bg-neutral-100"
              disabled={isSubmitting}
            >
              Cancelar
            </Button>
            <Button
              type="submit"
              disabled={!isFormValid || isSubmitting || machineInactive}
              className="rounded-full bg-neutral-900 px-6 text-sm font-semibold text-white hover:bg-neutral-900/90"
            >
              Registrar chamado
            </Button>
          </div>
        </form>
      </CardContent>
    </Card>
  )
}
