"use client"

import { useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { Globe, Plus } from "lucide-react"
import { IconAlarm, IconBolt, IconTargetArrow } from "@tabler/icons-react"
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 { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Skeleton } from "@/components/ui/skeleton"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { cn } from "@/lib/utils"

import { CategorySlaManager } from "./category-sla-manager"
import { CompanySlaManager } from "./company-sla-manager"

type SlaPolicy = {
  id: string
  name: string
  description: string
  timeToFirstResponse: number | null
  responseMode: "business" | "calendar"
  timeToResolution: number | null
  solutionMode: "business" | "calendar"
  alertThreshold: number
  pauseStatuses: string[]
}

type TimeUnit = "minutes" | "hours" | "days"
type TimeMode = "business" | "calendar"

const TIME_UNITS: Array<{ value: TimeUnit; label: string; factor: number }> = [
  { value: "minutes", label: "Minutos", factor: 1 },
  { value: "hours", label: "Horas", factor: 60 },
  { value: "days", label: "Dias", factor: 1440 },
]

const MODE_OPTIONS: Array<{ value: TimeMode; label: string }> = [
  { value: "calendar", label: "Horas corridas" },
  { value: "business", label: "Horas úteis" },
]

const PAUSE_STATUS_OPTIONS = [
  { value: "PENDING", label: "Pendente" },
  { value: "AWAITING_ATTENDANCE", label: "Em atendimento" },
  { value: "PAUSED", label: "Pausado" },
] as const

function formatMinutes(value: number | null) {
  if (value === null) return "—"
  if (value < 60) return `${Math.round(value)} min`
  const hours = Math.floor(value / 60)
  const minutes = Math.round(value % 60)
  if (minutes === 0) return `${hours}h`
  return `${hours}h ${minutes}min`
}

function minutesToForm(input: number | null): { amount: string; unit: TimeUnit } {
  if (!input || input <= 0) return { amount: "", unit: "hours" }
  for (const option of [...TIME_UNITS].reverse()) {
    if (input % option.factor === 0) {
      return { amount: String(Math.round(input / option.factor)), unit: option.value }
    }
  }
  return { amount: String(input), unit: "minutes" }
}

function convertToMinutes(amount: string, unit: TimeUnit): number | undefined {
  const numeric = Number(amount)
  if (!Number.isFinite(numeric) || numeric <= 0) return undefined
  const factor = TIME_UNITS.find((item) => item.value === unit)?.factor ?? 1
  return Math.round(numeric * factor)
}

export function SlasManager() {
  const { session, convexUserId } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID

  const slas = useQuery(
    api.slas.list,
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as SlaPolicy[] | undefined

  const createSla = useMutation(api.slas.create)
  const updateSla = useMutation(api.slas.update)
  const removeSla = useMutation(api.slas.remove)

  const [dialogOpen, setDialogOpen] = useState(false)
  const [editingSla, setEditingSla] = useState<SlaPolicy | null>(null)
  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [responseAmount, setResponseAmount] = useState("")
  const [responseUnit, setResponseUnit] = useState<TimeUnit>("hours")
  const [responseMode, setResponseMode] = useState<TimeMode>("calendar")
  const [resolutionAmount, setResolutionAmount] = useState("")
  const [resolutionUnit, setResolutionUnit] = useState<TimeUnit>("hours")
  const [solutionMode, setSolutionMode] = useState<TimeMode>("calendar")
  const [alertThreshold, setAlertThreshold] = useState(80)
  const [pauseStatuses, setPauseStatuses] = useState<string[]>(["PAUSED"])
  const [saving, setSaving] = useState(false)

  const { bestFirstResponse, bestResolution } = useMemo(() => {
    if (!slas) return { bestFirstResponse: null, bestResolution: null }

    const response = slas.reduce<number | null>((acc, sla) => {
      if (sla.timeToFirstResponse === null) return acc
      return acc === null ? sla.timeToFirstResponse : Math.min(acc, sla.timeToFirstResponse)
    }, null)

    const resolution = slas.reduce<number | null>((acc, sla) => {
      if (sla.timeToResolution === null) return acc
      return acc === null ? sla.timeToResolution : Math.min(acc, sla.timeToResolution)
    }, null)

    return { bestFirstResponse: response, bestResolution: resolution }
  }, [slas])

  const resetForm = () => {
    setName("")
    setDescription("")
    setResponseAmount("")
    setResponseUnit("hours")
    setResponseMode("calendar")
    setResolutionAmount("")
    setResolutionUnit("hours")
    setSolutionMode("calendar")
    setAlertThreshold(80)
    setPauseStatuses(["PAUSED"])
  }

  const openCreateDialog = () => {
    resetForm()
    setEditingSla(null)
    setDialogOpen(true)
  }

  const openEditDialog = (policy: SlaPolicy) => {
    const response = minutesToForm(policy.timeToFirstResponse)
    const resolution = minutesToForm(policy.timeToResolution)
    setEditingSla(policy)
    setName(policy.name)
    setDescription(policy.description)
    setResponseAmount(response.amount)
    setResponseUnit(response.unit)
    setResponseMode(policy.responseMode ?? "calendar")
    setResolutionAmount(resolution.amount)
    setResolutionUnit(resolution.unit)
    setSolutionMode(policy.solutionMode ?? "calendar")
    setAlertThreshold(Math.round((policy.alertThreshold ?? 0.8) * 100))
    setPauseStatuses(policy.pauseStatuses ?? ["PAUSED"])
    setDialogOpen(true)
  }

  const togglePauseStatus = (status: string) => {
    setPauseStatuses((current) => {
      const selected = new Set(current)
      if (selected.has(status)) {
        selected.delete(status)
      } else {
        selected.add(status)
      }
      if (selected.size === 0) {
        selected.add("PAUSED")
      }
      return Array.from(selected)
    })
  }

  const closeDialog = () => {
    setDialogOpen(false)
    setEditingSla(null)
    resetForm()
  }

  const handleSave = async () => {
    if (!name.trim()) {
      toast.error("Informe um nome para a política")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }

    const timeToFirstResponse = convertToMinutes(responseAmount, responseUnit)
    const timeToResolution = convertToMinutes(resolutionAmount, resolutionUnit)

    setSaving(true)
    const toastId = editingSla ? "sla-edit" : "sla-create"
    toast.loading(editingSla ? "Salvando alterações..." : "Criando política...", { id: toastId })

    const normalizedThreshold = Math.min(Math.max(alertThreshold, 10), 95) / 100

    try {
      if (editingSla) {
        await updateSla({
          tenantId,
          policyId: editingSla.id as Id<"slaPolicies">,
          actorId: convexUserId as Id<"users">,
          name: name.trim(),
          description: description.trim() || undefined,
          timeToFirstResponse,
          responseMode,
          timeToResolution,
          solutionMode,
          alertThreshold: normalizedThreshold,
          pauseStatuses,
        })
        toast.success("Política atualizada", { id: toastId })
      } else {
        await createSla({
          tenantId,
          actorId: convexUserId as Id<"users">,
          name: name.trim(),
          description: description.trim() || undefined,
          timeToFirstResponse,
          responseMode,
          timeToResolution,
          solutionMode,
          alertThreshold: normalizedThreshold,
          pauseStatuses,
        })
        toast.success("Política criada", { id: toastId })
      }
      closeDialog()
    } catch (error) {
      console.error(error)
      toast.error(editingSla ? "Não foi possível atualizar a política" : "Não foi possível criar a política", { id: toastId })
    } finally {
      setSaving(false)
    }
  }

  const handleRemove = async (policy: SlaPolicy) => {
    const confirmed = window.confirm(`Excluir a política ${policy.name}?`)
    if (!confirmed) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    toast.loading("Removendo política...", { id: `sla-remove-${policy.id}` })
    try {
      await removeSla({
        tenantId,
        policyId: policy.id as Id<"slaPolicies">,
        actorId: convexUserId as Id<"users">,
      })
      toast.success("Política removida", { id: `sla-remove-${policy.id}` })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover a política", { id: `sla-remove-${policy.id}` })
    }
  }

  return (
    <div className="space-y-8">
      {/* Cards de resumo */}
      <div className="grid gap-4 md:grid-cols-3">
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconTargetArrow className="size-4" /> Políticas globais
            </CardTitle>
            <CardDescription>Regras que valem para todas as empresas.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {slas ? slas.length : <Skeleton className="h-8 w-16" />}
          </CardContent>
        </Card>
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconAlarm className="size-4" /> Melhor resposta
            </CardTitle>
            <CardDescription>Menor meta de primeira resposta.</CardDescription>
          </CardHeader>
          <CardContent className="text-xl font-semibold text-neutral-900">
            {slas ? formatMinutes(bestFirstResponse ?? null) : <Skeleton className="h-8 w-24" />}
          </CardContent>
        </Card>
        <Card className="border-slate-200">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-neutral-600">
              <IconBolt className="size-4" /> Melhor resolução
            </CardTitle>
            <CardDescription>Menor meta para encerrar chamados.</CardDescription>
          </CardHeader>
          <CardContent className="text-xl font-semibold text-neutral-900">
            {slas ? formatMinutes(bestResolution ?? null) : <Skeleton className="h-8 w-24" />}
          </CardContent>
        </Card>
      </div>

      {/* Políticas globais de SLA */}
      <Card className="border-slate-200">
        <CardHeader>
          <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
            <div>
              <CardTitle className="flex items-center gap-2 text-lg font-semibold text-neutral-900">
                <Globe className="size-5" />
                Políticas globais de SLA
              </CardTitle>
              <CardDescription className="mt-1">
                Estas regras valem para todas as empresas e categorias. São sobrescritas por regras mais específicas
                (por empresa ou por categoria).
              </CardDescription>
            </div>
            <Button size="sm" onClick={openCreateDialog} disabled={!convexUserId} className="gap-2 shrink-0">
              <Plus className="size-4" />
              Nova política
            </Button>
          </div>
        </CardHeader>
        <CardContent className="space-y-4">
          {slas === undefined ? (
            <div className="space-y-3">
              {Array.from({ length: 2 }).map((_, index) => (
                <Skeleton key={`sla-skeleton-${index}`} className="h-20 rounded-xl" />
              ))}
            </div>
          ) : slas.length === 0 ? (
            <div className="rounded-xl border border-dashed border-slate-300 bg-slate-50/80 p-6 text-center">
              <Globe className="mx-auto size-8 text-slate-400" />
              <p className="mt-2 text-sm font-medium text-neutral-700">Nenhuma política global cadastrada</p>
              <p className="mt-1 text-xs text-neutral-500">
                Crie políticas de SLA para definir metas de resposta e resolução para os chamados.
              </p>
            </div>
          ) : (
            <div className="space-y-3">
              {slas.map((policy) => (
                <div
                  key={policy.id}
                  className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-slate-200 bg-white px-4 py-3"
                >
                  <div className="space-y-1">
                    <div className="flex items-center gap-2">
                      <p className="text-sm font-semibold text-neutral-900">{policy.name}</p>
                      <Badge variant="secondary" className="rounded-full text-xs">
                        <Globe className="mr-1 size-3" />
                        Global
                      </Badge>
                    </div>
                    {policy.description && (
                      <p className="text-xs text-neutral-500">{policy.description}</p>
                    )}
                    <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-neutral-600">
                      <span>
                        Resposta: {formatMinutes(policy.timeToFirstResponse)}
                        {policy.timeToFirstResponse !== null && (
                          <span className="ml-1 text-neutral-400">
                            ({policy.responseMode === "business" ? "horas úteis" : "corrido"})
                          </span>
                        )}
                      </span>
                      <span>
                        Resolução: {formatMinutes(policy.timeToResolution)}
                        {policy.timeToResolution !== null && (
                          <span className="ml-1 text-neutral-400">
                            ({policy.solutionMode === "business" ? "horas úteis" : "corrido"})
                          </span>
                        )}
                      </span>
                      <span>Alerta: {Math.round(policy.alertThreshold * 100)}%</span>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <Button size="sm" variant="secondary" onClick={() => openEditDialog(policy)} disabled={!convexUserId}>
                      Editar
                    </Button>
                    <Button size="sm" variant="destructive" onClick={() => handleRemove(policy)} disabled={!convexUserId}>
                      Excluir
                    </Button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* SLA por empresa */}
      <CompanySlaManager />

      {/* SLA por categoria */}
      <CategorySlaManager />

      {/* Modal unificado de criar/editar */}
      <Dialog open={dialogOpen} onOpenChange={(open) => !open && closeDialog()}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>{editingSla ? "Editar política de SLA" : "Nova política de SLA"}</DialogTitle>
            <DialogDescription>
              {editingSla
                ? "Altere os dados da política. Ela continua valendo para todas as empresas e categorias."
                : "Crie uma política global que vale para todas as empresas e categorias. Você pode criar regras mais específicas depois."}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label htmlFor="sla-name">Nome da política</Label>
              <Input
                id="sla-name"
                placeholder="Ex.: Atendimento padrão, Premium, Urgente..."
                value={name}
                onChange={(event) => setName(event.target.value)}
                autoFocus
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="sla-description">Descrição (opcional)</Label>
              <textarea
                id="sla-description"
                className="min-h-[80px] w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-neutral-700 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900/10"
                placeholder="Quando esta política deve ser usada, para quais tipos de chamado..."
                value={description}
                onChange={(event) => setDescription(event.target.value)}
              />
            </div>
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label>Tempo para primeira resposta</Label>
                <p className="text-xs text-neutral-500">Quanto tempo a equipe tem para dar a primeira resposta ao cliente.</p>
                <div className="flex gap-2">
                  <Input
                    type="number"
                    min={1}
                    placeholder="0"
                    value={responseAmount}
                    onChange={(event) => setResponseAmount(event.target.value)}
                    className="flex-1"
                  />
                  <Select value={responseUnit} onValueChange={(value) => setResponseUnit(value as TimeUnit)}>
                    <SelectTrigger className="w-28">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {TIME_UNITS.map((unit) => (
                        <SelectItem key={unit.value} value={unit.value}>
                          {unit.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <Select value={responseMode} onValueChange={(value) => setResponseMode(value as TimeMode)}>
                  <SelectTrigger className="w-full">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {MODE_OPTIONS.map((mode) => (
                      <SelectItem key={mode.value} value={mode.value}>
                        {mode.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label>Tempo para resolução</Label>
                <p className="text-xs text-neutral-500">Quanto tempo a equipe tem para resolver o chamado por completo.</p>
                <div className="flex gap-2">
                  <Input
                    type="number"
                    min={1}
                    placeholder="0"
                    value={resolutionAmount}
                    onChange={(event) => setResolutionAmount(event.target.value)}
                    className="flex-1"
                  />
                  <Select value={resolutionUnit} onValueChange={(value) => setResolutionUnit(value as TimeUnit)}>
                    <SelectTrigger className="w-28">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {TIME_UNITS.map((unit) => (
                        <SelectItem key={unit.value} value={unit.value}>
                          {unit.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <Select value={solutionMode} onValueChange={(value) => setSolutionMode(value as TimeMode)}>
                  <SelectTrigger className="w-full">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {MODE_OPTIONS.map((mode) => (
                      <SelectItem key={mode.value} value={mode.value}>
                        {mode.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label>Alerta de proximidade</Label>
                <p className="text-xs text-neutral-500">
                  Percentual do tempo em que o sistema emitirá alerta antes do vencimento.
                </p>
                <div className="flex items-center gap-2">
                  <Input
                    type="number"
                    min={10}
                    max={95}
                    value={alertThreshold}
                    onChange={(event) => setAlertThreshold(Number(event.target.value))}
                    className="w-20"
                  />
                  <span className="text-sm text-neutral-500">%</span>
                </div>
              </div>
              <div className="space-y-2">
                <Label>Status que pausam o SLA</Label>
                <p className="text-xs text-neutral-500">
                  Quando o chamado estiver em um desses status, o cronômetro do SLA será pausado.
                </p>
                <div className="flex flex-wrap gap-2">
                  {PAUSE_STATUS_OPTIONS.map((option) => (
                    <button
                      key={option.value}
                      type="button"
                      onClick={() => togglePauseStatus(option.value)}
                      className={cn(
                        "rounded-full px-3 py-1 text-xs font-medium transition-colors",
                        pauseStatuses.includes(option.value)
                          ? "bg-neutral-900 text-white"
                          : "bg-slate-100 text-neutral-600 hover:bg-slate-200"
                      )}
                    >
                      {option.label}
                    </button>
                  ))}
                </div>
              </div>
            </div>
            <div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
              <p className="text-xs text-blue-800">
                <strong>Dica:</strong> Esta política é global e será aplicada a todos os chamados que não tiverem uma
                regra mais específica (por empresa ou categoria). Use as seções abaixo para criar regras personalizadas.
              </p>
            </div>
          </div>
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={closeDialog}>
              Cancelar
            </Button>
            <Button onClick={handleSave} disabled={saving || !name.trim()}>
              {saving ? "Salvando..." : editingSla ? "Salvar alterações" : "Criar política"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
