import { APIClient } from "./ApiClient";

export interface NumberConstraint {
  min: number;
  max: number;
}

export interface LenConstraint {
  min: number;
  max: number;
}

interface Constraints {
  date_year: NumberConstraint;
  date_month: NumberConstraint;
  date_day: NumberConstraint;
  photo_allowed_types: string[];
  photo_max_size: number;
  mail_len: LenConstraint;
  user_name_len: LenConstraint;
  password_len: LenConstraint;
  family_name_len: LenConstraint;
  invitation_code_len: LenConstraint;
  member_first_name: LenConstraint;
  member_last_name: LenConstraint;
  member_birth_last_name: LenConstraint;
  member_email: LenConstraint;
  member_phone: LenConstraint;
  member_address: LenConstraint;
  member_city: LenConstraint;
  member_postal_code: LenConstraint;
  member_country: LenConstraint;
  member_sex: LenConstraint;
  member_note: LenConstraint;
  accommodation_name_len: LenConstraint;
  accommodation_description_len: LenConstraint;
  accommodation_calendar_name_len: LenConstraint;
}

interface OIDCProvider {
  id: string;
  name: string;
}

export interface Country {
  code: string;
  en: string;
  fr: string;
}

export interface CouplesStates {
  code: string;
  en: string;
  fr: string;
}

export interface ServerConfig {
  constraints: Constraints;
  mail: string;
  oidc_providers: OIDCProvider[];
  countries: Country[];
  couples_states: CouplesStates[];
}

let config: ServerConfig | null = null;

export class ServerApi {
  /**
   * Get server configuration
   */
  static async LoadConfig(): Promise<void> {
    config = (
      await APIClient.exec({
        uri: "/server/config",
        method: "GET",
      })
    ).data;
  }

  /**
   * Get cached configuration
   */
  static get Config(): ServerConfig {
    if (config === null) throw new Error("Missing configuration!");
    return config;
  }

  /**
   * Check password against policy
   *
   * @returns The detected error (if any) or null if the password
   * is valid
   */
  static CheckPassword(pwd: string): string | null {
    const constraint = this.Config.constraints.password_len;
    if (pwd.length < constraint.min || pwd.length > constraint.max)
      return `Le mot de passe doit comporter entre ${constraint.min} et ${constraint.max} caractères`;

    return null;
  }
}
