"use client"

import { useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { IconInbox, IconHierarchy2, IconLink, IconPlus } 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 { 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 { Badge } from "@/components/ui/badge"
import { Skeleton } from "@/components/ui/skeleton"
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { useDefaultQueues } from "@/hooks/use-default-queues"

type Queue = {
  id: string
  name: string
  slug: string
  team: { id: string; name: string } | null
}

type TeamOption = {
  id: string
  name: string
}

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

  const NO_TEAM_VALUE = "__none__"

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

  const createQueue = useMutation(api.queues.create)
  const updateQueue = useMutation(api.queues.update)
  const removeQueue = useMutation(api.queues.remove)

  const [name, setName] = useState("")
  const [teamId, setTeamId] = useState<string | undefined>()
  const [editingQueue, setEditingQueue] = useState<Queue | null>(null)
  const [saving, setSaving] = useState(false)

  const totalQueues = queues?.length ?? 0
  const withoutTeam = useMemo(() => {
    if (!queues) return 0
    return queues.filter((queue) => !queue.team).length
  }, [queues])

  const handleCreate = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    if (!name.trim()) {
      toast.error("Informe o nome da fila")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    setSaving(true)
    toast.loading("Criando fila...", { id: "queue" })
    try {
      await createQueue({
        tenantId,
        actorId: convexUserId as Id<"users">,
        name: name.trim(),
        teamId: teamId as Id<"teams"> | undefined,
      })
      setName("")
      setTeamId(undefined)
      toast.success("Fila criada", { id: "queue" })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar a fila", { id: "queue" })
    } finally {
      setSaving(false)
    }
  }

  const openEdit = (queue: Queue) => {
    setEditingQueue(queue)
    setName(queue.name)
    setTeamId(queue.team?.id)
  }

  const handleUpdate = async () => {
    if (!editingQueue) return
    if (!name.trim()) {
      toast.error("Informe o nome da fila")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    setSaving(true)
    toast.loading("Salvando alterações...", { id: "queue-edit" })
    try {
      await updateQueue({
        queueId: editingQueue.id as Id<"queues">,
        tenantId,
        actorId: convexUserId as Id<"users">,
        name: name.trim(),
        teamId: (teamId ?? undefined) as Id<"teams"> | undefined,
      })
      toast.success("Fila atualizada", { id: "queue-edit" })
      setEditingQueue(null)
      setName("")
      setTeamId(undefined)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível atualizar a fila", { id: "queue-edit" })
    } finally {
      setSaving(false)
    }
  }

  const handleRemove = async (queue: Queue) => {
    const confirmed = window.confirm(`Remover a fila ${queue.name}?`)
    if (!confirmed) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    toast.loading("Removendo fila...", { id: `queue-remove-${queue.id}` })
    try {
      await removeQueue({ tenantId, queueId: queue.id as Id<"queues">, actorId: convexUserId as Id<"users"> })
      toast.success("Fila removida", { id: `queue-remove-${queue.id}` })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover a fila", { id: `queue-remove-${queue.id}` })
    }
  }

  return (
    <div className="space-y-8">
      <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">
              <IconInbox className="size-4" /> Filas criadas
            </CardTitle>
            <CardDescription>Rotas que recebem tickets dos canais conectados.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {queues ? totalQueues : <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">
              <IconHierarchy2 className="size-4" /> Com time definido
            </CardTitle>
            <CardDescription>Filas com time responsável atribuído.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {queues ? totalQueues - withoutTeam : <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">
              <IconLink className="size-4" /> Sem vinculação
            </CardTitle>
            <CardDescription>Filas aguardando responsáveis.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {queues ? withoutTeam : <Skeleton className="h-8 w-16" />}
          </CardContent>
        </Card>
      </div>

      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-lg font-semibold text-neutral-900">
            <IconPlus className="size-5 text-neutral-500" /> Nova fila
          </CardTitle>
          <CardDescription>Defina as filas de atendimento, conectando-as aos times responsáveis.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleCreate} className="grid gap-4 md:grid-cols-[minmax(0,300px)_minmax(0,300px)_auto]">
            <div className="space-y-2">
              <Label htmlFor="queue-name">Nome da fila</Label>
              <Input
                id="queue-name"
                placeholder="Ex.: Suporte N1"
                value={name}
                onChange={(event) => setName(event.target.value)}
                required
              />
            </div>
            <div className="space-y-2">
              <Label>Time responsável</Label>
              <Select
                value={teamId ?? NO_TEAM_VALUE}
                onValueChange={(value) => setTeamId(value === NO_TEAM_VALUE ? undefined : value)}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Selecione um time" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={NO_TEAM_VALUE}>Sem time</SelectItem>
                  {teams?.map((team) => (
                    <SelectItem key={team.id} value={team.id}>
                      {team.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="flex items-end">
              <Button type="submit" className="w-full" disabled={saving}>
                Criar fila
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>

      <div className="grid gap-4 lg:grid-cols-2">
        {queues === undefined ? (
          Array.from({ length: 4 }).map((_, index) => <Skeleton key={index} className="h-40 rounded-2xl" />)
        ) : queues.length === 0 ? (
          <Card className="border-dashed border-slate-300 bg-slate-50/80">
            <CardHeader>
              <CardTitle className="text-lg font-semibold text-neutral-900">Nenhuma fila cadastrada</CardTitle>
              <CardDescription className="text-neutral-600">
                Crie filas para segmentar os atendimentos por canal ou especialidade.
              </CardDescription>
            </CardHeader>
          </Card>
        ) : (
          queues.map((queue) => (
            <Card key={queue.id} className="border-slate-200">
              <CardHeader>
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <CardTitle className="text-xl font-semibold text-neutral-900">{queue.name}</CardTitle>
                    <CardDescription className="mt-2 text-xs uppercase tracking-wide text-neutral-500">
                      Slug: {queue.slug}
                    </CardDescription>
                  </div>
                  <div className="flex gap-2">
                    <Button variant="outline" size="sm" onClick={() => openEdit(queue)}>
                      Editar
                    </Button>
                    <Button variant="destructive" size="sm" onClick={() => handleRemove(queue)}>
                      Excluir
                    </Button>
                  </div>
                </div>
              </CardHeader>
              <CardContent>
                <div className="flex items-center gap-3 text-sm text-neutral-600">
                  <span className="font-medium text-neutral-500">Time:</span>
                  {queue.team ? (
                    <Badge variant="outline" className="rounded-full border-neutral-300 text-neutral-700">
                      {queue.team.name}
                    </Badge>
                  ) : (
                    <span className="text-neutral-500">Sem time vinculado</span>
                  )}
                </div>
              </CardContent>
            </Card>
          ))
        )}
      </div>

      <Dialog open={Boolean(editingQueue)} onOpenChange={(value) => (!value ? setEditingQueue(null) : null)}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>Editar fila</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label htmlFor="edit-queue-name">Nome</Label>
              <Input
                id="edit-queue-name"
                value={name}
                onChange={(event) => setName(event.target.value)}
                autoFocus
              />
            </div>
            <div className="space-y-2">
              <Label>Time responsável</Label>
              <Select
                value={teamId ?? NO_TEAM_VALUE}
                onValueChange={(value) => setTeamId(value === NO_TEAM_VALUE ? undefined : value)}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Selecione um time" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={NO_TEAM_VALUE}>Sem time</SelectItem>
                  {teams?.map((team) => (
                    <SelectItem key={team.id} value={team.id}>
                      {team.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setEditingQueue(null)}>
              Cancelar
            </Button>
            <Button onClick={handleUpdate} disabled={saving}>
              Salvar alterações
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
