import { SignInForm } from '@/components/auth/SignInForm';
import { API_BASE } from '@/lib/api';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it, vi } from 'vitest';

let searchParams = new URLSearchParams();
let pathname = '/en/light/sign-in';

vi.mock('next/navigation', () => ({
  usePathname: () => pathname,
  useSearchParams: () => searchParams,
}));

vi.mock('next/image', () => ({
  default: ({ priority, unoptimized, ...props }: any) => <img {...props} />,
}));

function jsonResponse(status: number, body: unknown) {
  return {
    ok: status >= 200 && status < 300,
    status,
    json: vi.fn().mockResolvedValue(body),
  } as unknown as Response;
}

async function submitForm() {
  const user = userEvent.setup();
  await user.type(screen.getByLabelText(/Email/), 'owner@example.com');
  await user.type(screen.getByLabelText(/Password/), 'password123');
  await user.click(screen.getByRole('button', { name: 'Sign in' }));
}

describe('SignInForm auth routing', () => {
  beforeEach(() => {
    searchParams = new URLSearchParams();
    pathname = '/en/light/sign-in';
    vi.stubGlobal('fetch', vi.fn().mockResolvedValue(
      jsonResponse(401, { error: 'invalid_credentials' }),
    ));
  });

  it('uses employee login only on the default sign-in page', async () => {
    vi.mocked(fetch).mockResolvedValueOnce(
      jsonResponse(200, { data: { employee: { id: 'employee_1' } } }),
    );
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.anything(),
    );
  });

  it('falls back to admin login when default employee login rejects the credentials', async () => {
    vi.mocked(fetch)
      .mockResolvedValueOnce(jsonResponse(401, { error: 'invalid_credentials' }))
      .mockResolvedValueOnce(jsonResponse(401, { error: 'totp_required' }));

    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(2));
    expect(fetch).toHaveBeenNthCalledWith(
      1,
      `${API_BASE}/auth/employee/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).toHaveBeenNthCalledWith(
      2,
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(await screen.findByText('Authentication code')).toBeInTheDocument();
  });

  it('uses employee login only when the requested destination is a dashboard path', async () => {
    vi.mocked(fetch).mockResolvedValueOnce(
      jsonResponse(200, { data: { employee: { id: 'employee_1' } } }),
    );
    searchParams = new URLSearchParams('redirect=/dashboard/billing');
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.anything(),
    );
  });

  it('uses admin login only when the admin portal is requested', async () => {
    searchParams = new URLSearchParams('portal=admin');
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.anything(),
    );
  });

  it('uses admin login when the requested destination is an admin path', async () => {
    searchParams = new URLSearchParams('next=/admin/dashboard');
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
  });

  it('uses admin login when the requested destination is an absolute admin URL', async () => {
    searchParams = new URLSearchParams('redirect=http://localhost:3000/admin/dashboard');
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.anything(),
    );
  });

  it('uses admin login when the page forces admin auth mode', async () => {
    render(<SignInForm locale="en" authMode="admin" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.anything(),
    );
  });

  it('uses admin login on the admin sign-in path', async () => {
    pathname = '/en/light/admin-sign-in';
    render(<SignInForm locale="en" />);

    await submitForm();

    await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
    expect(fetch).toHaveBeenCalledWith(
      `${API_BASE}/admin/auth/login`,
      expect.objectContaining({ method: 'POST' }),
    );
    expect(fetch).not.toHaveBeenCalledWith(
      `${API_BASE}/auth/employee/login`,
      expect.anything(),
    );
  });
});
