"use client"

import { useMemo, useState, useTransition } from "react"

import { toast } from "sonner"

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 { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ROLE_OPTIONS, type RoleOption } from "@/lib/authz"

type AdminUser = {
  id: string
  email: string
  name: string
  role: RoleOption
  tenantId: string
  createdAt: string
  updatedAt: string | null
}

type AdminInvite = {
  id: string
  email: string
  name: string | null
  role: RoleOption
  tenantId: string
  status: "pending" | "accepted" | "revoked" | "expired"
  token: string
  inviteUrl: string
  expiresAt: string
  createdAt: string
  createdById: string | null
  acceptedAt: string | null
  acceptedById: string | null
  revokedAt: string | null
  revokedById: string | null
  revokedReason: string | null
}

type Props = {
  initialUsers: AdminUser[]
  initialInvites: AdminInvite[]
  roleOptions: readonly RoleOption[]
  defaultTenantId: string
}

function formatDate(dateIso: string) {
  const date = new Date(dateIso)
  return new Intl.DateTimeFormat("pt-BR", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date)
}

function formatStatus(status: AdminInvite["status"]) {
  switch (status) {
    case "pending":
      return "Pendente"
    case "accepted":
      return "Aceito"
    case "revoked":
      return "Revogado"
    case "expired":
      return "Expirado"
    default:
      return status
  }
}

function sanitizeInvite(invite: AdminInvite & { events?: unknown }): AdminInvite {
  const { events: unusedEvents, ...rest } = invite
  void unusedEvents
  return rest
}

export function AdminUsersManager({ initialUsers, initialInvites, roleOptions, defaultTenantId }: Props) {
  const [users] = useState<AdminUser[]>(initialUsers)
  const [invites, setInvites] = useState<AdminInvite[]>(initialInvites)
  const [email, setEmail] = useState("")
  const [name, setName] = useState("")
  const [role, setRole] = useState<RoleOption>("agent")
  const [tenantId, setTenantId] = useState(defaultTenantId)
  const [expiresInDays, setExpiresInDays] = useState<string>("7")
  const [lastInviteLink, setLastInviteLink] = useState<string | null>(null)
  const [revokingId, setRevokingId] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()
  const [companies, setCompanies] = useState<Array<{ id: string; name: string }>>([])
  const [linkEmail, setLinkEmail] = useState("")
  const [linkCompanyId, setLinkCompanyId] = useState("")

  const normalizedRoles = useMemo(() => roleOptions ?? ROLE_OPTIONS, [roleOptions])

  // load companies for association
  useMemo(() => {
    void (async () => {
      try {
        const r = await fetch("/api/admin/companies", { credentials: "include" })
        const j = await r.json()
        const items = (j.companies ?? []).map((c: any) => ({ id: c.id as string, name: c.name as string }))
        setCompanies(items)
      } catch {
        // noop
      }
    })()
  }, [])

  async function handleInviteSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    if (!email || !email.includes("@")) {
      toast.error("Informe um e-mail válido")
      return
    }

    const payload = {
      email,
      name,
      role,
      tenantId,
      expiresInDays: Number.parseInt(expiresInDays, 10),
    }

    startTransition(async () => {
      try {
        const response = await fetch("/api/admin/invites", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        })

        if (!response.ok) {
          const data = await response.json().catch(() => ({}))
          throw new Error(data.error ?? "Não foi possível gerar o convite")
        }

        const data = (await response.json()) as { invite: AdminInvite }
        const nextInvite = sanitizeInvite(data.invite)
        setInvites((previous) => [nextInvite, ...previous.filter((item) => item.id !== nextInvite.id)])
        setEmail("")
        setName("")
        setRole("agent")
        setTenantId(defaultTenantId)
        setExpiresInDays("7")
        setLastInviteLink(nextInvite.inviteUrl)
        toast.success("Convite criado com sucesso")
      } catch (error) {
        const message = error instanceof Error ? error.message : "Falha ao criar convite"
        toast.error(message)
      }
    })
  }

  function handleCopy(link: string) {
    navigator.clipboard
      .writeText(link)
      .then(() => toast.success("Link de convite copiado"))
      .catch(() => toast.error("Não foi possível copiar o link"))
  }

  async function handleRevoke(inviteId: string) {
    const invite = invites.find((item) => item.id === inviteId)
    if (!invite || invite.status !== "pending") {
      return
    }

    const confirmed = window.confirm("Deseja revogar este convite?")
    if (!confirmed) return

    setRevokingId(inviteId)
    try {
      const response = await fetch(`/api/admin/invites/${inviteId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ reason: "Revogado manualmente" }),
      })

      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Falha ao revogar convite")
      }

      const data = (await response.json()) as { invite: AdminInvite }
      const updated = sanitizeInvite(data.invite)
      setInvites((previous) => previous.map((item) => (item.id === updated.id ? updated : item)))
      toast.success("Convite revogado")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao revogar convite"
      toast.error(message)
    } finally {
      setRevokingId(null)
    }
  }

  return (
    <Tabs defaultValue="invites" className="w-full">
      <TabsList className="h-12 w-full justify-start rounded-xl bg-slate-100 p-1">
        <TabsTrigger value="invites" className="rounded-lg">Convites</TabsTrigger>
        <TabsTrigger value="users" className="rounded-lg">Usuários</TabsTrigger>
        <TabsTrigger value="queues" className="rounded-lg">Filas</TabsTrigger>
        <TabsTrigger value="categories" className="rounded-lg">Categorias</TabsTrigger>
      </TabsList>

      <TabsContent value="invites" className="mt-6 space-y-6">
        <Card>
          <CardHeader>
            <CardTitle>Gerar convite</CardTitle>
            <CardDescription>
              Envie convites personalizados com validade controlada e acompanhe o status em tempo real.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <form
              onSubmit={handleInviteSubmit}
              className="grid gap-4 lg:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)_160px_160px_160px_auto]"
            >
              <div className="grid gap-2">
                <Label htmlFor="invite-email">E-mail corporativo</Label>
                <Input
                  id="invite-email"
                  type="email"
                  inputMode="email"
                  placeholder="nome@suaempresa.com"
                  value={email}
                  onChange={(event) => setEmail(event.target.value)}
                  required
                  autoComplete="off"
                />
              </div>
              <div className="grid gap-2">
                <Label htmlFor="invite-name">Nome</Label>
                <Input
                  id="invite-name"
                  placeholder="Nome completo"
                  value={name}
                  onChange={(event) => setName(event.target.value)}
                  autoComplete="off"
                />
              </div>
              <div className="grid gap-2">
                <Label>Papel</Label>
                <Select value={role} onValueChange={(value) => setRole(value as RoleOption)}>
                  <SelectTrigger id="invite-role">
                    <SelectValue placeholder="Selecione" />
                  </SelectTrigger>
                  <SelectContent>
                    {normalizedRoles.map((item) => (
                      <SelectItem key={item} value={item}>
                        {item === "admin"
                          ? "Administrador"
                          : item === "manager"
                          ? "Gestor"
                          : item === "agent"
                          ? "Agente"
                          : "Colaborador"}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label htmlFor="invite-tenant">Tenant</Label>
                <Input
                  id="invite-tenant"
                  value={tenantId}
                  onChange={(event) => setTenantId(event.target.value)}
                />
              </div>
              <div className="grid gap-2">
                <Label>Expira em</Label>
                <Select value={expiresInDays} onValueChange={setExpiresInDays}>
                  <SelectTrigger id="invite-expiration">
                    <SelectValue placeholder="7 dias" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="7">7 dias</SelectItem>
                    <SelectItem value="14">14 dias</SelectItem>
                    <SelectItem value="30">30 dias</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="flex items-end">
                <Button type="submit" disabled={isPending} className="w-full">
                  {isPending ? "Gerando..." : "Gerar convite"}
                </Button>
              </div>
            </form>
            {lastInviteLink ? (
              <div className="mt-4 flex flex-col gap-2 rounded-lg border border-slate-200 bg-slate-50 p-4 text-sm text-neutral-700 lg:flex-row lg:items-center lg:justify-between">
                <div>
                  <p className="font-medium text-neutral-900">Link de convite pronto</p>
                  <p className="text-neutral-600">Compartilhe com o convidado. O link expira automaticamente no prazo definido.</p>
                  <p className="mt-2 truncate font-mono text-xs text-neutral-500">{lastInviteLink}</p>
                </div>
                <Button type="button" variant="outline" onClick={() => handleCopy(lastInviteLink)}>
                  Copiar link
                </Button>
              </div>
            ) : null}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Vincular usuário a empresa</CardTitle>
            <CardDescription>Associe um colaborador à sua empresa (usado para escopo de gestores e relatórios).</CardDescription>
          </CardHeader>
          <CardContent>
            <form
              className="grid grid-cols-1 gap-4 md:grid-cols-[1fr_1fr_auto]"
              onSubmit={(e) => {
                e.preventDefault()
                if (!linkEmail || !linkCompanyId) {
                  toast.error("Informe e-mail e empresa")
                  return
                }
                startTransition(async () => {
                  toast.loading("Vinculando...", { id: "assign-company" })
                  try {
                    const r = await fetch("/api/admin/users/assign-company", {
                      method: "POST",
                      headers: { "Content-Type": "application/json" },
                      body: JSON.stringify({ email: linkEmail, companyId: linkCompanyId }),
                      credentials: "include",
                    })
                    if (!r.ok) throw new Error("failed")
                    toast.success("Usuário vinculado à empresa!", { id: "assign-company" })
                  } catch {
                    toast.error("Não foi possível vincular", { id: "assign-company" })
                  }
                })
              }}
            >
              <div className="grid gap-2">
                <Label>E-mail do usuário</Label>
                <Input value={linkEmail} onChange={(e) => setLinkEmail(e.target.value)} placeholder="colaborador@empresa.com" />
              </div>
              <div className="grid gap-2">
                <Label>Empresa</Label>
                <Select value={linkCompanyId} onValueChange={setLinkCompanyId}>
                  <SelectTrigger>
                    <SelectValue placeholder="Selecionar" />
                  </SelectTrigger>
                  <SelectContent>
                    {companies.map((c) => (
                      <SelectItem key={c.id} value={c.id}>
                        {c.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="flex items-end">
                <Button type="submit" disabled={isPending}>Vincular</Button>
              </div>
            </form>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Convites emitidos</CardTitle>
            <CardDescription>Histórico e status atual de todos os convites enviados para o workspace.</CardDescription>
          </CardHeader>
          <CardContent className="overflow-x-auto">
            <table className="min-w-full table-fixed divide-y divide-slate-200 text-sm">
              <thead>
                <tr className="text-left text-xs uppercase tracking-wide text-neutral-500">
                  <th className="py-3 pr-4 font-medium">Colaborador</th>
                  <th className="py-3 pr-4 font-medium">Papel</th>
                  <th className="py-3 pr-4 font-medium">Tenant</th>
                  <th className="py-3 pr-4 font-medium">Expira em</th>
                  <th className="py-3 pr-4 font-medium">Status</th>
                  <th className="py-3 font-medium">Ações</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {invites.map((invite) => (
                  <tr key={invite.id} className="hover:bg-slate-50">
                    <td className="py-3 pr-4">
                      <div className="flex flex-col">
                        <span className="font-medium text-neutral-800">{invite.name || invite.email}</span>
                        <span className="text-xs text-neutral-500">{invite.email}</span>
                      </div>
                    </td>
                    <td className="py-3 pr-4 uppercase text-neutral-600">{invite.role}</td>
                    <td className="py-3 pr-4 text-neutral-600">{invite.tenantId}</td>
                    <td className="py-3 pr-4 text-neutral-600">{formatDate(invite.expiresAt)}</td>
                    <td className="py-3 pr-4">
                      <Badge
                        variant={invite.status === "pending" ? "secondary" : invite.status === "accepted" ? "default" : invite.status === "expired" ? "outline" : "destructive"}
                        className="rounded-full px-3 py-1 text-[11px] uppercase tracking-wide"
                      >
                        {formatStatus(invite.status)}
                      </Badge>
                    </td>
                    <td className="py-3">
                      <div className="flex flex-wrap gap-2">
                        <Button variant="outline" size="sm" onClick={() => handleCopy(invite.inviteUrl)}>
                          Copiar link
                        </Button>
                        {invite.status === "pending" ? (
                          <Button
                            variant="ghost"
                            size="sm"
                            className="text-red-600 hover:bg-red-50"
                            onClick={() => handleRevoke(invite.id)}
                            disabled={revokingId === invite.id}
                          >
                            {revokingId === invite.id ? "Revogando..." : "Revogar"}
                          </Button>
                        ) : null}
                      </div>
                    </td>
                  </tr>
                ))}
                {invites.length === 0 ? (
                  <tr>
                    <td colSpan={6} className="py-6 text-center text-neutral-500">
                      Nenhum convite emitido até o momento.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </CardContent>
        </Card>
      </TabsContent>

      <TabsContent value="users" className="mt-6">
        <Card>
          <CardHeader>
            <CardTitle>Equipe cadastrada</CardTitle>
            <CardDescription>Usuários ativos e provisionados via convites aceitos.</CardDescription>
          </CardHeader>
          <CardContent className="overflow-x-auto">
            <table className="min-w-full table-fixed divide-y divide-slate-200 text-sm">
              <thead>
                <tr className="text-left text-xs uppercase tracking-wide text-neutral-500">
                  <th className="py-3 pr-4 font-medium">Nome</th>
                  <th className="py-3 pr-4 font-medium">E-mail</th>
                  <th className="py-3 pr-4 font-medium">Papel</th>
                  <th className="py-3 pr-4 font-medium">Tenant</th>
                  <th className="py-3 font-medium">Criado em</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {users.map((user) => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="py-3 pr-4 font-medium text-neutral-800">{user.name || "—"}</td>
                    <td className="py-3 pr-4 text-neutral-600">{user.email}</td>
                    <td className="py-3 pr-4 uppercase text-neutral-600">{user.role}</td>
                    <td className="py-3 pr-4 text-neutral-600">{user.tenantId}</td>
                    <td className="py-3 text-neutral-500">{formatDate(user.createdAt)}</td>
                  </tr>
                ))}
                {users.length === 0 ? (
                  <tr>
                    <td colSpan={5} className="py-6 text-center text-neutral-500">
                      Nenhum usuário cadastrado até o momento.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </CardContent>
        </Card>
      </TabsContent>

      <TabsContent value="queues" className="mt-6">
        <Card>
          <CardHeader>
            <CardTitle>Gestão de filas</CardTitle>
            <CardDescription>
              Em breve será possível criar e reordenar as filas utilizadas na triagem dos tickets.
            </CardDescription>
          </CardHeader>
        </Card>
      </TabsContent>

      <TabsContent value="categories" className="mt-6">
        <Card>
          <CardHeader>
            <CardTitle>Gestão de categorias</CardTitle>
            <CardDescription>
              Estamos preparando o painel completo para organizar categorias e subcategorias do catálogo.
            </CardDescription>
          </CardHeader>
        </Card>
      </TabsContent>
    </Tabs>
  )
}
