import { useState, useRef, useEffect } from 'react';
import { toast } from 'sonner';
import {
  MoreHorizontal,
  ShieldCheck,
  ShieldOff,
  KeyRound,
  UserX,
  UserCheck,
  LogOut,
  Smartphone,
  SmartphoneOff,
  ChevronRight,
  Loader2,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useConfirmAction } from '@/hooks/useConfirmAction';
import {
  useUpdateRole,
  useResetPassword,
  useDisableMfa,
  useEnforceMfa,
  useRemoveMfaEnforcement,
  useToggleUserActive,
  useRevokeSessions,
  getErrorMessage,
} from '@/hooks/useAdmin';
import type { AdminUserDetail, UserRole } from '@/types';
import { cn } from '@/lib/utils';

interface UserActionsMenuProps {
  user: AdminUserDetail;
}

const ROLES: { value: UserRole; label: string }[] = [
  { value: 'admin', label: 'Admin' },
  { value: 'standard', label: 'Standard' },
  { value: 'public_event_manager', label: 'Public Event Manager' },
];

export default function UserActionsMenu({ user }: UserActionsMenuProps) {
  const [open, setOpen] = useState(false);
  const [roleSubmenuOpen, setRoleSubmenuOpen] = useState(false);
  const [showResetPassword, setShowResetPassword] = useState(false);
  const [newPassword, setNewPassword] = useState('');
  const menuRef = useRef<HTMLDivElement>(null);

  const updateRole = useUpdateRole();
  const resetPassword = useResetPassword();
  const disableMfa = useDisableMfa();
  const enforceMfa = useEnforceMfa();
  const removeMfaEnforcement = useRemoveMfaEnforcement();
  const toggleActive = useToggleUserActive();
  const revokeSessions = useRevokeSessions();

  // Close on outside click
  useEffect(() => {
    const handleOutside = (e: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setOpen(false);
        setRoleSubmenuOpen(false);
      }
    };
    if (open) document.addEventListener('mousedown', handleOutside);
    return () => document.removeEventListener('mousedown', handleOutside);
  }, [open]);

  const handleAction = async (fn: () => Promise<unknown>, successMsg: string) => {
    try {
      await fn();
      toast.success(successMsg);
      setOpen(false);
    } catch (err) {
      toast.error(getErrorMessage(err, 'Action failed'));
    }
  };

  // Two-click confirms
  const disableMfaConfirm = useConfirmAction(() => {
    handleAction(() => disableMfa.mutateAsync(user.id), 'MFA disabled');
  });

  const toggleActiveConfirm = useConfirmAction(() => {
    handleAction(
      () => toggleActive.mutateAsync({ userId: user.id, active: !user.is_active }),
      user.is_active ? 'Account disabled' : 'Account enabled'
    );
  });

  const revokeSessionsConfirm = useConfirmAction(() => {
    handleAction(() => revokeSessions.mutateAsync(user.id), 'Sessions revoked');
  });

  const isLoading =
    updateRole.isPending ||
    resetPassword.isPending ||
    disableMfa.isPending ||
    enforceMfa.isPending ||
    removeMfaEnforcement.isPending ||
    toggleActive.isPending ||
    revokeSessions.isPending;

  return (
    <div ref={menuRef} className="relative">
      <Button
        variant="ghost"
        size="icon"
        className="h-7 w-7"
        onClick={() => setOpen((v) => !v)}
        aria-label="User actions"
      >
        {isLoading ? (
          <Loader2 className="h-4 w-4 animate-spin" />
        ) : (
          <MoreHorizontal className="h-4 w-4" />
        )}
      </Button>

      {open && (
        <div className="absolute right-0 top-8 z-50 min-w-[200px] rounded-lg border bg-card shadow-lg py-1">
          {/* Edit Role */}
          <div className="relative">
            <button
              className="flex w-full items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-card-elevated transition-colors"
              onMouseEnter={() => setRoleSubmenuOpen(true)}
              onMouseLeave={() => setRoleSubmenuOpen(false)}
              onClick={() => setRoleSubmenuOpen((v) => !v)}
            >
              <span className="flex items-center gap-2">
                <ShieldCheck className="h-4 w-4 text-muted-foreground" />
                Edit Role
              </span>
              <ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
            </button>

            {roleSubmenuOpen && (
              <div
                className="absolute left-full top-0 z-50 min-w-[180px] rounded-lg border bg-card shadow-lg py-1"
                onMouseEnter={() => setRoleSubmenuOpen(true)}
                onMouseLeave={() => setRoleSubmenuOpen(false)}
              >
                {ROLES.map(({ value, label }) => (
                  <button
                    key={value}
                    className={cn(
                      'flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-card-elevated transition-colors',
                      user.role === value && 'text-accent'
                    )}
                    onClick={() =>
                      handleAction(
                        () => updateRole.mutateAsync({ userId: user.id, role: value }),
                        `Role updated to ${label}`
                      )
                    }
                  >
                    {user.role === value && <span className="h-1.5 w-1.5 rounded-full bg-accent" />}
                    {label}
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* Reset Password */}
          {!showResetPassword ? (
            <button
              className="flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-card-elevated transition-colors"
              onClick={() => setShowResetPassword(true)}
            >
              <KeyRound className="h-4 w-4 text-muted-foreground" />
              Reset Password
            </button>
          ) : (
            <div className="px-3 py-2 space-y-2">
              <input
                className="h-8 w-full rounded-md border border-input bg-background px-2 text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
                type="password"
                placeholder="New password"
                value={newPassword}
                onChange={(e) => setNewPassword(e.target.value)}
                autoFocus
              />
              <div className="flex gap-2">
                <button
                  className="flex-1 rounded-md bg-accent/15 px-2 py-1 text-xs text-accent hover:bg-accent/25 transition-colors"
                  onClick={() => {
                    if (!newPassword.trim()) return;
                    handleAction(
                      () => resetPassword.mutateAsync({ userId: user.id, new_password: newPassword }),
                      'Password reset'
                    );
                    setNewPassword('');
                    setShowResetPassword(false);
                  }}
                >
                  Set
                </button>
                <button
                  className="flex-1 rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
                  onClick={() => {
                    setShowResetPassword(false);
                    setNewPassword('');
                  }}
                >
                  Cancel
                </button>
              </div>
            </div>
          )}

          <div className="my-1 border-t border-border" />

          {/* MFA actions */}
          {user.mfa_enforce_pending ? (
            <button
              className="flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-card-elevated transition-colors"
              onClick={() =>
                handleAction(
                  () => removeMfaEnforcement.mutateAsync(user.id),
                  'MFA enforcement removed'
                )
              }
            >
              <SmartphoneOff className="h-4 w-4 text-muted-foreground" />
              Remove MFA Enforcement
            </button>
          ) : (
            <button
              className="flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-card-elevated transition-colors"
              onClick={() =>
                handleAction(() => enforceMfa.mutateAsync(user.id), 'MFA enforcement set')
              }
            >
              <Smartphone className="h-4 w-4 text-muted-foreground" />
              Enforce MFA
            </button>
          )}

          {user.totp_enabled && (
            <button
              className={cn(
                'flex w-full items-center gap-2 px-3 py-2 text-sm transition-colors',
                disableMfaConfirm.confirming
                  ? 'text-orange-400 bg-orange-500/10 hover:bg-orange-500/15'
                  : 'hover:bg-card-elevated'
              )}
              onClick={disableMfaConfirm.handleClick}
            >
              <SmartphoneOff className="h-4 w-4" />
              {disableMfaConfirm.confirming ? 'Sure? Click to confirm' : 'Disable MFA'}
            </button>
          )}

          <div className="my-1 border-t border-border" />

          {/* Disable / Enable Account */}
          <button
            className={cn(
              'flex w-full items-center gap-2 px-3 py-2 text-sm transition-colors',
              toggleActiveConfirm.confirming
                ? 'text-orange-400 bg-orange-500/10 hover:bg-orange-500/15'
                : 'hover:bg-card-elevated'
            )}
            onClick={toggleActiveConfirm.handleClick}
          >
            {user.is_active ? (
              <>
                <UserX className="h-4 w-4" />
                {toggleActiveConfirm.confirming ? 'Sure? Click to confirm' : 'Disable Account'}
              </>
            ) : (
              <>
                <UserCheck className="h-4 w-4 text-green-400" />
                {toggleActiveConfirm.confirming ? 'Sure? Click to confirm' : 'Enable Account'}
              </>
            )}
          </button>

          {/* Revoke Sessions */}
          <button
            className={cn(
              'flex w-full items-center gap-2 px-3 py-2 text-sm transition-colors',
              revokeSessionsConfirm.confirming
                ? 'text-orange-400 bg-orange-500/10 hover:bg-orange-500/15'
                : 'hover:bg-card-elevated'
            )}
            onClick={revokeSessionsConfirm.handleClick}
          >
            <LogOut className="h-4 w-4" />
            {revokeSessionsConfirm.confirming ? 'Sure? Click to confirm' : 'Revoke All Sessions'}
          </button>
        </div>
      )}
    </div>
  );
}
