/* eslint-disable import-x/order */
import { fireEvent, render, screen } from '@testing-library/react';
import * as React from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';

// Mock lucide-react icons to avoid SVG rendering issues
vi.mock('lucide-react', () => ({
  ChevronDown: () => <span data-testid="icon-chevron-down" />,
  LayoutDashboard: () => <span data-testid="icon-layout-dashboard" />,
  LogOut: () => <span data-testid="icon-logout" />,
  Menu: () => <span data-testid="icon-menu" />,
  Moon: () => <span data-testid="icon-moon" />,
  Shield: () => <span data-testid="icon-shield" />,
  Sun: () => <span data-testid="icon-sun" />,
  User: () => <span data-testid="icon-user" />,
  X: () => <span data-testid="icon-x" />,
}));

import { Navbar, type NavbarProps } from '../navbar';

const renderLink: NavbarProps['renderLink'] = ({ href, children, className, onClick }) => (
  <a href={href} className={className} onClick={onClick}>
    {children}
  </a>
);

const baseLabels: NavbarProps['labels'] = {
  login: 'Đăng nhập',
  register: 'Đăng ký',
  dashboard: 'Quản lý',
  admin: 'Quản trị',
  profile: 'Hồ sơ',
  logout: 'Đăng xuất',
  openMenu: 'Mở menu',
  closeMenu: 'Đóng menu',
  darkMode: 'Chế độ tối',
  lightMode: 'Chế độ sáng',
  mainNav: 'Điều hướng chính',
};

const baseLinks: NavbarProps['links'] = [
  { href: '/', label: 'Trang chủ', isActive: true },
  { href: '/search', label: 'Tìm kiếm', isActive: false },
  { href: '/pricing', label: 'Bảng giá', isActive: false },
];

const defaultProps: NavbarProps = {
  brand: 'GoodGo',
  links: baseLinks,
  user: null,
  dashboardHref: '/dashboard',
  theme: 'light',
  onToggleTheme: vi.fn(),
  onLogout: vi.fn(),
  labels: baseLabels,
  renderLink,
};

describe('Navbar', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders the brand name', () => {
    render(<Navbar {...defaultProps} />);
    expect(screen.getByText('GoodGo')).toBeInTheDocument();
  });

  it('renders as a banner landmark', () => {
    render(<Navbar {...defaultProps} />);
    expect(screen.getByRole('banner')).toBeInTheDocument();
  });

  it('renders desktop nav links', () => {
    render(<Navbar {...defaultProps} />);
    expect(screen.getAllByText('Trang chủ').length).toBeGreaterThan(0);
    expect(screen.getAllByText('Tìm kiếm').length).toBeGreaterThan(0);
    expect(screen.getAllByText('Bảng giá').length).toBeGreaterThan(0);
  });

  it('renders login and register buttons when unauthenticated', () => {
    render(<Navbar {...defaultProps} />);
    expect(screen.getAllByText('Đăng nhập').length).toBeGreaterThan(0);
    expect(screen.getAllByText('Đăng ký').length).toBeGreaterThan(0);
  });

  it('does not render dashboard button when unauthenticated', () => {
    render(<Navbar {...defaultProps} />);
    expect(screen.queryByText('Quản lý')).toBeNull();
  });

  it('renders user full name when authenticated', () => {
    render(
      <Navbar
        {...defaultProps}
        user={{ fullName: 'Nguyễn Văn A', role: 'BUYER', email: 'a@test.com' }}
      />,
    );
    expect(screen.getAllByText('Nguyễn Văn A').length).toBeGreaterThan(0);
  });

  it('renders dashboard menu item for authenticated user (after opening dropdown)', () => {
    render(
      <Navbar
        {...defaultProps}
        user={{ fullName: 'Nguyễn Văn A', role: 'BUYER' }}
      />,
    );
    // The pill is the dropdown trigger; click it to reveal the menu.
    const trigger = screen.getByRole('button', { name: /Nguyễn Văn A/ });
    fireEvent.click(trigger);
    expect(screen.getByRole('menuitem', { name: /Quản lý/ })).toBeInTheDocument();
  });

  it('renders admin label as a role badge AND in the dropdown for ADMIN role', () => {
    render(
      <Navbar
        {...defaultProps}
        user={{ fullName: 'Admin User', role: 'ADMIN' }}
      />,
    );
    // Role badge in the trigger pill is always visible.
    expect(screen.getByText('Quản trị viên')).toBeInTheDocument();
    // After opening, the ADMIN-specific menu item shows.
    fireEvent.click(screen.getByRole('button', { name: /Admin User/ }));
    expect(screen.getByRole('menuitem', { name: /Quản trị/ })).toBeInTheDocument();
  });

  it('shows moon icon in light theme', () => {
    render(<Navbar {...defaultProps} theme="light" />);
    expect(screen.getByTestId('icon-moon')).toBeInTheDocument();
  });

  it('shows sun icon in dark theme', () => {
    render(<Navbar {...defaultProps} theme="dark" />);
    expect(screen.getByTestId('icon-sun')).toBeInTheDocument();
  });

  it('calls onToggleTheme when theme button is clicked', () => {
    const onToggleTheme = vi.fn();
    render(<Navbar {...defaultProps} onToggleTheme={onToggleTheme} />);
    const themeBtn = screen.getByRole('button', { name: 'Chế độ tối' });
    fireEvent.click(themeBtn);
    expect(onToggleTheme).toHaveBeenCalledTimes(1);
  });

  it('toggles mobile menu on hamburger click', () => {
    render(<Navbar {...defaultProps} />);
    const hamburger = screen.getByRole('button', { name: 'Mở menu' });
    fireEvent.click(hamburger);
    expect(screen.getByRole('button', { name: 'Đóng menu' })).toBeInTheDocument();
  });

  it('renders main nav accessible label', () => {
    render(<Navbar {...defaultProps} />);
    const navEls = screen.getAllByRole('navigation');
    const mainNavs = navEls.filter((el) => el.getAttribute('aria-label') === 'Điều hướng chính');
    expect(mainNavs.length).toBeGreaterThan(0);
  });

  it('renders notification slot when provided', () => {
    render(
      <Navbar
        {...defaultProps}
        user={{ fullName: 'User', role: 'BUYER' }}
        notifications={<button aria-label="Thông báo">🔔</button>}
      />,
    );
    expect(screen.getByRole('button', { name: 'Thông báo' })).toBeInTheDocument();
  });

  it('renders language switcher slot when provided', () => {
    render(
      <Navbar
        {...defaultProps}
        languageSwitcher={<div data-testid="lang-sw">VI</div>}
      />,
    );
    expect(screen.getByTestId('lang-sw')).toBeInTheDocument();
  });

  it('calls onLogout and closes mobile menu when logout clicked', async () => {
    const onLogout = vi.fn().mockResolvedValue(undefined);
    render(
      <Navbar
        {...defaultProps}
        user={{ fullName: 'User', role: 'BUYER' }}
        onLogout={onLogout}
      />,
    );
    // Open mobile menu
    fireEvent.click(screen.getByRole('button', { name: 'Mở menu' }));
    const logoutBtn = screen.getByRole('button', { name: 'Đăng xuất' });
    fireEvent.click(logoutBtn);
    expect(onLogout).toHaveBeenCalledTimes(1);
  });
});
