import { APIClient } from "../ApiClient";
import { Family } from "../FamilyApi";

export interface Accommodation {
  id: number;
  family_id: number;
  time_create: number;
  time_update: number;
  name: string;
  need_validation: boolean;
  description?: string;
  color?: string;
  open_to_reservations: boolean;
}

export class AccommodationsList {
  private list: Accommodation[];
  private map: Map<number, Accommodation>;

  constructor(list: Accommodation[]) {
    this.list = list;
    this.map = new Map();

    for (const m of list) {
      this.map.set(m.id, m);
    }

    this.list.sort((a, b) =>
      a.name.toLowerCase().localeCompare(b.name.toLocaleLowerCase())
    );
  }

  public get isEmpty(): boolean {
    return this.list.length === 0;
  }

  public get size(): number {
    return this.list.length;
  }

  public get fullList(): Accommodation[] {
    return this.list;
  }

  filter(predicate: (m: Accommodation) => boolean): Accommodation[] {
    return this.list.filter(predicate);
  }

  get openToReservationList(): Accommodation[] {
    return this.filter((a) => a.open_to_reservations);
  }

  get(id: number): Accommodation | undefined {
    return this.map.get(id);
  }
}

export interface UpdateAccommodation {
  name: string;
  need_validation: boolean;
  description?: string;
  color?: string;
  open_to_reservations: boolean;
}

export class AccommodationListApi {
  /**
   * Get the list of accommodation of a family
   */
  static async GetListOfFamily(family: Family): Promise<AccommodationsList> {
    const data = (
      await APIClient.exec({
        method: "GET",
        uri: `/family/${family.family_id}/accommodations/list/list`,
      })
    ).data;

    return new AccommodationsList(data);
  }

  /**
   * Create a new accommodation
   */
  static async Create(
    family: Family,
    accommodation: UpdateAccommodation
  ): Promise<Accommodation> {
    return (
      await APIClient.exec({
        method: "POST",
        uri: `/family/${family.family_id}/accommodations/list/create`,
        jsonData: accommodation,
      })
    ).data;
  }

  /**
   * Update an accommodation
   */
  static async Update(
    accommodation: Accommodation,
    update: UpdateAccommodation
  ): Promise<Accommodation> {
    return (
      await APIClient.exec({
        method: "PUT",
        uri: `/family/${accommodation.family_id}/accommodations/list/${accommodation.id}`,
        jsonData: update,
      })
    ).data;
  }

  /**
   * Delete an accommodation
   */
  static async Delete(accommodation: Accommodation): Promise<Accommodation> {
    return (
      await APIClient.exec({
        method: "DELETE",
        uri: `/family/${accommodation.family_id}/accommodations/list/${accommodation.id}`,
      })
    ).data;
  }
}
