"use client"

import { useEffect, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { AlertTriangle, Trash2 } from "lucide-react"

import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

const PRIORITY_ROWS = [
  { value: "URGENT", label: "Crítico" },
  { value: "HIGH", label: "Alta" },
  { value: "MEDIUM", label: "Média" },
  { value: "LOW", label: "Baixa" },
  { value: "DEFAULT", label: "Sem prioridade" },
] as const

const TIME_UNITS: Array<{ value: RuleFormState["responseUnit"]; 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: RuleFormState["responseMode"]; 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

const DEFAULT_RULE_STATE: RuleFormState = {
  responseValue: "",
  responseUnit: "hours",
  responseMode: "calendar",
  solutionValue: "",
  solutionUnit: "hours",
  solutionMode: "calendar",
  alertThreshold: 80,
  pauseStatuses: ["PAUSED"],
}

type RuleFormState = {
  responseValue: string
  responseUnit: "minutes" | "hours" | "days"
  responseMode: "calendar" | "business"
  solutionValue: string
  solutionUnit: "minutes" | "hours" | "days"
  solutionMode: "calendar" | "business"
  alertThreshold: number
  pauseStatuses: string[]
}

export type CompanySlaDrawerProps = {
  company: { id: string; name: string } | null
  tenantId: string
  viewerId: Id<"users"> | null
  onClose: () => void
}

export function CompanySlaDrawer({ company, tenantId, viewerId, onClose }: CompanySlaDrawerProps) {
  const [rules, setRules] = useState<Record<string, RuleFormState>>(() => buildDefaultRuleState())
  const [saving, setSaving] = useState(false)
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const drawerOpen = Boolean(company)

  const canLoad = Boolean(company?.id && viewerId)
  const existing = useQuery(
    api.companySlas.get,
    canLoad && company?.id
      ? {
          tenantId,
          viewerId: viewerId as Id<"users">,
          companyId: company.id as Id<"companies">,
        }
      : "skip"
  ) as {
    companyId: string
    companyName: string
    rules: Array<{
      priority: string
      categoryId: string | null
      categoryName: string | null
      responseTargetMinutes: number | null
      responseMode?: string | null
      solutionTargetMinutes: number | null
      solutionMode?: string | null
      alertThreshold?: number | null
      pauseStatuses?: string[] | null
    }>
  } | undefined

  const saveSla = useMutation(api.companySlas.save)
  const removeSla = useMutation(api.companySlas.remove)

  useEffect(() => {
    if (!existing?.rules) {
      setRules(buildDefaultRuleState())
      return
    }
    const next = buildDefaultRuleState()
    // Filtrar apenas regras globais (sem categoryId) por enquanto
    for (const rule of existing.rules.filter((r) => !r.categoryId)) {
      const priority = rule.priority?.toUpperCase() ?? "DEFAULT"
      next[priority] = convertRuleToForm(rule)
    }
    setRules(next)
  }, [existing, company?.id])

  const handleChange = (priority: string, patch: Partial<RuleFormState>) => {
    setRules((current) => ({
      ...current,
      [priority]: {
        ...current[priority],
        ...patch,
      },
    }))
  }

  const togglePause = (priority: string, status: string) => {
    setRules((current) => {
      const selected = new Set(current[priority].pauseStatuses)
      if (selected.has(status)) {
        selected.delete(status)
      } else {
        selected.add(status)
      }
      if (selected.size === 0) {
        selected.add("PAUSED")
      }
      return {
        ...current,
        [priority]: {
          ...current[priority],
          pauseStatuses: Array.from(selected),
        },
      }
    })
  }

  const handleSave = async () => {
    if (!company || !viewerId) return
    setSaving(true)
    toast.loading("Salvando SLA...", { id: "company-sla" })
    try {
      const payload = PRIORITY_ROWS.map((row) => {
        const form = rules[row.value]
        return {
          priority: row.value,
          categoryId: null, // Regras globais da empresa
          responseTargetMinutes: convertToMinutes(form.responseValue, form.responseUnit),
          responseMode: form.responseMode,
          solutionTargetMinutes: convertToMinutes(form.solutionValue, form.solutionUnit),
          solutionMode: form.solutionMode,
          alertThreshold: Math.min(Math.max(form.alertThreshold, 5), 95) / 100,
          pauseStatuses: form.pauseStatuses,
        }
      })
      await saveSla({
        tenantId,
        actorId: viewerId,
        companyId: company.id as Id<"companies">,
        rules: payload,
      })
      toast.success("SLA atualizado", { id: "company-sla" })
      onClose()
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível salvar as regras de SLA.", { id: "company-sla" })
    } finally {
      setSaving(false)
    }
  }

  const handleDelete = async () => {
    if (!company || !viewerId) return
    setDeleting(true)
    toast.loading("Removendo SLA...", { id: "company-sla-delete" })
    try {
      await removeSla({
        tenantId,
        actorId: viewerId,
        companyId: company.id as Id<"companies">,
      })
      toast.success("SLA removido", { id: "company-sla-delete" })
      setDeleteConfirmOpen(false)
      onClose()
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover o SLA.", { id: "company-sla-delete" })
    } finally {
      setDeleting(false)
    }
  }

  const hasExistingRules = existing?.rules && existing.rules.length > 0

  return (
    <>
      <Dialog
        open={drawerOpen}
        onOpenChange={(open) => {
          if (!open) {
            onClose()
          }
        }}
      >
        <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Configurar SLA - {company?.name ?? ""}</DialogTitle>
            <DialogDescription>
              Defina metas de resposta e resolução para cada prioridade. Estas regras têm prioridade sobre as regras
              por categoria.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            {PRIORITY_ROWS.map((row) => {
              const form = rules[row.value]
              return (
                <div key={row.value} className="space-y-3 rounded-2xl border border-slate-200 bg-white/80 p-4 shadow-sm">
                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <div>
                      <p className="text-sm font-semibold text-neutral-900">{row.label}</p>
                      <p className="text-xs text-neutral-500">
                        {row.value === "DEFAULT"
                          ? "Aplicado quando o ticket não tem prioridade definida."
                          : "Aplica-se aos tickets desta prioridade."}
                      </p>
                    </div>
                  </div>
                  <div className="grid gap-4 md:grid-cols-2">
                    <SlaInputGroup
                      title="Tempo de resposta"
                      amount={form.responseValue}
                      unit={form.responseUnit}
                      mode={form.responseMode}
                      onAmountChange={(value) => handleChange(row.value, { responseValue: value })}
                      onUnitChange={(value) =>
                        handleChange(row.value, { responseUnit: value as RuleFormState["responseUnit"] })
                      }
                      onModeChange={(value) =>
                        handleChange(row.value, { responseMode: value as RuleFormState["responseMode"] })
                      }
                    />
                    <SlaInputGroup
                      title="Tempo de solução"
                      amount={form.solutionValue}
                      unit={form.solutionUnit}
                      mode={form.solutionMode}
                      onAmountChange={(value) => handleChange(row.value, { solutionValue: value })}
                      onUnitChange={(value) =>
                        handleChange(row.value, { solutionUnit: value as RuleFormState["solutionUnit"] })
                      }
                      onModeChange={(value) =>
                        handleChange(row.value, { solutionMode: value as RuleFormState["solutionMode"] })
                      }
                    />
                  </div>
                  <div className="grid gap-4 md:grid-cols-2">
                    <div>
                      <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Alertar quando</p>
                      <div className="mt-2 flex items-center gap-2">
                        <Input
                          type="number"
                          min={10}
                          max={95}
                          step={5}
                          value={form.alertThreshold}
                          onChange={(event) => handleChange(row.value, { alertThreshold: Number(event.target.value) || 0 })}
                        />
                        <span className="text-xs text-neutral-500">% do tempo for consumido.</span>
                      </div>
                    </div>
                    <div>
                      <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Estados que pausam</p>
                      <div className="mt-2 flex flex-wrap gap-2">
                        {PAUSE_STATUS_OPTIONS.map((option) => {
                          const selected = form.pauseStatuses.includes(option.value)
                          return (
                            <button
                              key={option.value}
                              type="button"
                              onClick={() => togglePause(row.value, option.value)}
                              className={cn(
                                "rounded-full border px-3 py-1 text-xs font-semibold transition",
                                selected
                                  ? "border-primary bg-primary text-primary-foreground"
                                  : "border-slate-200 bg-white text-neutral-600"
                              )}
                            >
                              {option.label}
                            </button>
                          )
                        })}
                      </div>
                    </div>
                  </div>
                </div>
              )
            })}
          </div>
          <DialogFooter className="flex-col gap-2 sm:flex-row sm:justify-between">
            <div>
              {hasExistingRules && (
                <Button
                  variant="outline"
                  onClick={() => setDeleteConfirmOpen(true)}
                  className="gap-2 text-destructive hover:text-destructive"
                >
                  <Trash2 className="size-4" />
                  Remover SLA
                </Button>
              )}
            </div>
            <div className="flex gap-2">
              <Button variant="outline" onClick={onClose}>
                Cancelar
              </Button>
              <Button onClick={handleSave} disabled={saving || !viewerId}>
                {saving ? "Salvando..." : "Salvar"}
              </Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Confirmação de exclusão */}
      <Dialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2 text-destructive">
              <AlertTriangle className="size-5" />
              Remover SLA da empresa
            </DialogTitle>
            <DialogDescription>
              Esta ação irá remover todas as regras de SLA personalizadas da empresa{" "}
              <span className="font-semibold">{company?.name}</span>. Os tickets passarão a usar as regras por
              categoria.
            </DialogDescription>
          </DialogHeader>
          <div className="flex justify-end gap-2 pt-2">
            <Button variant="outline" onClick={() => setDeleteConfirmOpen(false)} disabled={deleting}>
              Cancelar
            </Button>
            <Button variant="destructive" onClick={handleDelete} disabled={deleting} className="gap-2">
              {deleting ? "Removendo..." : (<><Trash2 className="size-4" /> Remover</>)}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </>
  )
}

function buildDefaultRuleState() {
  return PRIORITY_ROWS.reduce<Record<string, RuleFormState>>((acc, row) => {
    acc[row.value] = { ...DEFAULT_RULE_STATE }
    return acc
  }, {})
}

function convertRuleToForm(rule: {
  priority: string
  responseTargetMinutes: number | null
  responseMode?: string | null
  solutionTargetMinutes: number | null
  solutionMode?: string | null
  alertThreshold?: number | null
  pauseStatuses?: string[] | null
}): RuleFormState {
  const response = minutesToForm(rule.responseTargetMinutes)
  const solution = minutesToForm(rule.solutionTargetMinutes)
  return {
    responseValue: response.amount,
    responseUnit: response.unit,
    responseMode: (rule.responseMode ?? "calendar") as RuleFormState["responseMode"],
    solutionValue: solution.amount,
    solutionUnit: solution.unit,
    solutionMode: (rule.solutionMode ?? "calendar") as RuleFormState["solutionMode"],
    alertThreshold: Math.round((rule.alertThreshold ?? 0.8) * 100),
    pauseStatuses: rule.pauseStatuses && rule.pauseStatuses.length > 0 ? rule.pauseStatuses : ["PAUSED"],
  }
}

function minutesToForm(input?: number | null) {
  if (!input || input <= 0) {
    return { amount: "", unit: "hours" as RuleFormState["responseUnit"] }
  }
  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" as RuleFormState["responseUnit"] }
}

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

type SlaInputGroupProps = {
  title: string
  amount: string
  unit: RuleFormState["responseUnit"]
  mode: RuleFormState["responseMode"]
  onAmountChange: (value: string) => void
  onUnitChange: (value: string) => void
  onModeChange: (value: string) => void
}

function SlaInputGroup({ title, amount, unit, mode, onAmountChange, onUnitChange, onModeChange }: SlaInputGroupProps) {
  return (
    <div className="space-y-2 rounded-xl border border-slate-200 bg-white px-3 py-3">
      <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">{title}</p>
      <div className="flex flex-col gap-2 md:flex-row">
        <Input
          type="number"
          min={0}
          step={1}
          value={amount}
          onChange={(event) => onAmountChange(event.target.value)}
          placeholder="0"
        />
        <Select value={unit} onValueChange={onUnitChange}>
          <SelectTrigger>
            <SelectValue placeholder="Unidade" />
          </SelectTrigger>
          <SelectContent>
            {TIME_UNITS.map((option) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
      <Select value={mode} onValueChange={onModeChange}>
        <SelectTrigger>
          <SelectValue placeholder="Tipo de contagem" />
        </SelectTrigger>
        <SelectContent>
          {MODE_OPTIONS.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  )
}
