import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

(globalThis as unknown as { React?: typeof React }).React = React;

const redirectMock = vi.fn();
const getSessionMock = vi.fn();
const isRevokedMock = vi.fn();
const cookiesMock = vi.fn();

const MspSignInMock = () => null;
const PortalSwitchPromptMock = () => null;

vi.mock('next/headers', () => ({
  cookies: cookiesMock,
}));

vi.mock('next/navigation', () => ({
  redirect: redirectMock,
}));

vi.mock('@alga-psa/auth', () => ({
  getSession: getSessionMock,
}));

vi.mock('@alga-psa/db/models/UserSession', () => ({
  UserSession: {
    isRevoked: (...args: unknown[]) => isRevokedMock(...args),
  },
}));

vi.mock('@alga-psa/auth/client', () => ({
  MspSignIn: MspSignInMock,
  PortalSwitchPrompt: PortalSwitchPromptMock,
}));

const { default: MspSignInPage } = await import('server/src/app/auth/msp/signin/page');

describe('MspSignInPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    getSessionMock.mockReset();
    isRevokedMock.mockReset();
    cookiesMock.mockResolvedValue({
      get: vi.fn(() => undefined),
    });
  });

  it('redirects authenticated internal users to the MSP dashboard when no callback is provided', async () => {
    getSessionMock.mockResolvedValue({ user: { id: 'user-1', user_type: 'internal' } });

    await MspSignInPage({ searchParams: Promise.resolve({}) });

    expect(redirectMock).toHaveBeenCalledWith('/msp/dashboard');
  });

  it('redirects authenticated internal users to the provided callback when present', async () => {
    getSessionMock.mockResolvedValue({ user: { id: 'user-2', user_type: 'internal' } });

    await MspSignInPage({ searchParams: Promise.resolve({ callbackUrl: '/msp/tickets' }) });

    expect(redirectMock).toHaveBeenCalledWith('/msp/tickets');
  });

  it('renders a portal switch prompt for authenticated client users', async () => {
    isRevokedMock.mockResolvedValue(false);
    getSessionMock.mockResolvedValue({
      user: { id: 'user-3', user_type: 'client', tenant: 'tenant-1', email: 'client@example.com' },
      session_id: 'session-1',
    });

    const result = await MspSignInPage({ searchParams: Promise.resolve({}) });

    expect(redirectMock).not.toHaveBeenCalled();
    expect((result as any)?.type).toBe(PortalSwitchPromptMock);
  });

  it('renders the sign-in component for unauthenticated users', async () => {
    getSessionMock.mockResolvedValue(null);

    const result = await MspSignInPage({ searchParams: Promise.resolve({}) });

    expect(redirectMock).not.toHaveBeenCalled();
    expect((result as any)?.type).toBe(MspSignInMock);
  });

  it('T001: passes the remembered email into the shared sign-in component when the durable cookie is present', async () => {
    cookiesMock.mockResolvedValue({
      get: vi.fn((name: string) =>
        name === 'msp_remembered_email' ? { value: ' remembered@example.com ' } : undefined
      ),
    });
    getSessionMock.mockResolvedValue(null);

    const result = await MspSignInPage({ searchParams: Promise.resolve({}) });

    expect((result as any)?.type).toBe(MspSignInMock);
    expect((result as any)?.props).toMatchObject({
      initialEmail: 'remembered@example.com',
    });
  });

  it('T002: passes no initial email when the durable cookie is absent', async () => {
    getSessionMock.mockResolvedValue(null);

    const result = await MspSignInPage({ searchParams: Promise.resolve({}) });

    expect((result as any)?.type).toBe(MspSignInMock);
    expect((result as any)?.props.initialEmail).toBeUndefined();
  });
});
