import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

vi.mock('../../src/api/usrApi', () => ({
  fetchCompanies: vi.fn(),
  login: vi.fn(),
}));

import { fetchCompanies, login } from '../../src/api/usrApi';
import LoginPage from '../../src/pages/usr/Login/LoginPage';
import { renderWithProviders } from './renderLogin';

const mockedFetch = fetchCompanies as unknown as ReturnType<typeof vi.fn>;
const mockedLogin = login as unknown as ReturnType<typeof vi.fn>;

async function selectVersion(user: ReturnType<typeof userEvent.setup>, label: string) {
  const combobox = screen.getByRole('combobox');
  await user.click(combobox);
  const option = await screen.findByText(label);
  await user.click(option);
}

describe('LoginPage 必填校验', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
    mockedFetch.mockResolvedValue([
      { id: 1, sCompanyName: '甲公司', sVersion: '标准版' },
      { id: 2, sCompanyName: '乙公司', sVersion: null },
    ]);
  });

  it('blocks submit and shows required messages when empty', async () => {
    renderWithProviders(<LoginPage />);
    // 等待版本加载完成
    expect(await screen.findByText('请选择版本')).toBeInTheDocument();
    const user = userEvent.setup();
    await user.click(screen.getByRole('button', { name: /登\s*录/ }));
    // 校验错误文案渲染在 .ant-form-item-explain-error，逐条断言（避免与 Select placeholder 文案冲突）
    await waitFor(() => {
      const errors = Array.from(
        document.querySelectorAll('.ant-form-item-explain-error'),
      ).map((el) => el.textContent);
      expect(errors).toContain('请输入用户名');
      expect(errors).toContain('请输入密码');
      expect(errors).toContain('请选择版本');
    });
    expect(mockedLogin).not.toHaveBeenCalled();
  });

  it('submits with payload when all filled', async () => {
    mockedLogin.mockReturnValue(new Promise(() => {})); // 挂起，只断言入参
    renderWithProviders(<LoginPage />);
    expect(await screen.findByText('请选择版本')).toBeInTheDocument();
    const user = userEvent.setup();
    await user.type(screen.getByPlaceholderText('请输入你的用户名'), 'admin');
    await user.type(screen.getByPlaceholderText('请输入你的密码'), 'secret');
    await selectVersion(user, '乙公司');
    await user.click(screen.getByRole('button', { name: /登\s*录/ }));
    await waitFor(() =>
      expect(mockedLogin).toHaveBeenCalledWith({
        sUserName: 'admin',
        password: 'secret',
        companyId: 2,
      }),
    );
  });
});
