import { isAxiosError } from 'axios';
import { extractApiErrorMessage } from '@/shared/utils/apiErrors';

export const DEFAULT_INVITE_EMAIL_DOMAIN = 'mountainview-eg.com';

export type InviteFieldErrors = {
  email?: string;
  company?: string;
  department?: string;
  transferAck?: string;
};

export type InviteValidationMessages = {
  emailRequired: string;
  emailInvalid: string;
  emailDomain: string;
  companyRequired: string;
  departmentRequired: string;
  transferAckRequired: string;
};

export function normalizeInviteEmail(email: string): string {
  return email.trim().toLowerCase();
}

export function isValidEmailFormat(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

export function emailMatchesAllowedDomain(email: string, domain: string): boolean {
  const normalizedDomain = domain.trim().toLowerCase().replace(/^@/, '');
  return email.toLowerCase().endsWith(`@${normalizedDomain}`);
}

export function resolveInviteEmailDomain(
  companyDomain?: string | null,
  fallback = DEFAULT_INVITE_EMAIL_DOMAIN,
): string {
  const trimmed = companyDomain?.trim();
  return trimmed ? trimmed : fallback;
}

export function validateInviteForm(input: {
  email: string;
  companyId?: string;
  departmentId?: string;
  requireCompany?: boolean;
  requireDepartment?: boolean;
  requiresTransferAck?: boolean;
  transferAcknowledged?: boolean;
  allowedDomain: string;
  messages: InviteValidationMessages;
}): { valid: boolean; errors: InviteFieldErrors; normalizedEmail: string } {
  const errors: InviteFieldErrors = {};
  const normalizedEmail = normalizeInviteEmail(input.email);

  if (!normalizedEmail) {
    errors.email = input.messages.emailRequired;
  } else if (!isValidEmailFormat(normalizedEmail)) {
    errors.email = input.messages.emailInvalid;
  } else if (!emailMatchesAllowedDomain(normalizedEmail, input.allowedDomain)) {
    errors.email = input.messages.emailDomain;
  }

  if (input.requireCompany && !input.companyId) {
    errors.company = input.messages.companyRequired;
  }

  if (input.requireDepartment && !input.departmentId) {
    errors.department = input.messages.departmentRequired;
  }

  if (input.requiresTransferAck && !input.transferAcknowledged) {
    errors.transferAck = input.messages.transferAckRequired;
  }

  return {
    valid: Object.keys(errors).length === 0,
    errors,
    normalizedEmail,
  };
}

const DUPLICATE_USER_PATTERNS = [/already exists/i];
const INVALID_DOMAIN_PATTERNS = [/corporate email/i, /allowed for invites/i];

export function resolveInviteErrorMessage(
  error: unknown,
  messages: {
    forbidden: string;
    userExists: string;
    invalidDomain: string;
    sendFailed: string;
  },
): { message: string; field?: keyof InviteFieldErrors } {
  if (isAxiosError(error) && error.response) {
    const status = error.response.status;
    const apiMessage = extractApiErrorMessage(error.response.data);

    if (status === 403) {
      return { message: messages.forbidden };
    }

    if (apiMessage) {
      if (DUPLICATE_USER_PATTERNS.some((pattern) => pattern.test(apiMessage))) {
        return { message: messages.userExists, field: 'email' };
      }
      if (INVALID_DOMAIN_PATTERNS.some((pattern) => pattern.test(apiMessage))) {
        return { message: messages.invalidDomain, field: 'email' };
      }
      return { message: apiMessage };
    }
  }

  return { message: messages.sendFailed };
}
