"use client"

import { useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { IconUsersGroup, IconCalendarClock, IconSettings, IconUserPlus } from "@tabler/icons-react"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { useAuth } from "@/lib/auth-client"
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 { Badge } from "@/components/ui/badge"
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Checkbox } from "@/components/ui/checkbox"
import { Skeleton } from "@/components/ui/skeleton"

type Team = {
  id: string
  name: string
  description: string
  members: { id: string; name: string; email: string; role: string }[]
  queueCount: number
  createdAt: number
}

type DirectoryUser = {
  id: string
  name: string
  email: string
  role: string
  teams: string[]
}

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

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

  const createTeam = useMutation(api.teams.create)
  const updateTeam = useMutation(api.teams.update)
  const removeTeam = useMutation(api.teams.remove)
  const setMembers = useMutation(api.teams.setMembers)

  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [editingTeam, setEditingTeam] = useState<Team | null>(null)
  const [membershipTeam, setMembershipTeam] = useState<Team | null>(null)
  const [selectedMembers, setSelectedMembers] = useState<Set<string>>(new Set())
  const [saving, setSaving] = useState(false)

  const totalMembers = useMemo(() => {
    if (!teams) return 0
    return teams.reduce((acc, team) => acc + team.members.length, 0)
  }, [teams])

  const totalQueues = useMemo(() => {
    if (!teams) return 0
    return teams.reduce((acc, team) => acc + team.queueCount, 0)
  }, [teams])

  const handleCreate = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    if (!name.trim()) {
      toast.error("Informe um nome para o time")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    setSaving(true)
    toast.loading("Criando time...", { id: "team" })
    try {
      await createTeam({
        tenantId,
        actorId: convexUserId as Id<"users">,
        name: name.trim(),
        description: description.trim() || undefined,
      })
      setName("")
      setDescription("")
      toast.success("Time criado com sucesso", { id: "team" })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar o time", { id: "team" })
    } finally {
      setSaving(false)
    }
  }

  const openEdit = (team: Team) => {
    setEditingTeam(team)
    setName(team.name)
    setDescription(team.description)
  }

  const handleUpdate = async () => {
    if (!editingTeam) return
    if (!name.trim()) {
      toast.error("Informe um nome para o time")
      return
    }
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    setSaving(true)
    toast.loading("Salvando alterações...", { id: "team-edit" })
    try {
      await updateTeam({
        tenantId,
        teamId: editingTeam.id as Id<"teams">,
        actorId: convexUserId as Id<"users">,
        name: name.trim(),
        description: description.trim() || undefined,
      })
      toast.success("Time atualizado", { id: "team-edit" })
      setEditingTeam(null)
      setName("")
      setDescription("")
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível atualizar o time", { id: "team-edit" })
    } finally {
      setSaving(false)
    }
  }

  const handleRemove = async (team: Team) => {
    const confirmed = window.confirm(`Excluir o time ${team.name}?`)
    if (!confirmed) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    toast.loading("Removendo time...", { id: `team-remove-${team.id}` })
    try {
      await removeTeam({ tenantId, teamId: team.id as Id<"teams">, actorId: convexUserId as Id<"users"> })
      toast.success("Time removido", { id: `team-remove-${team.id}` })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover o time", { id: `team-remove-${team.id}` })
    }
  }

  const openMembership = (team: Team) => {
    setMembershipTeam(team)
    setSelectedMembers(new Set(team.members.map((member) => member.id)))
  }

  const toggleMember = (userId: string) => {
    setSelectedMembers((current) => {
      const next = new Set(current)
      if (next.has(userId)) {
        next.delete(userId)
      } else {
        next.add(userId)
      }
      return next
    })
  }

  const handleMembershipSave = async () => {
    if (!membershipTeam) return
    if (!convexUserId) {
      toast.error("Sessão não sincronizada com o Convex")
      return
    }
    setSaving(true)
    toast.loading("Atualizando membros...", { id: "team-members" })
    try {
      await setMembers({
        tenantId,
        teamId: membershipTeam.id as Id<"teams">,
        actorId: convexUserId as Id<"users">,
        memberIds: Array.from(selectedMembers) as Id<"users">[],
      })
      toast.success("Membros atualizados", { id: "team-members" })
      setMembershipTeam(null)
      setSelectedMembers(new Set())
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível atualizar os membros", { id: "team-members" })
    } finally {
      setSaving(false)
    }
  }

  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">
              <IconUsersGroup className="size-4" /> Times cadastrados
            </CardTitle>
            <CardDescription>Organize a operação em células de atendimento.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {teams ? teams.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">
              <IconUserPlus className="size-4" /> Pessoas alocadas
            </CardTitle>
            <CardDescription>Soma de integrantes em cada time.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {teams ? totalMembers : <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">
              <IconCalendarClock className="size-4" /> Filas vinculadas
            </CardTitle>
            <CardDescription>Total de canais ligados aos times.</CardDescription>
          </CardHeader>
          <CardContent className="text-3xl font-semibold text-neutral-900">
            {teams ? totalQueues : <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">
            <IconSettings className="size-5 text-neutral-500" /> Novo time
          </CardTitle>
          <CardDescription>Defina a que squad, célula ou capítulo cada chamado poderá ser roteado.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleCreate} className="grid gap-4 md:grid-cols-[minmax(0,300px)_minmax(0,1fr)_auto]">
            <div className="space-y-2">
              <Label htmlFor="team-name">Nome do time</Label>
              <Input
                id="team-name"
                placeholder="Ex.: Suporte N1"
                value={name}
                onChange={(event) => setName(event.target.value)}
                required
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="team-description">Descrição</Label>
              <Input
                id="team-description"
                placeholder="Contextualize a responsabilidade do time"
                value={description}
                onChange={(event) => setDescription(event.target.value)}
              />
            </div>
            <div className="flex items-end">
              <Button type="submit" className="w-full" disabled={saving}>
                {saving && !editingTeam ? "Salvando..." : "Adicionar"}
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>

      <div className="grid gap-4 lg:grid-cols-2">
        {teams === undefined ? (
          Array.from({ length: 4 }).map((_, index) => <Skeleton key={index} className="h-48 rounded-2xl" />)
        ) : teams.length === 0 ? (
          <Card className="border-dashed border-slate-300 bg-slate-50/80">
            <CardHeader>
              <CardTitle className="text-lg font-semibold text-neutral-900">Nenhum time cadastrado</CardTitle>
              <CardDescription className="text-neutral-600">
                Crie o primeiro time para organizar a distribuição das filas e agentes.
              </CardDescription>
            </CardHeader>
          </Card>
        ) : (
          teams.map((team) => (
            <Card key={team.id} className="flex flex-col justify-between border-slate-200">
              <CardHeader>
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <CardTitle className="text-xl font-semibold text-neutral-900">{team.name}</CardTitle>
                    {team.description ? (
                      <CardDescription className="mt-1 text-neutral-600">{team.description}</CardDescription>
                    ) : null}
                    <div className="mt-4 flex flex-wrap gap-2 text-xs text-neutral-500">
                      <Badge variant="outline" className="rounded-full border-neutral-300 text-neutral-600">
                        {team.members.length} membro{team.members.length === 1 ? "" : "s"}
                      </Badge>
                      <Badge variant="outline" className="rounded-full border-neutral-300 text-neutral-600">
                        {team.queueCount} fila{team.queueCount === 1 ? "" : "s"}
                      </Badge>
                    </div>
                  </div>
                  <div className="flex flex-col gap-2">
                    <Button variant="outline" size="sm" onClick={() => openMembership(team)}>
                      Gerenciar membros
                    </Button>
                    <Button variant="secondary" size="sm" onClick={() => openEdit(team)}>
                      Renomear
                    </Button>
                    <Button variant="destructive" size="sm" onClick={() => handleRemove(team)}>
                      Excluir
                    </Button>
                  </div>
                </div>
              </CardHeader>
              <CardContent>
                <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Integrantes</p>
                {team.members.length === 0 ? (
                  <p className="mt-2 text-sm text-neutral-600">Nenhum membro atribuído.</p>
                ) : (
                  <ul className="mt-2 space-y-2">
                    {team.members.map((member) => (
                      <li key={member.id} className="flex items-center justify-between rounded-lg border border-slate-200 px-3 py-2 text-sm">
                        <div>
                          <p className="font-medium text-neutral-800">{member.name || member.email}</p>
                          <p className="text-xs text-neutral-500">{member.email}</p>
                        </div>
                        <Badge variant="outline" className="rounded-full border-neutral-200 text-neutral-600">
                          {member.role.toLowerCase()}
                        </Badge>
                      </li>
                    ))}
                  </ul>
                )}
              </CardContent>
            </Card>
          ))
        )}
      </div>

      <Dialog open={Boolean(editingTeam)} onOpenChange={(value) => (!value ? setEditingTeam(null) : null)}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>Editar time</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label htmlFor="edit-team-name">Nome</Label>
              <Input
                id="edit-team-name"
                value={name}
                onChange={(event) => setName(event.target.value)}
                autoFocus
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="edit-team-description">Descrição</Label>
              <Input
                id="edit-team-description"
                value={description}
                onChange={(event) => setDescription(event.target.value)}
              />
            </div>
          </div>
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setEditingTeam(null)}>
              Cancelar
            </Button>
            <Button onClick={handleUpdate} disabled={saving}>
              Salvar alterações
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={Boolean(membershipTeam)} onOpenChange={(value) => (!value ? setMembershipTeam(null) : null)}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>Gerenciar membros</DialogTitle>
          </DialogHeader>
          <div className="max-h-[420px] overflow-y-auto rounded-lg border border-slate-200">
            {directory === undefined ? (
              <div className="space-y-2 p-4">
                {Array.from({ length: 6 }).map((_, index) => (
                  <Skeleton key={index} className="h-10 rounded" />
                ))}
              </div>
            ) : directory.length === 0 ? (
              <p className="p-4 text-sm text-neutral-600">Nenhum usuário sincronizado para este tenant.</p>
            ) : (
              <ul className="divide-y divide-slate-100">
                {directory.map((user) => {
                  const checked = selectedMembers.has(user.id)
                  return (
                    <li key={user.id} className="flex items-center justify-between gap-3 px-4 py-3">
                      <div>
                        <p className="text-sm font-medium text-neutral-900">{user.name || user.email}</p>
                        <p className="text-xs text-neutral-500">{user.email}</p>
                      </div>
                      <div className="flex items-center gap-3">
                        <Badge variant="outline" className="rounded-full border-neutral-200 text-neutral-600">
                          {user.role.toLowerCase()}
                        </Badge>
                        <Checkbox checked={checked} onCheckedChange={() => toggleMember(user.id)} />
                      </div>
                    </li>
                  )
                })}
              </ul>
            )}
          </div>
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setMembershipTeam(null)}>
              Cancelar
            </Button>
            <Button onClick={handleMembershipSave} disabled={saving}>
              Salvar
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
