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';

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>
  ),
}));

vi.mock('@/lib/auth-store', () => {
  const store = {
    register: vi.fn(),
    isLoading: false,
    error: null,
    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: {
    register: ReturnType<typeof vi.fn>;
    isLoading: boolean;
    error: string | null;
    clearError: ReturnType<typeof vi.fn>;
  };

  beforeEach(() => {
    vi.clearAllMocks();
    mockStore = {
      register: vi.fn(),
      isLoading: false,
      error: null,
      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.getByText('Tạo tài khoản')).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('/');
    });
  });
});
