'use client';

import { useState } from 'react';
import { DashboardShell } from '@/components/layouts/dashboard-shell';
import { Card, CardContent, CardHeader, CardTitle, Button, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@horux/shared-ui';
import { useUsuarios, useInviteUsuario, useUpdateUsuario, useDeleteUsuario } from '@/lib/hooks/use-usuarios';
import { useContribuyentes } from '@/lib/hooks/use-contribuyentes';
import { addClienteAcceso } from '@/lib/api/contribuyentes';
import { useQuery } from '@tanstack/react-query';
import { apiClient } from '@/lib/api/client';
import { useAuthStore } from '@/stores/auth-store';
import { Users, UserPlus, Trash2, Shield, Eye, Calculator, UserCheck, UserCog, Building2, FolderOpen, KeyRound, Pencil } from 'lucide-react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@horux/shared-ui';
import Link from 'next/link';
import { cn } from '@horux/shared-ui';
import { isDespachoTenant } from '@horux/shared';
import type { Role, UserInvite } from '@horux/shared';

// ── Horux360 legacy roles ─────────────────────────────────────────────────────
const legacyRoleLabels: Record<string, { label: string; icon: React.ElementType; color: string }> = {
  owner:    { label: 'Dueño',    icon: Shield,    color: 'text-primary' },
  cfo:      { label: 'CFO',      icon: Shield,    color: 'text-primary' },
  contador: { label: 'Contador', icon: Calculator, color: 'text-success' },
  auxiliar: { label: 'Auxiliar', icon: UserCog,   color: 'text-success' },
  visor:    { label: 'Visor',    icon: Eye,        color: 'text-muted-foreground' },
};

const legacyInviteRoles: { value: string; label: string }[] = [
  { value: 'contador', label: 'Contador' },
  { value: 'visor',    label: 'Visor' },
  { value: 'auxiliar', label: 'Auxiliar' },
];

// ── Despacho roles ────────────────────────────────────────────────────────────
const despachoRoleLabels: Record<string, { label: string; icon: React.ElementType; color: string }> = {
  owner:      { label: 'Owner',      icon: Shield,     color: 'text-primary' },
  supervisor: { label: 'Supervisor', icon: UserCheck,  color: 'text-success' },
  auxiliar:   { label: 'Auxiliar',   icon: UserCog,    color: 'text-success' },
  cliente:    { label: 'Cliente',    icon: Building2,  color: 'text-muted-foreground' },
};

const despachoInviteRoles: { value: string; label: string; description: string }[] = [
  {
    value: 'supervisor',
    label: 'Supervisor',
    description: 'Titular de RFCs, crea carteras y gestiona auxiliares',
  },
  {
    value: 'auxiliar',
    label: 'Auxiliar',
    description: 'Accede a RFCs asignados vía carteras',
  },
  {
    value: 'cliente',
    label: 'Cliente',
    description: 'Visor externo — acceso read-only a sus RFCs',
  },
];

// ── Fallback for unknown roles ─────────────────────────────────────────────────
function getRoleInfo(
  role: string,
  isDespacho: boolean,
): { label: string; icon: React.ElementType; color: string } {
  if (isDespacho) {
    return despachoRoleLabels[role] ?? { label: role, icon: Eye, color: 'text-muted-foreground' };
  }
  return legacyRoleLabels[role] ?? { label: role, icon: Eye, color: 'text-muted-foreground' };
}

export default function UsuariosPage() {
  const { user: currentUser } = useAuthStore();
  const { data: usuarios, isLoading } = useUsuarios();
  const { data: contribuyentes } = useContribuyentes();
  const inviteUsuario = useInviteUsuario();
  const updateUsuario = useUpdateUsuario();
  const deleteUsuario = useDeleteUsuario();

  const isDespacho = isDespachoTenant(currentUser?.tenantRfc);
  const inviteRoles = isDespacho
    ? (currentUser?.role === 'supervisor'
        ? despachoInviteRoles.filter(r => r.value === 'cliente' || r.value === 'auxiliar')
        : despachoInviteRoles)
    : legacyInviteRoles;
  const defaultInviteRole = isDespacho ? 'auxiliar' : 'visor';

  const isAdmin = currentUser?.role === 'owner' || currentUser?.role === 'cfo' || currentUser?.role === 'supervisor';

  const [showInvite, setShowInvite] = useState(false);
  const [inviteForm, setInviteForm] = useState<{ email: string; nombre: string; role: UserInvite['role']; supervisorUserId?: string }>({
    email: '',
    nombre: '',
    role: defaultInviteRole as UserInvite['role'],
  });
  const [selectedRfcIds, setSelectedRfcIds] = useState<string[]>([]);

  // Edit accesos modal
  const [editingAccesosUser, setEditingAccesosUser] = useState<{ id: string; nombre: string } | null>(null);
  const [accesosRfcIds, setAccesosRfcIds] = useState<string[]>([]);
  const [savingAccesos, setSavingAccesos] = useState(false);

  // Edit supervisor modal (para auxiliares)
  const [editingSupervisorUser, setEditingSupervisorUser] = useState<{ id: string; nombre: string; supervisorNombre?: string | null } | null>(null);
  const [selectedSupervisorId, setSelectedSupervisorId] = useState<string>('');
  const [savingSupervisor, setSavingSupervisor] = useState(false);

  const [currentSupervisorNombre, setCurrentSupervisorNombre] = useState<string>('');

  // Edit user modal (owner only)
  const [editingUser, setEditingUser] = useState<{ id: string; nombre: string; role: Role; email: string } | null>(null);
  const [editForm, setEditForm] = useState<{ nombre: string; role: Role }>({ nombre: '', role: 'auxiliar' });
  const [savingUser, setSavingUser] = useState(false);

  const isOwner = currentUser?.role === 'owner';

  const openEditSupervisor = async (userId: string, nombre: string) => {
    try {
      const res = await apiClient.get<{ supervisorUserId: string | null; supervisorNombre: string | null }>(`/usuarios/${userId}/supervisor`);
      setSelectedSupervisorId(res.data.supervisorUserId ?? '');
      setCurrentSupervisorNombre(res.data.supervisorNombre ?? '');
      setEditingSupervisorUser({ id: userId, nombre, supervisorNombre: res.data.supervisorNombre });
    } catch {
      alert('Error al cargar supervisor');
    }
  };

  const handleSaveSupervisor = async () => {
    if (!editingSupervisorUser) return;
    setSavingSupervisor(true);
    try {
      await apiClient.put(`/usuarios/${editingSupervisorUser.id}/supervisor`, {
        supervisorUserId: selectedSupervisorId || null,
      });
      setEditingSupervisorUser(null);
    } catch {
      alert('Error al guardar supervisor');
    } finally {
      setSavingSupervisor(false);
    }
  };

  const openEditUser = (usuario: { id: string; nombre: string; role: Role; email: string }) => {
    setEditingUser(usuario);
    setEditForm({ nombre: usuario.nombre, role: usuario.role });
  };

  const handleSaveUser = async () => {
    if (!editingUser) return;
    setSavingUser(true);
    try {
      await updateUsuario.mutateAsync({ id: editingUser.id, data: editForm });
      setEditingUser(null);
    } catch (error: any) {
      alert(error.response?.data?.message || 'Error al guardar usuario');
    } finally {
      setSavingUser(false);
    }
  };

  const openEditAccesos = async (userId: string, nombre: string) => {
    try {
      const res = await apiClient.get<{ data: string[] }>(`/usuarios/${userId}/accesos`);
      setAccesosRfcIds(res.data.data);
      setEditingAccesosUser({ id: userId, nombre });
    } catch {
      alert('Error al cargar accesos');
    }
  };

  const handleSaveAccesos = async () => {
    if (!editingAccesosUser) return;
    setSavingAccesos(true);
    try {
      await apiClient.post(`/usuarios/${editingAccesosUser.id}/accesos`, { entidadIds: accesosRfcIds });
      setEditingAccesosUser(null);
    } catch {
      alert('Error al guardar accesos');
    } finally {
      setSavingAccesos(false);
    }
  };

  const toggleAccesoRfc = (id: string) => {
    setAccesosRfcIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
  };

  // Fetch supervisors for auxiliar invite dropdown
  const { data: supervisores } = useQuery({
    queryKey: ['cartera-supervisores'],
    queryFn: async () => {
      const res = await apiClient.get<{ data: Array<{ userId: string; nombre: string; email: string }> }>('/carteras/supervisores');
      return res.data.data;
    },
    enabled: isDespacho && isAdmin,
  });

  const toggleRfc = (id: string) => {
    setSelectedRfcIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
    );
  };

  const handleInvite = async (e: React.FormEvent) => {
    e.preventDefault();
    if (inviteForm.role === 'auxiliar' && !inviteForm.supervisorUserId) {
      alert('Debes asignar un supervisor al auxiliar');
      return;
    }
    try {
      const newUser = await inviteUsuario.mutateAsync(inviteForm);
      // If role is 'cliente' and RFCs were selected, grant access to each
      if (inviteForm.role === 'cliente' && selectedRfcIds.length > 0) {
        await Promise.all(
          selectedRfcIds.map((rfcId) => addClienteAcceso(rfcId, newUser.id)),
        );
      }
      setShowInvite(false);
      setInviteForm({ email: '', nombre: '', role: defaultInviteRole as UserInvite['role'], supervisorUserId: undefined });
      setSelectedRfcIds([]);
    } catch (error: any) {
      alert(error.response?.data?.message || 'Error al invitar usuario');
    }
  };

  const handleToggleActive = (id: string, active: boolean) => {
    updateUsuario.mutate({ id, data: { active: !active } });
  };

  const handleDelete = (id: string) => {
    if (confirm('¿Eliminar este usuario?')) {
      deleteUsuario.mutate(id);
    }
  };

  return (
    <DashboardShell title="Usuarios">
      <div className="space-y-4">
        {/* Header */}
        <div className="flex justify-between items-center">
          <div>
            <h1 className="text-2xl font-bold">Usuarios</h1>
            <p className="text-sm text-muted-foreground">Gestiona tu equipo</p>
          </div>
          <div className="flex items-center gap-2">
            {isAdmin && isDespacho && (
              <Button variant="outline" className="flex items-center gap-2" asChild>
                <Link href="/carteras">
                  <FolderOpen className="h-4 w-4" /> Gestionar Carteras
                </Link>
              </Button>
            )}
            {isAdmin && (
              <Button onClick={() => setShowInvite(true)}>
                <UserPlus className="h-4 w-4 mr-2" />
                Invitar Usuario
              </Button>
            )}
          </div>
        </div>
        {/* User count */}
        <div className="flex items-center gap-2 text-sm text-muted-foreground">
          <Users className="h-4 w-4" />
          <span>{usuarios?.length || 0} usuarios</span>
        </div>

        {/* Invite Form */}
        {showInvite && (
          <Card>
            <CardHeader>
              <CardTitle>Invitar Nuevo Usuario</CardTitle>
            </CardHeader>
            <CardContent>
              <form onSubmit={handleInvite} className="space-y-4">
                <div className="grid gap-4 md:grid-cols-3">
                  <div className="space-y-2">
                    <Label htmlFor="email">Email</Label>
                    <Input
                      id="email"
                      type="email"
                      value={inviteForm.email}
                      onChange={e => setInviteForm({ ...inviteForm, email: e.target.value })}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="nombre">Nombre</Label>
                    <Input
                      id="nombre"
                      value={inviteForm.nombre}
                      onChange={e => setInviteForm({ ...inviteForm, nombre: e.target.value })}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="role">Rol</Label>
                    <Select
                      value={inviteForm.role}
                      onValueChange={(v) => {
                        const isAuxiliar = v === 'auxiliar';
                        const isSupervisor = currentUser?.role === 'supervisor';
                        setInviteForm({
                          ...inviteForm,
                          role: v as UserInvite['role'],
                          supervisorUserId: isAuxiliar && isSupervisor ? currentUser?.id : undefined,
                        });
                        if (v !== 'cliente') setSelectedRfcIds([]);
                      }}
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {inviteRoles.map((r: { value: string; label: string; description?: string }) => (
                          <SelectItem key={r.value} value={r.value}>
                            <div className="flex flex-col">
                              <span>{r.label}</span>
                              {'description' in r && r.description && (
                                <span className="text-xs text-muted-foreground">{r.description}</span>
                              )}
                            </div>
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
                {/* Supervisor selector for auxiliar role */}
                {isDespacho && inviteForm.role === 'auxiliar' && (
                  <div className="space-y-2">
                    <Label>Supervisor asignado</Label>
                    {supervisores && supervisores.length > 0 ? (
                      <Select
                        value={inviteForm.supervisorUserId || ''}
                        onValueChange={(v) => setInviteForm({ ...inviteForm, supervisorUserId: v })}
                      >
                        <SelectTrigger>
                          <SelectValue placeholder="Seleccionar supervisor..." />
                        </SelectTrigger>
                        <SelectContent>
                          {supervisores.map(s => (
                            <SelectItem key={s.userId} value={s.userId}>
                              {s.nombre} ({s.email})
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    ) : (
                      <p className="text-sm text-muted-foreground border rounded-md p-3">
                        No hay supervisores registrados. Crea uno primero para poder asignar auxiliares.
                      </p>
                    )}
                  </div>
                )}
                {/* RFC access for cliente role */}
                {isDespacho && inviteForm.role === 'cliente' && contribuyentes && contribuyentes.length > 0 && (
                  <div className="space-y-2">
                    <Label>RFCs con acceso (opcional)</Label>
                    <div className="border rounded-md p-3 space-y-2 max-h-48 overflow-y-auto">
                      {contribuyentes.map((c) => (
                        <div key={c.id} className="flex items-center gap-2">
                          <input
                            type="checkbox"
                            id={`rfc-${c.id}`}
                            checked={selectedRfcIds.includes(c.id)}
                            onChange={() => toggleRfc(c.id)}
                            className="h-4 w-4"
                          />
                          <label htmlFor={`rfc-${c.id}`} className="text-sm cursor-pointer">
                            <span className="font-mono">{c.rfc}</span>
                            {' — '}
                            <span className="text-muted-foreground">{c.nombre}</span>
                          </label>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                <div className="flex gap-2">
                  <Button type="submit" disabled={inviteUsuario.isPending}>
                    {inviteUsuario.isPending ? 'Enviando...' : 'Enviar Invitación'}
                  </Button>
                  <Button type="button" variant="outline" onClick={() => { setShowInvite(false); setSelectedRfcIds([]); }}>
                    Cancelar
                  </Button>
                </div>
              </form>
            </CardContent>
          </Card>
        )}

        {/* Users List */}
        <Card>
          <CardContent className="p-0">
            {isLoading ? (
              <div className="text-center py-8 text-muted-foreground">Cargando...</div>
            ) : (
              <div className="divide-y">
                {usuarios?.map(usuario => {
                  const roleInfo = getRoleInfo(usuario.role, isDespacho);
                  const RoleIcon = roleInfo.icon;
                  const isCurrentUser = usuario.id === currentUser?.id;

                  return (
                    <div key={usuario.id} className="p-4 flex items-center justify-between">
                      <div className="flex items-center gap-4">
                        <div className={cn(
                          'w-10 h-10 rounded-full flex items-center justify-center',
                          'bg-primary/10 text-primary font-medium'
                        )}>
                          {usuario.nombre.charAt(0).toUpperCase()}
                        </div>
                        <div>
                          <div className="flex items-center gap-2">
                            <span className="font-medium">{usuario.nombre}</span>
                            {isCurrentUser && (
                              <span className="text-xs bg-primary/10 text-primary px-2 py-0.5 rounded">Tú</span>
                            )}
                            {!usuario.active && (
                              <span className="text-xs bg-destructive/10 text-destructive px-2 py-0.5 rounded">Inactivo</span>
                            )}
                          </div>
                          <div className="text-sm text-muted-foreground">{usuario.email}</div>
                        </div>
                      </div>
                      <div className="flex items-center gap-4">
                        <div className={cn('flex items-center gap-1', roleInfo.color)}>
                          <RoleIcon className="h-4 w-4" />
                          <span className="text-sm">{roleInfo.label}</span>
                        </div>
                        {isOwner && (
                          <div className="flex gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => openEditUser(usuario)}
                              title="Editar nombre y rol"
                            >
                              <Pencil className="h-4 w-4 mr-1" /> Editar
                            </Button>
                          </div>
                        )}
                        {isAdmin && !isCurrentUser && (
                          <div className="flex gap-1">
                            {isDespacho && usuario.role === 'cliente' && (
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => openEditAccesos(usuario.id, usuario.nombre)}
                                title="Editar RFCs con acceso"
                              >
                                <KeyRound className="h-4 w-4 mr-1" /> Accesos
                              </Button>
                            )}
                            {isDespacho && usuario.role === 'auxiliar' && (
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => openEditSupervisor(usuario.id, usuario.nombre)}
                                title="Asignar supervisor"
                              >
                                <UserCheck className="h-4 w-4 mr-1" /> Supervisor
                              </Button>
                            )}
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleToggleActive(usuario.id, usuario.active)}
                            >
                              {usuario.active ? 'Desactivar' : 'Activar'}
                            </Button>
                            <Button
                              variant="ghost"
                              size="icon"
                              onClick={() => handleDelete(usuario.id)}
                            >
                              <Trash2 className="h-4 w-4" />
                            </Button>
                          </div>
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Edit Accesos Modal */}
      {editingAccesosUser && (
        <Dialog open onOpenChange={(open) => { if (!open) setEditingAccesosUser(null); }}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Editar accesos — {editingAccesosUser.nombre}</DialogTitle>
            </DialogHeader>
            <div className="space-y-2 max-h-60 overflow-y-auto py-2">
              {contribuyentes && contribuyentes.length > 0 ? (
                contribuyentes.map((c) => (
                  <div key={c.id} className="flex items-center gap-2">
                    <input
                      type="checkbox"
                      id={`acceso-${c.id}`}
                      checked={accesosRfcIds.includes(c.id)}
                      onChange={() => toggleAccesoRfc(c.id)}
                      className="h-4 w-4"
                    />
                    <label htmlFor={`acceso-${c.id}`} className="text-sm cursor-pointer">
                      <span className="font-mono">{c.rfc}</span>
                      {' — '}
                      <span className="text-muted-foreground">{c.nombre}</span>
                    </label>
                  </div>
                ))
              ) : (
                <p className="text-sm text-muted-foreground">No hay contribuyentes registrados.</p>
              )}
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={() => setEditingAccesosUser(null)}>Cancelar</Button>
              <Button onClick={handleSaveAccesos} disabled={savingAccesos}>
                {savingAccesos ? 'Guardando...' : 'Guardar'}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}

      {/* Edit Supervisor Modal (auxiliares) */}
      {editingSupervisorUser && (
        <Dialog open onOpenChange={(open) => { if (!open) setEditingSupervisorUser(null); }}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Asignar supervisor — {editingSupervisorUser.nombre}</DialogTitle>
            </DialogHeader>
            <div className="space-y-2 py-2">
              {supervisores && supervisores.length > 0 ? (
                <Select value={selectedSupervisorId || 'none'} onValueChange={(v) => setSelectedSupervisorId(v === 'none' ? '' : v)}>
                  <SelectTrigger className="w-full">
                    {(() => {
                      if (!selectedSupervisorId || selectedSupervisorId === 'none') return <span className="text-muted-foreground">Sin supervisor asignado</span>;
                      const s = supervisores?.find(x => x.userId === selectedSupervisorId);
                      if (s) return <span>{s.nombre} — {s.email}</span>;
                      return <span>{currentSupervisorNombre || editingSupervisorUser?.supervisorNombre || selectedSupervisorId}</span>;
                    })()}
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">Sin supervisor asignado</SelectItem>
                    {supervisores.map(s => (
                      <SelectItem key={s.userId} value={s.userId}>
                        {s.nombre} — {s.email}
                      </SelectItem>
                    ))}
                    {/* Si el supervisor actual no está en la lista de carteras, mostrarlo igual */}
                    {selectedSupervisorId && !supervisores.some(s => s.userId === selectedSupervisorId) && (
                      <SelectItem value={selectedSupervisorId}>
                        {currentSupervisorNombre || editingSupervisorUser?.supervisorNombre || selectedSupervisorId}
                      </SelectItem>
                    )}
                  </SelectContent>
                </Select>
              ) : (
                <p className="text-sm text-muted-foreground">No hay supervisores registrados todavía.</p>
              )}
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={() => setEditingSupervisorUser(null)}>Cancelar</Button>
              <Button onClick={handleSaveSupervisor} disabled={savingSupervisor}>
                {savingSupervisor ? 'Guardando...' : 'Guardar'}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}

      {/* Edit User Modal */}
      {editingUser && (
        <Dialog open onOpenChange={(open) => { if (!open) setEditingUser(null); }}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Editar usuario</DialogTitle>
            </DialogHeader>
            <div className="space-y-4 py-2">
              <div className="space-y-2">
                <Label htmlFor="edit-email">Email</Label>
                <Input id="edit-email" value={editingUser.email} disabled />
              </div>
              <div className="space-y-2">
                <Label htmlFor="edit-nombre">Nombre</Label>
                <Input
                  id="edit-nombre"
                  value={editForm.nombre}
                  onChange={e => setEditForm({ ...editForm, nombre: e.target.value })}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="edit-role">Rol</Label>
                {editingUser.id === currentUser?.id ? (
                  <div className="text-sm border rounded-md px-3 py-2 bg-muted text-muted-foreground">
                    {getRoleInfo(editForm.role, isDespacho).label}
                  </div>
                ) : (
                  <Select
                    value={editForm.role}
                    onValueChange={(v) => setEditForm({ ...editForm, role: v as Role })}
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {(isDespacho
                        ? (['owner', 'supervisor', 'auxiliar', 'cliente'] as Role[])
                        : (['owner', 'cfo', 'contador', 'visor', 'auxiliar'] as Role[])
                      ).map((r) => (
                        <SelectItem key={r} value={r}>
                          {getRoleInfo(r, isDespacho).label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                )}
                {editingUser.id === currentUser?.id && (
                  <p className="text-xs text-muted-foreground">No puedes cambiar tu propio rol.</p>
                )}
              </div>
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={() => setEditingUser(null)}>Cancelar</Button>
              <Button onClick={handleSaveUser} disabled={savingUser}>
                {savingUser ? 'Guardando...' : 'Guardar'}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}
    </DashboardShell>
  );
}
