import { useEffect, useMemo, useState } from "react";
import { Edit, Plus, Power, Users, UserCheck, UserX } from "lucide-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 {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  fechamentoUsuariosService,
  type UsuarioItem,
  type UsuarioPapel,
  type UsuarioStatusFiltro,
} from "@/services/fechamento/usuarios";
import {
  fechamentoParceirosService,
  type ParceiroItem,
} from "@/services/fechamento/parceiros";

type UsuarioForm = {
  nome: string;
  email: string;
  papel: UsuarioPapel;
  parceiroId: string;
};

const formInicial: UsuarioForm = {
  nome: "",
  email: "",
  papel: "admin",
  parceiroId: "",
};
const parceiroSemVinculoValue = "__none__";

function getNomeUsuario(usuario: UsuarioItem | null | undefined): string {
  if (!usuario) {
    return "—";
  }
  const nome = usuario.nome?.trim();
  return nome && nome.length > 0 ? nome : "—";
}

function getEmailUsuario(usuario: UsuarioItem | null | undefined): string {
  if (!usuario) {
    return "—";
  }
  const email = usuario.email?.trim();
  return email && email.length > 0 ? email : "—";
}

export default function Usuarios() {
  const [usuarios, setUsuarios] = useState<UsuarioItem[]>([]);
  const [parceiros, setParceiros] = useState<ParceiroItem[]>([]);

  const [loadingList, setLoadingList] = useState(true);
  const [loadingParceiros, setLoadingParceiros] = useState(true);
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [isEditOpen, setIsEditOpen] = useState(false);
  const [isToggleOpen, setIsToggleOpen] = useState(false);
  const [saving, setSaving] = useState(false);
  const [toggling, setToggling] = useState(false);

  const [selectedUsuario, setSelectedUsuario] = useState<UsuarioItem | null>(null);
  const [form, setForm] = useState<UsuarioForm>(formInicial);

  const [busca, setBusca] = useState("");
  const [filtroPapel, setFiltroPapel] = useState<"all" | UsuarioPapel>("all");
  const [filtroStatus, setFiltroStatus] = useState<UsuarioStatusFiltro>("all");
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);
  const [totalRegistros, setTotalRegistros] = useState(0);
  const [totalPaginas, setTotalPaginas] = useState(1);
  const [reloadNonce, setReloadNonce] = useState(0);

  const totalPages = Math.max(1, totalPaginas);
  const hasActiveFilters =
    busca.trim().length > 0 || filtroPapel !== "all" || filtroStatus !== "all";
  const parceiroObrigatorio = form.papel === "parceiro";
  const parceiroSelecionado = useMemo(
    () => parceiros.find((p) => p.id === form.parceiroId) ?? null,
    [parceiros, form.parceiroId],
  );

  useEffect(() => {
    let cancelled = false;
    setLoadingParceiros(true);
    fechamentoParceirosService
      .listarParceirosAtivos()
      .then((data) => {
        if (!cancelled) {
          setParceiros(data);
        }
      })
      .catch((error) => {
        if (!cancelled) {
          const message = error instanceof Error ? error.message : "Erro ao listar parceiros.";
          toast.error(message);
          setParceiros([]);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoadingParceiros(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    let cancelled = false;
    setLoadingList(true);
    fechamentoUsuariosService
      .listarUsuarios({
        busca: busca.trim() || undefined,
        papel: filtroPapel === "all" ? undefined : filtroPapel,
        estaAtivo: filtroStatus,
        page: currentPage,
        perPage: itemsPerPage,
      })
      .then((res) => {
        if (!cancelled) {
          setUsuarios(res.data ?? []);
          setTotalRegistros(res.meta?.total ?? 0);
          setTotalPaginas(res.meta?.totalPaginas ?? 1);
        }
      })
      .catch((error) => {
        if (!cancelled) {
          const message = error instanceof Error ? error.message : "Erro ao listar usuários.";
          toast.error(message);
          setUsuarios([]);
          setTotalRegistros(0);
          setTotalPaginas(1);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoadingList(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [busca, filtroPapel, filtroStatus, currentPage, itemsPerPage, reloadNonce]);

  useEffect(() => {
    setCurrentPage(1);
  }, [busca, filtroPapel, filtroStatus]);

  const clearFilters = () => {
    setBusca("");
    setFiltroPapel("all");
    setFiltroStatus("all");
    setCurrentPage(1);
  };

  const openCreateDialog = () => {
    setForm(formInicial);
    setIsCreateOpen(true);
  };

  const openEditDialog = (usuario: UsuarioItem) => {
    setSelectedUsuario(usuario);
    setForm({
      nome: usuario.nome ?? "",
      email: usuario.email ?? "",
      papel: usuario.papel,
      parceiroId: usuario.parceiroId ?? "",
    });
    setIsEditOpen(true);
  };

  const openToggleDialog = (usuario: UsuarioItem) => {
    setSelectedUsuario(usuario);
    setIsToggleOpen(true);
  };

  const validateForm = (): boolean => {
    if (!form.nome.trim()) {
      toast.error("Nome é obrigatório.");
      return false;
    }
    if (!form.email.trim()) {
      toast.error("E-mail é obrigatório.");
      return false;
    }
    if (parceiroObrigatorio && !form.parceiroId) {
      toast.error("Selecione um parceiro para o perfil parceiro.");
      return false;
    }
    return true;
  };

  const handleCreate = async () => {
    if (!validateForm()) {
      return;
    }
    try {
      setSaving(true);
      await fechamentoUsuariosService.criarUsuario({
        nome: form.nome.trim(),
        email: form.email.trim(),
        papel: form.papel,
        parceiroId: form.parceiroId || null,
        estaAtivo: true,
      });
      toast.success("Usuário criado com sucesso.");
      setIsCreateOpen(false);
      setCurrentPage(1);
      setReloadNonce((prev) => prev + 1);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao criar usuário.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  const handleEdit = async () => {
    if (!selectedUsuario || !validateForm()) {
      return;
    }
    try {
      setSaving(true);
      await fechamentoUsuariosService.editarUsuario(selectedUsuario.id, {
        nome: form.nome.trim(),
        email: form.email.trim(),
        papel: form.papel,
        parceiroId: form.parceiroId || null,
      });
      toast.success("Usuário atualizado com sucesso.");
      setIsEditOpen(false);
      setSelectedUsuario(null);
      setReloadNonce((prev) => prev + 1);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao editar usuário.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  const handleToggleStatus = async () => {
    if (!selectedUsuario) {
      return;
    }
    try {
      setToggling(true);
      const updated = await fechamentoUsuariosService.toggleAtivoUsuario(selectedUsuario.id);
      toast.success(updated.estaAtivo ? "Usuário reativado com sucesso." : "Usuário inativado com sucesso.");
      setIsToggleOpen(false);
      setSelectedUsuario(null);
      setReloadNonce((prev) => prev + 1);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao atualizar status do usuário.";
      toast.error(message);
    } finally {
      setToggling(false);
    }
  };

  const handleItemsPerPageChange = (value: string) => {
    setItemsPerPage(Number(value));
    setCurrentPage(1);
  };

  const onChangePapel = (value: UsuarioPapel) => {
    setForm((prev) => ({
      ...prev,
      papel: value,
    }));
  };

  return (
    <div className="flex h-full flex-col bg-background pb-16 md:pb-0">
      <div className="border-b border-border p-3 md:p-6">
        <div className="mb-4 flex flex-col items-start justify-between gap-3 md:flex-row md:items-center">
          <h1 className="flex items-center gap-2 text-xl font-bold text-foreground md:text-3xl">
            <Users className="h-5 w-5 md:h-6 md:w-6" />
            Usuários
          </h1>
          <Button onClick={openCreateDialog} className="gap-2">
            <Plus className="h-4 w-4" />
            Novo usuário
          </Button>
        </div>

        <div className="flex flex-col items-stretch gap-2 md:flex-row md:items-center md:gap-4">
          <Input
            placeholder="Buscar por nome ou e-mail..."
            value={busca}
            onChange={(e) => setBusca(e.target.value)}
            className="w-full md:max-w-sm"
          />
          <Select
            value={filtroPapel}
            onValueChange={(value) => setFiltroPapel(value as "all" | UsuarioPapel)}
          >
            <SelectTrigger className="w-full md:w-[170px]">
              <SelectValue placeholder="Perfil" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Todos os perfis</SelectItem>
              <SelectItem value="admin">Admin</SelectItem>
              <SelectItem value="parceiro">Parceiro</SelectItem>
            </SelectContent>
          </Select>
          <Select value={filtroStatus} onValueChange={(value) => setFiltroStatus(value as UsuarioStatusFiltro)}>
            <SelectTrigger className="w-full md:w-[170px]">
              <SelectValue placeholder="Status" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Todos</SelectItem>
              <SelectItem value="true">Ativos</SelectItem>
              <SelectItem value="false">Inativos</SelectItem>
            </SelectContent>
          </Select>
          {hasActiveFilters && (
            <Button variant="ghost" size="sm" onClick={clearFilters}>
              Limpar
            </Button>
          )}
          <div className="flex items-center gap-2">
            <span className="whitespace-nowrap text-sm text-muted-foreground">Itens:</span>
            <Select value={itemsPerPage.toString()} onValueChange={handleItemsPerPageChange}>
              <SelectTrigger className="w-20">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="10">10</SelectItem>
                <SelectItem value="20">20</SelectItem>
                <SelectItem value="50">50</SelectItem>
                <SelectItem value="100">100</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>
      </div>

      <div className="flex-1 overflow-auto p-3 md:p-6">
        {!loadingList && totalRegistros === 0 && !hasActiveFilters ? (
          <Card className="mx-auto mt-12 max-w-2xl">
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Users className="h-5 w-5" />
                Nenhum usuário cadastrado
              </CardTitle>
              <CardDescription>
                Crie o primeiro usuário para iniciar o gerenciamento de acessos.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <Button onClick={openCreateDialog}>
                <Plus className="mr-2 h-4 w-4" />
                Novo usuário
              </Button>
            </CardContent>
          </Card>
        ) : (
          <>
            <div className="overflow-x-auto rounded-lg border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="min-w-[220px]">Nome</TableHead>
                    <TableHead className="min-w-[220px]">E-mail</TableHead>
                    <TableHead className="min-w-[120px]">Perfil</TableHead>
                    <TableHead className="min-w-[120px]">Status</TableHead>
                    <TableHead className="text-center">Ações</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {loadingList ? (
                    <TableRow>
                      <TableCell colSpan={5} className="py-8 text-center text-muted-foreground">
                        Carregando...
                      </TableCell>
                    </TableRow>
                  ) : totalRegistros === 0 ? (
                    <TableRow>
                      <TableCell colSpan={5} className="py-8 text-center text-muted-foreground">
                        Nenhum usuário encontrado para os filtros atuais.
                      </TableCell>
                    </TableRow>
                  ) : (
                    usuarios.map((usuario) => (
                      <TableRow key={usuario.id}>
                        <TableCell className="font-medium">{getNomeUsuario(usuario)}</TableCell>
                        <TableCell>{getEmailUsuario(usuario)}</TableCell>
                        <TableCell>
                          <Badge
                            className={
                              usuario.papel === "admin"
                                ? "border-blue-600/30 bg-blue-50 font-normal text-blue-800 hover:bg-blue-50 dark:bg-blue-950/40 dark:text-blue-200"
                                : "border-slate-500/25 bg-slate-100 font-normal text-slate-700 hover:bg-slate-100 dark:bg-slate-800/60 dark:text-slate-200"
                            }
                          >
                            {usuario.papel === "admin" ? "Admin" : "Parceiro"}
                          </Badge>
                        </TableCell>
                        <TableCell>
                          <Badge
                            className={
                              usuario.estaAtivo
                                ? "border-emerald-600/30 bg-emerald-50 font-normal text-emerald-800 hover:bg-emerald-50 dark:bg-emerald-950/40 dark:text-emerald-200"
                                : "border-red-600/30 bg-red-50 font-normal text-red-800 hover:bg-red-50 dark:bg-red-950/40 dark:text-red-200"
                            }
                          >
                            {usuario.estaAtivo ? "Ativo" : "Inativo"}
                          </Badge>
                        </TableCell>
                        <TableCell>
                          <div className="flex items-center justify-center gap-1">
                            <Button
                              variant="ghost"
                              size="icon"
                              onClick={() => openEditDialog(usuario)}
                              title="Editar usuário"
                            >
                              <Edit className="h-4 w-4" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="icon"
                              onClick={() => openToggleDialog(usuario)}
                              title={usuario.estaAtivo ? "Inativar usuário" : "Reativar usuário"}
                            >
                              <Power className="h-4 w-4" />
                            </Button>
                          </div>
                        </TableCell>
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </div>

            {!loadingList && totalRegistros > 0 && (
              <div className="mt-4 flex flex-col items-stretch justify-between gap-2 sm:flex-row sm:items-center">
                <p className="text-center text-sm text-muted-foreground sm:text-left">
                  Mostrando {totalRegistros} {totalRegistros === 1 ? "usuário" : "usuários"}
                </p>
                <div className="flex justify-center gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
                    disabled={currentPage === 1}
                  >
                    Anterior
                  </Button>
                  <div className="flex items-center gap-1">
                    {Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
                      let page: number;
                      if (totalPages <= 5) {
                        page = i + 1;
                      } else if (currentPage <= 3) {
                        page = i + 1;
                      } else if (currentPage >= totalPages - 2) {
                        page = totalPages - 4 + i;
                      } else {
                        page = currentPage - 2 + i;
                      }
                      return (
                        <Button
                          key={page}
                          variant={currentPage === page ? "default" : "outline"}
                          size="sm"
                          onClick={() => setCurrentPage(page)}
                          className="h-9 w-10 p-0"
                        >
                          {page}
                        </Button>
                      );
                    })}
                  </div>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
                    disabled={currentPage === totalPages}
                  >
                    Próxima
                  </Button>
                </div>
              </div>
            )}
          </>
        )}
      </div>

      <Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Novo usuário</DialogTitle>
            <DialogDescription>Preencha os dados para criar um novo usuário.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div>
              <Label htmlFor="create-nome">Nome</Label>
              <Input
                id="create-nome"
                value={form.nome}
                onChange={(e) => setForm((prev) => ({ ...prev, nome: e.target.value }))}
                placeholder="Nome completo"
              />
            </div>
            <div>
              <Label htmlFor="create-email">E-mail</Label>
              <Input
                id="create-email"
                type="email"
                value={form.email}
                onChange={(e) => setForm((prev) => ({ ...prev, email: e.target.value }))}
                placeholder="usuario@empresa.com"
              />
            </div>
            <div>
              <Label>Perfil</Label>
              <Select value={form.papel} onValueChange={(value) => onChangePapel(value as UsuarioPapel)}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="admin">Admin</SelectItem>
                  <SelectItem value="parceiro">Parceiro</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>
                Parceiro {parceiroObrigatorio ? <span className="text-destructive">*</span> : null}
              </Label>
              <Select
                value={form.parceiroId || parceiroSemVinculoValue}
                onValueChange={(value) =>
                  setForm((prev) => ({
                    ...prev,
                    parceiroId: value === parceiroSemVinculoValue ? "" : value,
                  }))
                }
                disabled={loadingParceiros}
              >
                <SelectTrigger>
                  <SelectValue
                    placeholder={
                      parceiroObrigatorio
                        ? "Selecione um parceiro"
                        : "Opcional para admin, obrigatório para parceiro"
                    }
                  />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={parceiroSemVinculoValue} disabled={parceiroObrigatorio}>
                    Sem parceiro
                  </SelectItem>
                  {parceiros.map((parceiro) => (
                    <SelectItem key={parceiro.id} value={parceiro.id}>
                      {parceiro.codinome?.trim()
                        ? `${parceiro.nome} (${parceiro.codinome.trim()})`
                        : parceiro.nome}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <p className="mt-1 text-xs text-muted-foreground">
                Cada parceiro pode estar vinculado a apenas um usuário.
              </p>
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              className="hover:bg-muted/60 hover:text-foreground"
              onClick={() => setIsCreateOpen(false)}
              disabled={saving}
            >
              Cancelar
            </Button>
            <Button onClick={handleCreate} disabled={saving}>
              {saving ? "Criando..." : "Criar usuário"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={isEditOpen} onOpenChange={setIsEditOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Editar usuário</DialogTitle>
            <DialogDescription>Atualize os dados do usuário selecionado.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div>
              <Label htmlFor="edit-nome">Nome</Label>
              <Input
                id="edit-nome"
                value={form.nome}
                onChange={(e) => setForm((prev) => ({ ...prev, nome: e.target.value }))}
                placeholder="Nome completo"
              />
            </div>
            <div>
              <Label htmlFor="edit-email">E-mail</Label>
              <Input
                id="edit-email"
                type="email"
                value={form.email}
                onChange={(e) => setForm((prev) => ({ ...prev, email: e.target.value }))}
                placeholder="usuario@empresa.com"
              />
            </div>
            <div>
              <Label>Perfil</Label>
              <Select value={form.papel} onValueChange={(value) => onChangePapel(value as UsuarioPapel)}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="admin">Admin</SelectItem>
                  <SelectItem value="parceiro">Parceiro</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>
                Parceiro {parceiroObrigatorio ? <span className="text-destructive">*</span> : null}
              </Label>
              <Select
                value={form.parceiroId || parceiroSemVinculoValue}
                onValueChange={(value) =>
                  setForm((prev) => ({
                    ...prev,
                    parceiroId: value === parceiroSemVinculoValue ? "" : value,
                  }))
                }
                disabled={loadingParceiros}
              >
                <SelectTrigger>
                  <SelectValue
                    placeholder={
                      parceiroObrigatorio
                        ? "Selecione um parceiro"
                        : "Opcional para admin, obrigatório para parceiro"
                    }
                  />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={parceiroSemVinculoValue} disabled={parceiroObrigatorio}>
                    Sem parceiro
                  </SelectItem>
                  {parceiros.map((parceiro) => (
                    <SelectItem key={parceiro.id} value={parceiro.id}>
                      {parceiro.codinome?.trim()
                        ? `${parceiro.nome} (${parceiro.codinome.trim()})`
                        : parceiro.nome}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {parceiroSelecionado && (
                <p className="mt-1 text-xs text-muted-foreground">
                  Vinculado: {parceiroSelecionado.codinome?.trim() || parceiroSelecionado.nome}
                </p>
              )}
              <p className="mt-1 text-xs text-muted-foreground">
                Cada parceiro pode estar vinculado a apenas um usuário.
              </p>
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              className="hover:bg-muted/60 hover:text-foreground"
              onClick={() => setIsEditOpen(false)}
              disabled={saving}
            >
              Cancelar
            </Button>
            <Button onClick={handleEdit} disabled={saving}>
              {saving ? "Salvando..." : "Salvar alterações"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <AlertDialog open={isToggleOpen} onOpenChange={setIsToggleOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              {selectedUsuario?.estaAtivo ? "Inativar usuário" : "Reativar usuário"}
            </AlertDialogTitle>
            <AlertDialogDescription>
              {selectedUsuario?.estaAtivo ? (
                <>
                  Deseja inativar o usuário <strong>{getNomeUsuario(selectedUsuario)}</strong>?
                </>
              ) : (
                <>
                  Deseja reativar o usuário <strong>{getNomeUsuario(selectedUsuario)}</strong>?
                </>
              )}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel className="hover:bg-muted/60 hover:text-foreground" disabled={toggling}>
              Cancelar
            </AlertDialogCancel>
            <AlertDialogAction onClick={handleToggleStatus} disabled={toggling || !selectedUsuario}>
              {toggling ? (
                "Processando..."
              ) : selectedUsuario?.estaAtivo ? (
                <span className="inline-flex items-center gap-2">
                  <UserX className="h-4 w-4" />
                  Inativar
                </span>
              ) : (
                <span className="inline-flex items-center gap-2">
                  <UserCheck className="h-4 w-4" />
                  Reativar
                </span>
              )}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
