import { AxiosError, AxiosHeaders } from 'axios';
import { describe, expect, it } from 'vitest';
import {
  emailMatchesAllowedDomain,
  isValidEmailFormat,
  normalizeInviteEmail,
  resolveInviteErrorMessage,
  validateInviteForm,
} from '@/features/admin/utils/inviteFormValidation';

const messages = {
  emailRequired: 'Enter an email address.',
  emailInvalid: 'Enter a valid email address.',
  emailDomain: 'Invitations must use a @mountainview-eg.com email address.',
  companyRequired: 'Select a company.',
  departmentRequired: 'Select a department.',
  transferAckRequired: 'Confirm department ownership transfer before sending.',
};

describe('inviteFormValidation', () => {
  it('normalizes invite email', () => {
    expect(normalizeInviteEmail('  Agent@MountainView-EG.com ')).toBe('agent@mountainview-eg.com');
  });

  it('rejects empty and invalid email formats', () => {
    expect(
      validateInviteForm({
        email: '',
        allowedDomain: 'mountainview-eg.com',
        messages,
      }).errors.email,
    ).toBe(messages.emailRequired);

    expect(
      validateInviteForm({
        email: 'not-an-email',
        allowedDomain: 'mountainview-eg.com',
        messages,
      }).errors.email,
    ).toBe(messages.emailInvalid);
  });

  it('rejects emails outside the allowed domain', () => {
    expect(
      validateInviteForm({
        email: 'user@gmail.com',
        allowedDomain: 'mountainview-eg.com',
        messages,
      }).errors.email,
    ).toBe(messages.emailDomain);
    expect(emailMatchesAllowedDomain('user@mountainview-eg.com', 'mountainview-eg.com')).toBe(true);
    expect(isValidEmailFormat('user@mountainview-eg.com')).toBe(true);
  });

  it('requires company, department, and transfer acknowledgement when configured', () => {
    const result = validateInviteForm({
      email: 'user@mountainview-eg.com',
      requireCompany: true,
      requireDepartment: true,
      requiresTransferAck: true,
      transferAcknowledged: false,
      allowedDomain: 'mountainview-eg.com',
      messages,
    });

    expect(result.valid).toBe(false);
    expect(result.errors.company).toBe(messages.companyRequired);
    expect(result.errors.department).toBe(messages.departmentRequired);
    expect(result.errors.transferAck).toBe(messages.transferAckRequired);
  });

  it('maps duplicate-user API errors to the email field', () => {
    const error = new AxiosError(
      'Request failed',
      AxiosError.ERR_BAD_REQUEST,
      undefined,
      undefined,
      {
        status: 422,
        statusText: 'Unprocessable Entity',
        headers: {},
        config: { headers: new AxiosHeaders() },
        data: { message: 'A user with this email already exists.' },
      },
    );

    const resolved = resolveInviteErrorMessage(error, {
      forbidden: 'Forbidden',
      userExists: 'User exists',
      invalidDomain: 'Invalid domain',
      sendFailed: 'Send failed',
    });

    expect(resolved.field).toBe('email');
    expect(resolved.message).toBe('User exists');
  });
});
