/* eslint-disable import-x/order */
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { useAuthStore } from '@/lib/auth-store';

// Mock next-intl with Vietnamese messages
const viMessages = await import('@/messages/vi.json');
vi.mock('next-intl', () => ({
  useTranslations: (namespace: string) => {
    const messages = viMessages.default ?? viMessages;
    const ns = messages[namespace as keyof typeof messages] as Record<string, unknown> | undefined;
    return (key: string) => {
      if (!ns) return key;
      const parts = key.split('.');
      let val: unknown = ns;
      for (const p of parts) {
        val = (val as Record<string, unknown>)?.[p];
      }
      return typeof val === 'string' ? val : key;
    };
  },
  NextIntlClientProvider: ({ children }: { children: React.ReactNode }) => children,
}));

const mockPush = vi.fn();
vi.mock('next/navigation', () => ({
  useRouter: () => ({ push: mockPush }),
}));

vi.mock('next/link', () => ({
  default: ({ children, href, ...props }: { children: React.ReactNode; href: string; [key: string]: unknown }) => (
    <a href={href} {...props}>{children}</a>
  ),
}));

// Mock i18n navigation (Link used in register page)
vi.mock('@/i18n/navigation', () => ({
  Link: ({ children, href, ...props }: { children: React.ReactNode; href: string; [key: string]: unknown }) => (
    <a href={href} {...props}>{children}</a>
  ),
  useRouter: () => ({ push: vi.fn(), replace: vi.fn() }),
  usePathname: () => '/register',
  redirect: vi.fn(),
}));

vi.mock('@/lib/auth-store', () => {
  const store = {
    user: null,
    isAuthenticated: false,
    isInitialized: false,
    isLoading: false,
    error: null,
    login: vi.fn(),
    register: vi.fn(),
    handleOAuthCallback: vi.fn(),
    logout: vi.fn(),
    refreshToken: vi.fn(),
    fetchProfile: vi.fn(),
    initialize: vi.fn(),
    clearError: vi.fn(),
  };
  return {
    useAuthStore: vi.fn((selector) => {
      if (typeof selector === 'function') return selector(store);
      return store;
    }),
  };
});

import RegisterPage from '../register/page';

const mockedUseAuthStore = vi.mocked(useAuthStore);

describe('RegisterPage', () => {
  let mockStore: {
    user: null;
    isAuthenticated: boolean;
    isInitialized: boolean;
    isLoading: boolean;
    error: string | null;
    login: ReturnType<typeof vi.fn>;
    register: ReturnType<typeof vi.fn>;
    handleOAuthCallback: ReturnType<typeof vi.fn>;
    logout: ReturnType<typeof vi.fn>;
    refreshToken: ReturnType<typeof vi.fn>;
    fetchProfile: ReturnType<typeof vi.fn>;
    initialize: ReturnType<typeof vi.fn>;
    clearError: ReturnType<typeof vi.fn>;
  };

  beforeEach(() => {
    vi.clearAllMocks();
    mockStore = {
      user: null,
      isAuthenticated: false,
      isInitialized: false,
      isLoading: false,
      error: null,
      login: vi.fn(),
      register: vi.fn(),
      handleOAuthCallback: vi.fn(),
      logout: vi.fn(),
      refreshToken: vi.fn(),
      fetchProfile: vi.fn(),
      initialize: vi.fn(),
      clearError: vi.fn(),
    };
    mockedUseAuthStore.mockImplementation((selector) => {
      if (typeof selector === 'function') return (selector as (s: typeof mockStore) => unknown)(mockStore);
      return mockStore as ReturnType<typeof useAuthStore>;
    });
  });

  it('renders register form with all fields', () => {
    render(<RegisterPage />);

    expect(screen.getByRole('heading', { name: 'Đăng ký' })).toBeInTheDocument();
    expect(screen.getByLabelText('Họ và tên')).toBeInTheDocument();
    expect(screen.getByLabelText('Số điện thoại')).toBeInTheDocument();
    expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
    expect(screen.getByLabelText('Mật khẩu')).toBeInTheDocument();
    expect(screen.getByLabelText('Xác nhận mật khẩu')).toBeInTheDocument();
  });

  it('renders login link', () => {
    render(<RegisterPage />);
    const loginLink = screen.getByRole('link', { name: /đăng nhập/i });
    expect(loginLink).toHaveAttribute('href', '/login');
  });

  it('submits form with valid data', async () => {
    mockStore.register.mockResolvedValue(undefined);
    render(<RegisterPage />);

    await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A');
    await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678');
    await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123');
    await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'password123');
    await userEvent.click(screen.getByRole('button', { name: /đăng ký/i }));

    await waitFor(() => {
      expect(mockStore.register).toHaveBeenCalledWith({
        phone: '0912345678',
        password: 'password123',
        fullName: 'Nguyen Van A',
        email: undefined,
      });
    });
  });

  it('shows validation error for short password', async () => {
    render(<RegisterPage />);

    await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A');
    await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678');
    await userEvent.type(screen.getByLabelText('Mật khẩu'), 'short');
    await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'short');
    await userEvent.click(screen.getByRole('button', { name: /đăng ký/i }));

    await waitFor(() => {
      const alerts = screen.getAllByRole('alert');
      expect(alerts.length).toBeGreaterThan(0);
    });
  });

  it('shows error when passwords do not match', async () => {
    render(<RegisterPage />);

    await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A');
    await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678');
    await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123');
    await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'differentpw');
    await userEvent.click(screen.getByRole('button', { name: /đăng ký/i }));

    await waitFor(() => {
      const alerts = screen.getAllByRole('alert');
      expect(alerts.length).toBeGreaterThan(0);
    });
  });

  it('displays store error message', () => {
    mockStore.error = 'Số điện thoại đã tồn tại';
    render(<RegisterPage />);
    expect(screen.getByText('Số điện thoại đã tồn tại')).toBeInTheDocument();
  });

  it('navigates to home after successful registration', async () => {
    mockStore.register.mockResolvedValue(undefined);
    render(<RegisterPage />);

    await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A');
    await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678');
    await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123');
    await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'password123');
    await userEvent.click(screen.getByRole('button', { name: /đăng ký/i }));

    await waitFor(() => {
      expect(mockPush).toHaveBeenCalledWith('/');
    });
  });
});
