import { useMemo, useState } from "react"
import { format } from "date-fns"
import { ptBR } from "date-fns/locale"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { MonitorSmartphone } from "lucide-react"

import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import type { TicketWithDetails } from "@/lib/schemas/ticket"
import { useAuth } from "@/lib/auth-client"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { getTicketStatusLabel, getTicketStatusSummaryTone } from "@/lib/ticket-status-style"
import { Badge } from "@/components/ui/badge"
import { cn } from "@/lib/utils"
import { getSlaDisplayStatus, getSlaDueDate, type SlaDisplayStatus } from "@/lib/sla-utils"
import { Button } from "@/components/ui/button"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { useTicketRemoteAccess } from "@/hooks/use-ticket-remote-access"
import { PrioritySelect } from "@/components/tickets/priority-select"
import { StatusSelect } from "@/components/tickets/status-select"

interface TicketDetailsPanelProps {
  ticket: TicketWithDetails
}

type SummaryTone = "default" | "info" | "warning" | "success" | "muted" | "danger" | "primary"

const priorityLabel: Record<TicketWithDetails["priority"], string> = {
  LOW: "Baixa",
  MEDIUM: "Média",
  HIGH: "Alta",
  URGENT: "Urgente",
}

const priorityTone: Record<TicketWithDetails["priority"], SummaryTone> = {
  LOW: "muted",
  MEDIUM: "info",
  HIGH: "warning",
  URGENT: "danger",
}

const slaStatusTone: Record<Exclude<SlaDisplayStatus, "n/a">, { label: string; className: string }> = {
  on_track: { label: "No prazo", className: "text-emerald-600" },
  at_risk: { label: "Em risco", className: "text-amber-600" },
  breached: { label: "Violado", className: "text-rose-600" },
  met: { label: "Concluído", className: "text-emerald-600" },
}

function formatDuration(ms?: number | null) {
  if (!ms || ms <= 0) return "0s"
  const totalSeconds = Math.floor(ms / 1000)
  const hours = Math.floor(totalSeconds / 3600)
  const minutes = Math.floor((totalSeconds % 3600) / 60)
  const seconds = totalSeconds % 60
  if (hours > 0) {
    return `${hours}h ${minutes.toString().padStart(2, "0")}m`
  }
  if (minutes > 0) {
    return `${minutes}m ${seconds.toString().padStart(2, "0")}s`
  }
  return `${seconds}s`
}

function formatMinutes(value?: number | null) {
  if (value === null || value === undefined) return "—"
  return `${value} min`
}

function formatSlaTarget(value?: number | null, mode?: string) {
  if (!value) return "—"
  if (value < 60) return `${value} min${mode === "business" ? " úteis" : ""}`
  const hours = Math.floor(value / 60)
  const minutes = value % 60
  if (minutes === 0) {
    return `${hours}h${mode === "business" ? " úteis" : ""}`
  }
  return `${hours}h ${minutes}m${mode === "business" ? " úteis" : ""}`
}

function getSlaStatusDisplay(status: SlaDisplayStatus) {
  const normalized = status === "n/a" ? "on_track" : status
  return slaStatusTone[normalized as Exclude<SlaDisplayStatus, "n/a">]
}

type SummaryChipConfig = {
  key: string
  label: string
  value: string
  tone: SummaryTone
  labelClassName?: string
}

export function TicketDetailsPanel({ ticket }: TicketDetailsPanelProps) {
  const { convexUserId, isStaff } = useAuth()
  const {
    canShowRemoteAccess,
    primaryRemoteAccess,
    connect: handleRemoteConnect,
    hostname: remoteHostname,
  } = useTicketRemoteAccess(ticket)

  const canEdit = isStaff && !!convexUserId

  // Mutations para edição
  const updateStatus = useMutation(api.tickets.updateStatus)
  const updatePriority = useMutation(api.tickets.updatePriority)
  const changeQueue = useMutation(api.tickets.changeQueue)
  const changeAssignee = useMutation(api.tickets.changeAssignee)

  // Queries para opções (só carrega se usuário é staff e pode editar)
  const queues = useQuery(
    api.queues.listForStaff,
    canEdit && convexUserId ? { tenantId: ticket.tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const agents = useQuery(
    api.users.listAgents,
    canEdit ? { tenantId: ticket.tenantId } : "skip"
  )

  // Estados para popovers
  const [statusOpen, setStatusOpen] = useState(false)
  const [priorityOpen, setPriorityOpen] = useState(false)
  const [queueOpen, setQueueOpen] = useState(false)
  const [assigneeOpen, setAssigneeOpen] = useState(false)

  // Handlers de edição
  const handleStatusChange = async (newStatus: string) => {
    if (!convexUserId) return
    try {
      await updateStatus({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        status: newStatus,
      })
      setStatusOpen(false)
      toast.success("Status atualizado")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Erro ao atualizar status")
    }
  }

  const handlePriorityChange = async (newPriority: string) => {
    if (!convexUserId) return
    try {
      await updatePriority({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        priority: newPriority,
      })
      setPriorityOpen(false)
      toast.success("Prioridade atualizada")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Erro ao atualizar prioridade")
    }
  }

  const handleQueueChange = async (newQueue: string) => {
    if (!convexUserId) return
    try {
      await changeQueue({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        queueId: newQueue === "__none__" ? undefined : (newQueue as Id<"queues">),
      })
      setQueueOpen(false)
      toast.success("Fila atualizada")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Erro ao atualizar fila")
    }
  }

  const handleAssigneeChange = async (newAssignee: string) => {
    if (!convexUserId) return
    try {
      await changeAssignee({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        assigneeId: newAssignee === "__none__" ? undefined : (newAssignee as Id<"users">),
      })
      setAssigneeOpen(false)
      toast.success("Responsável atualizado")
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Erro ao atualizar responsável")
    }
  }

  const isAvulso = Boolean(ticket.company?.isAvulso)
  const companyLabel = ticket.company?.name ?? (isAvulso ? "Cliente avulso" : "Sem empresa vinculada")
  const responseStatus = getSlaDisplayStatus(ticket, "response")
  const solutionStatus = getSlaDisplayStatus(ticket, "solution")
  const responseDue = getSlaDueDate(ticket, "response")
  const solutionDue = getSlaDueDate(ticket, "solution")

  const summaryChips = useMemo(() => {
    const chips: SummaryChipConfig[] = [
      {
        key: "queue",
        label: "Fila",
        value: ticket.queue ?? "Sem fila",
        tone: ticket.queue ? "default" : "muted",
      },
      {
        key: "company",
        label: "Empresa",
        value: companyLabel,
        tone: isAvulso ? "warning" : "default",
      },
      {
        key: "status",
        label: "Status",
        value: getTicketStatusLabel(ticket.status) ?? ticket.status,
        tone: getTicketStatusSummaryTone(ticket.status) as SummaryTone,
      },
      {
        key: "priority",
        label: "Prioridade",
        value: priorityLabel[ticket.priority] ?? ticket.priority,
        tone: priorityTone[ticket.priority] ?? "default",
      },
      {
        key: "assignee",
        label: "Responsável",
        value: ticket.assignee?.name ?? "Não atribuído",
        tone: ticket.assignee ? "default" : "muted",
      },
    ]
    if (ticket.formTemplateLabel) {
      chips.splice(Math.min(chips.length, 5), 0, {
        key: "formTemplate",
        label: "Fluxo",
        value: ticket.formTemplateLabel,
        tone: "primary",
        labelClassName: "text-white",
      })
    }
    return chips
  }, [companyLabel, isAvulso, ticket.assignee, ticket.formTemplateLabel, ticket.priority, ticket.queue, ticket.status])

  const agentTotals = useMemo(() => {
    const totals = ticket.workSummary?.perAgentTotals ?? []
    return totals
      .map((item) => ({
        agentId: String(item.agentId),
        agentName: item.agentName ?? null,
        totalWorkedMs: item.totalWorkedMs ?? 0,
        internalWorkedMs: item.internalWorkedMs ?? 0,
        externalWorkedMs: item.externalWorkedMs ?? 0,
      }))
      .sort((a, b) => b.totalWorkedMs - a.totalWorkedMs)
  }, [ticket.workSummary?.perAgentTotals])

  return (
    <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
      <CardHeader className="px-4 pb-3">
        <div className="flex items-start justify-between gap-3">
          <div className="space-y-1">
            <CardTitle className="text-lg font-semibold text-neutral-900">Detalhes</CardTitle>
            <CardDescription className="text-sm text-neutral-500">
              Resumo do ticket, métricas de SLA, tempo dedicado e campos personalizados.
            </CardDescription>
          </div>
          {isAvulso ? (
            <Badge className="h-7 rounded-full border border-amber-200 bg-amber-50 px-3 text-xs font-semibold uppercase tracking-wide text-amber-700">
              Cliente avulso
            </Badge>
          ) : null}
        </div>
      </CardHeader>
      <CardContent className="space-y-6 px-4 pb-6">
        <section className="space-y-3">
          <h3 className="text-sm font-semibold text-neutral-900">Resumo</h3>
          <div className="grid gap-3 sm:grid-cols-2">
            {/* Fila - editável */}
            {canEdit ? (
              <Popover open={queueOpen} onOpenChange={setQueueOpen}>
                <PopoverTrigger asChild>
                  <button type="button" className="text-left w-full">
                    <SummaryChip
                      label="Fila"
                      value={ticket.queue ?? "Sem fila"}
                      tone={ticket.queue ? "default" : "muted"}
                      editable
                    />
                  </button>
                </PopoverTrigger>
                <PopoverContent className="w-64 p-0" align="start" sideOffset={4}>
                  <div className="p-3 space-y-2">
                    <p className="text-xs font-medium text-neutral-500 uppercase tracking-wide">Alterar fila</p>
                    <Select
                      value={queues?.find((q) => q.name === ticket.queue)?.id ?? "__none__"}
                      onValueChange={handleQueueChange}
                    >
                      <SelectTrigger className="h-10 bg-white">
                        <SelectValue placeholder="Selecione a fila" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="__none__">Sem fila</SelectItem>
                        {queues?.map((q) => (
                          <SelectItem key={q.id} value={q.id}>{q.name}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </PopoverContent>
              </Popover>
            ) : (
              <SummaryChip label="Fila" value={ticket.queue ?? "Sem fila"} tone={ticket.queue ? "default" : "muted"} />
            )}

            {/* Empresa - não editável */}
            <SummaryChip
              label="Empresa"
              value={companyLabel}
              tone={isAvulso ? "warning" : "default"}
            />

            {/* Status - editável */}
            {canEdit ? (
              <Popover open={statusOpen} onOpenChange={setStatusOpen}>
                <PopoverTrigger asChild>
                  <button type="button" className="text-left w-full">
                    <SummaryChip
                      label="Status"
                      value={getTicketStatusLabel(ticket.status) ?? ticket.status}
                      tone={getTicketStatusSummaryTone(ticket.status) as SummaryTone}
                      editable
                    />
                  </button>
                </PopoverTrigger>
                <PopoverContent className="w-64 p-0" align="start" sideOffset={4}>
                  <div className="p-3 space-y-2">
                    <p className="text-xs font-medium text-neutral-500 uppercase tracking-wide">Alterar status</p>
                    <StatusSelect value={ticket.status} onValueChange={handleStatusChange} />
                  </div>
                </PopoverContent>
              </Popover>
            ) : (
              <SummaryChip
                label="Status"
                value={getTicketStatusLabel(ticket.status) ?? ticket.status}
                tone={getTicketStatusSummaryTone(ticket.status) as SummaryTone}
              />
            )}

            {/* Prioridade - editável */}
            {canEdit ? (
              <Popover open={priorityOpen} onOpenChange={setPriorityOpen}>
                <PopoverTrigger asChild>
                  <button type="button" className="text-left w-full">
                    <SummaryChip
                      label="Prioridade"
                      value={priorityLabel[ticket.priority] ?? ticket.priority}
                      tone={priorityTone[ticket.priority] ?? "default"}
                      editable
                    />
                  </button>
                </PopoverTrigger>
                <PopoverContent className="w-64 p-0" align="start" sideOffset={4}>
                  <div className="p-3 space-y-2">
                    <p className="text-xs font-medium text-neutral-500 uppercase tracking-wide">Alterar prioridade</p>
                    <PrioritySelect value={ticket.priority} onValueChange={handlePriorityChange} />
                  </div>
                </PopoverContent>
              </Popover>
            ) : (
              <SummaryChip
                label="Prioridade"
                value={priorityLabel[ticket.priority] ?? ticket.priority}
                tone={priorityTone[ticket.priority] ?? "default"}
              />
            )}

            {/* Responsável - editável */}
            {canEdit ? (
              <Popover open={assigneeOpen} onOpenChange={setAssigneeOpen}>
                <PopoverTrigger asChild>
                  <button type="button" className="text-left w-full">
                    <SummaryChip
                      label="Responsável"
                      value={ticket.assignee?.name ?? "Não atribuído"}
                      tone={ticket.assignee ? "default" : "muted"}
                      editable
                    />
                  </button>
                </PopoverTrigger>
                <PopoverContent className="w-64 p-0" align="start" sideOffset={4}>
                  <div className="p-3 space-y-2">
                    <p className="text-xs font-medium text-neutral-500 uppercase tracking-wide">Alterar responsavel</p>
                    <Select value={ticket.assignee?.id ?? "__none__"} onValueChange={handleAssigneeChange}>
                      <SelectTrigger className="h-10 bg-white">
                        <SelectValue placeholder="Selecione o responsavel" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="__none__">Nao atribuido</SelectItem>
                        {agents?.map((a) => (
                          <SelectItem key={a._id} value={a._id}>{a.name}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </PopoverContent>
              </Popover>
            ) : (
              <SummaryChip
                label="Responsável"
                value={ticket.assignee?.name ?? "Não atribuído"}
                tone={ticket.assignee ? "default" : "muted"}
              />
            )}

            {/* Fluxo - não editável */}
            {ticket.formTemplateLabel && (
              <SummaryChip
                label="Fluxo"
                value={ticket.formTemplateLabel}
                tone="primary"
                labelClassName="text-white"
              />
            )}
          </div>
        </section>

        {canShowRemoteAccess ? (
          <section className="space-y-3">
            <h3 className="text-sm font-semibold text-neutral-900">Acesso remoto</h3>
            {primaryRemoteAccess ? (
              <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
                <div className="space-y-1 text-sm text-neutral-700">
                  <p className="font-medium text-neutral-900">
                    Conecte-se remotamente à máquina vinculada a este ticket.
                  </p>
                  {remoteHostname ? (
                    <p className="text-xs text-neutral-500">Host: {remoteHostname}</p>
                  ) : null}
                  {primaryRemoteAccess.identifier ? (
                    <p className="text-xs text-neutral-500">ID RustDesk: {primaryRemoteAccess.identifier}</p>
                  ) : null}
                </div>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="inline-flex items-center gap-2 border-slate-300 bg-white text-sm font-semibold text-slate-800 shadow-sm hover:border-slate-400 hover:bg-slate-50"
                  onClick={handleRemoteConnect}
                >
                  <MonitorSmartphone className="size-4 text-slate-700" />
                  Acessar remoto
                </Button>
              </div>
            ) : (
              <p className="text-xs text-neutral-500">
                Nenhum acesso remoto RustDesk está cadastrado para a máquina deste ticket.
              </p>
            )}
          </section>
        ) : null}

        <section className="space-y-3">
          <div className="flex flex-wrap items-center justify-between gap-2">
            <h3 className="text-sm font-semibold text-neutral-900">SLA & métricas</h3>
            {ticket.slaSnapshot ? (
              <span className="text-xs font-medium text-neutral-500">
                {ticket.slaSnapshot.categoryName ?? "Configuração personalizada"}
              </span>
            ) : null}
          </div>
          <div className="grid gap-3 md:grid-cols-2">
            <div className="rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
              <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Política de SLA</p>
              {ticket.slaSnapshot ? (
                <div className="mt-3 space-y-4 text-sm text-neutral-700">
                  <div>
                    <span className="text-xs text-neutral-500">Categoria</span>
                    <p className="font-semibold text-neutral-900">{ticket.slaSnapshot.categoryName ?? "Categoria padrão"}</p>
                    <p className="text-xs text-neutral-500">
                      Prioridade: {priorityLabel[ticket.priority] ?? ticket.priority}
                    </p>
                  </div>
                  <div className="grid gap-3 sm:grid-cols-2">
                    <SlaMetric
                      label="Resposta"
                      target={formatSlaTarget(ticket.slaSnapshot.responseTargetMinutes, ticket.slaSnapshot.responseMode)}
                      dueDate={responseDue}
                      status={responseStatus}
                    />
                    <SlaMetric
                      label="Resolução"
                      target={formatSlaTarget(ticket.slaSnapshot.solutionTargetMinutes, ticket.slaSnapshot.solutionMode)}
                      dueDate={solutionDue}
                      status={solutionStatus}
                    />
                  </div>
                </div>
              ) : (
                <p className="mt-3 text-sm text-neutral-600">Sem política de SLA atribuída.</p>
              )}
            </div>
            <div className="rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
              <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Métricas</p>
              {ticket.metrics ? (
                <div className="mt-3 space-y-2 text-sm text-neutral-700">
                  <div className="flex items-center justify-between gap-4">
                    <span className="text-xs text-neutral-500">Tempo aguardando</span>
                    <span className="text-sm font-semibold text-neutral-900">
                      {formatMinutes(ticket.metrics.timeWaitingMinutes)}
                    </span>
                  </div>
                  <div className="flex items-center justify-between gap-4">
                    <span className="text-xs text-neutral-500">Tempo aberto</span>
                    <span className="text-sm font-semibold text-neutral-900">
                      {formatMinutes(ticket.metrics.timeOpenedMinutes)}
                    </span>
                  </div>
                </div>
              ) : (
                <p className="mt-3 text-sm text-neutral-600">Sem dados registrados ainda.</p>
              )}
            </div>
          </div>
        </section>

        <section className="space-y-3">
          <h3 className="text-sm font-semibold text-neutral-900">Tempo por agente</h3>
          {agentTotals.length > 0 ? (
            <div className="grid gap-2">
              {agentTotals.map((agent) => (
                <div
                  key={agent.agentId}
                  className="rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm"
                >
                  <div className="flex items-center justify-between gap-4">
                    <span className="text-sm font-semibold text-neutral-900">
                      {agent.agentName ?? "Agente removido"}
                    </span>
                    <span className="text-sm font-semibold text-neutral-900">
                      {formatDuration(agent.totalWorkedMs)}
                    </span>
                  </div>
                  <div className="mt-2 flex flex-wrap gap-4 text-xs text-neutral-500">
                    <span>
                      Interno:{" "}
                      <span className="font-medium text-neutral-800">{formatDuration(agent.internalWorkedMs)}</span>
                    </span>
                    <span>
                      Externo:{" "}
                      <span className="font-medium text-neutral-800">{formatDuration(agent.externalWorkedMs)}</span>
                    </span>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <p className="text-sm text-neutral-600">Nenhum tempo registrado neste ticket ainda.</p>
          )}
        </section>

        <section className="space-y-3">
          <h3 className="text-sm font-semibold text-neutral-900">Histórico</h3>
          <div className="rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm text-sm text-neutral-700">
            <div className="flex items-center justify-between gap-4 border-b border-slate-100 pb-2">
              <span className="text-xs uppercase tracking-wide text-neutral-500">Criado em</span>
              <span className="font-semibold text-neutral-900">
                {format(ticket.createdAt, "dd/MM/yyyy HH:mm", { locale: ptBR })}
              </span>
            </div>
            <div className="flex items-center justify-between gap-4 border-b border-slate-100 py-2">
              <span className="text-xs uppercase tracking-wide text-neutral-500">Atualizado em</span>
              <span className="font-semibold text-neutral-900">
                {format(ticket.updatedAt, "dd/MM/yyyy HH:mm", { locale: ptBR })}
              </span>
            </div>
            <div className="flex items-center justify-between gap-4 pt-2">
              <span className="text-xs uppercase tracking-wide text-neutral-500">Resolvido em</span>
              <span className="font-semibold text-neutral-900">
                {ticket.resolvedAt ? format(ticket.resolvedAt, "dd/MM/yyyy HH:mm", { locale: ptBR }) : "—"}
              </span>
            </div>
          </div>
        </section>
      </CardContent>
    </Card>
  )
}

function SummaryChip({
  label,
  value,
  tone = "default",
  labelClassName,
  editable = false,
}: {
  label: string
  value: string
  tone?: SummaryTone
  labelClassName?: string
  editable?: boolean
}) {
  const toneClasses: Record<SummaryTone, string> = {
    default: "border-slate-200 bg-white text-neutral-900",
    info: "border-sky-200 bg-sky-50 text-sky-900",
    warning: "border-amber-200 bg-amber-50 text-amber-800",
    success: "border-emerald-200 bg-emerald-50 text-emerald-800",
    muted: "border-slate-200 bg-slate-50 text-neutral-600",
    danger: "border-rose-200 bg-rose-50 text-rose-700",
    primary: "border-black bg-black text-white",
  }

  return (
    <div
      className={cn(
        "rounded-xl border px-3 py-2 shadow-sm transition-all",
        toneClasses[tone],
        editable && "cursor-pointer hover:ring-2 hover:ring-slate-300 hover:border-slate-400"
      )}
    >
      <p className={cn("text-[11px] font-semibold uppercase tracking-wide text-neutral-500", labelClassName)}>{label}</p>
      <p className="mt-1 truncate text-sm font-semibold text-current">{value}</p>
    </div>
  )
}

interface SlaMetricProps {
  label: string
  target: string
  dueDate: Date | null
  status: SlaDisplayStatus
}

function SlaMetric({ label, target, dueDate, status }: SlaMetricProps) {
  const display = getSlaStatusDisplay(status)
  return (
    <div className="rounded-xl border border-slate-200 bg-white px-3 py-3 shadow-sm">
      <div className="flex items-center justify-between gap-3">
        <div>
          <p className="text-xs text-neutral-500">{label}</p>
          <p className="text-sm font-semibold text-neutral-900">{target}</p>
          {dueDate ? (
            <p className="text-xs text-neutral-500">{format(dueDate, "dd/MM/yyyy HH:mm", { locale: ptBR })}</p>
          ) : (
            <p className="text-xs text-neutral-500">Sem prazo calculado</p>
          )}
        </div>
        <span className={cn("text-xs font-semibold uppercase", display.className)}>{display.label}</span>
      </div>
    </div>
  )
}
