import { APIClient } from "./ApiClient";

export type Balances = Record<number, number>;

export interface MovementUpdate {
  account_id: number;
  time: number;
  label: string;
  file_id?: number;
  amount: number;
  checked: boolean;
}

export interface Movement {
  id: number;
  account_id: number;
  time: number;
  label: string;
  file_id?: number;
  amount: number;
  checked: boolean;
  time_create: number;
  time_update: number;
}

export class MovementApi {
  /**
   * Get all accounts balances
   */
  static async GetAllBalances(): Promise<Balances> {
    return (
      await APIClient.exec({
        uri: `/accounts/balances`,
        method: "GET",
      })
    ).data;
  }

  /**
   * Create a new movement
   */
  static async Create(q: MovementUpdate): Promise<Movement> {
    return (
      await APIClient.exec({
        uri: `/movement`,
        method: "POST",
        jsonData: q,
      })
    ).data;
  }

  /**
   * Get all the movements of an account
   */
  static async GetAccountMovements(
    account_id: number,
    filters?: {
      amount_min?: number;
      amount_max?: number;
      time_min?: number;
      time_max?: number;
      label?: string;
      limit?: number;
    }
  ): Promise<Movement[]> {
    const filtersS = new URLSearchParams();
    if (filters) {
      if (filters.amount_min)
        filtersS.append("amount_min", filters.amount_min.toString());
      if (filters.amount_max)
        filtersS.append("amount_max", filters.amount_max.toString());
      if (filters.time_min)
        filtersS.append("time_min", filters.time_min.toString());
      if (filters.time_max)
        filtersS.append("time_max", filters.time_max.toString());
      if (filters.label) filtersS.append("label", filters.label);
      if (filters.limit) filtersS.append("limit", filters.limit.toString());
    }

    return (
      await APIClient.exec({
        uri: `/account/${account_id}/movements?${filtersS}`,
        method: "GET",
      })
    ).data;
  }

  /**
   * Get a single movement information
   */ static async GetSingleMovement(movement_id: number): Promise<Movement> {
    return (
      await APIClient.exec({
        uri: `/movement/${movement_id}`,
        method: "GET",
      })
    ).data;
  }

  /**
   * Update a movement information
   */
  static async Update(
    movement: MovementUpdate & { id: number }
  ): Promise<Movement> {
    return (
      await APIClient.exec({
        uri: `/movement/${movement.id}`,
        method: "PUT",
        jsonData: movement,
      })
    ).data;
  }

  /**
   * Delete a movement
   */
  static async Delete(movement: Movement): Promise<void> {
    await APIClient.exec({
      uri: `/movement/${movement.id}`,
      method: "DELETE",
    });
  }
}
