"use client";

/**
 * UserMenu — личный кабинет в правом верхнем углу top-bar (gendsgn.ru/).
 *
 * Avatar-кнопка с инициалом из username + dropdown:
 *   - текущий username
 *   - role badge («Админ» / «Пилот» / «Аналитик»)
 *   - кнопка «Выйти» — invalidate Caddy basic_auth cached creds в browser
 *
 * Используется в `TopNav.rightSlot`. Если /me грузится или 401 (dev без
 * Caddy) — рендерим null (нечего показывать).
 *
 * Logout flow — basic_auth quirk:
 *   1. Отправляем fetch с заведомо неправильными Basic creds → 401 от Caddy
 *      → браузер забывает cached creds для этого origin.
 *   2. Hard reload (`window.location.href = "/"`) — basic_auth prompt
 *      покажется заново.
 *   Это работает в Safari/Chrome/Firefox; legacy `ClearAuthenticationCache`
 *   не нужен.
 */

import { useEffect, useRef, useState } from "react";

import { LogOut } from "lucide-react";

import { logout } from "@/lib/logout";

import { useMe, type Role } from "@/lib/useMe";

/**
 * Локализация ролей для badge. Должен покрывать все варианты `Role` из
 * `lib/useMe.ts` — TypeScript-проверка через `Record<Role, string>`
 * сломает build, если backend добавит новую роль без обновления map.
 */
const ROLE_LABELS: Record<Role, string> = {
  admin: "Админ",
  pilot: "Пилот",
  analyst: "Аналитик",
};

export function UserMenu() {
  const { data, isLoading, error } = useMe();
  const [open, setOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const buttonRef = useRef<HTMLButtonElement>(null);

  // Click outside → закрыть dropdown.
  useEffect(() => {
    if (!open) return;
    function handleClick(e: MouseEvent) {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target as Node)
      ) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [open]);

  // Escape key → закрыть + вернуть focus на avatar.
  useEffect(() => {
    if (!open) return;
    function handleKey(e: KeyboardEvent) {
      if (e.key === "Escape") {
        setOpen(false);
        buttonRef.current?.focus();
      }
    }
    document.addEventListener("keydown", handleKey);
    return () => document.removeEventListener("keydown", handleKey);
  }, [open]);

  // Loading / 401 / no data — ничего не рендерим.
  // TopNav сам обрабатывает 401 (dev без Caddy) — показывает все nav items.
  // Тут просто прячемся, чтобы не было «пустого» avatar без username.
  if (isLoading || error || !data) return null;

  const initial = data.username[0]?.toUpperCase() ?? "?";
  // Runtime-fallback: TS гарантирует синхрон ROLE_LABELS только compile-time.
  // Если backend добавит роль в roles.yaml и /me вернёт её до обновления фронта,
  // ROLE_LABELS[data.role] === undefined → badge отрендерится пустым. Падаем
  // на сырое значение роли, чтобы badge всегда был подписан.
  const roleLabel = ROLE_LABELS[data.role] ?? data.role;

  return (
    <div ref={containerRef} style={{ position: "relative" }}>
      <button
        ref={buttonRef}
        type="button"
        onClick={() => setOpen((v) => !v)}
        aria-label="Личный кабинет"
        aria-haspopup="menu"
        aria-expanded={open}
        style={{
          width: 32,
          height: 32,
          borderRadius: "50%",
          background: "var(--accent-soft)",
          color: "var(--accent)",
          border: "none",
          fontWeight: 600,
          fontSize: 14,
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          padding: 0,
          fontFamily: "inherit",
        }}
      >
        {initial}
      </button>

      {open && (
        <div
          role="menu"
          aria-label="Личный кабинет"
          style={{
            position: "absolute",
            top: "calc(100% + 8px)",
            right: 0,
            minWidth: 200,
            background: "var(--bg-card)",
            border: "1px solid var(--border-card)",
            borderRadius: 8,
            padding: 12,
            // Popover (не card) — допустимая лёгкая тень для отделения.
            boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)",
            zIndex: 200,
          }}
        >
          <div
            style={{
              fontSize: 14,
              fontWeight: 500,
              color: "var(--fg-primary)",
              marginBottom: 4,
              wordBreak: "break-all",
            }}
          >
            {data.username}
          </div>
          <div
            style={{
              display: "inline-block",
              background: "var(--accent-soft)",
              color: "var(--accent)",
              padding: "2px 8px",
              borderRadius: 4,
              fontSize: 11,
              textTransform: "uppercase",
              letterSpacing: "0.04em",
              fontWeight: 500,
            }}
          >
            {roleLabel}
          </div>
          <hr
            style={{
              margin: "12px 0",
              border: "none",
              borderTop: "1px solid var(--border-soft)",
            }}
          />
          <button
            role="menuitem"
            type="button"
            onClick={logout}
            style={{
              display: "flex",
              alignItems: "center",
              gap: 8,
              width: "100%",
              background: "none",
              border: "none",
              padding: "4px 0",
              cursor: "pointer",
              color: "var(--danger)",
              fontWeight: 500,
              fontSize: 14,
              textAlign: "left",
              fontFamily: "inherit",
            }}
          >
            <LogOut size={16} strokeWidth={1.5} />
            Выйти
          </button>
        </div>
      )}
    </div>
  );
}
