import { APIClient } from "./ApiClient";
import { Balances } from "./MovementsApi";
import { ServerApi } from "./ServerApi";

export interface Account {
  id: number;
  name: string;
  user_id: number;
  time_create: number;
  time_update: number;
  type: string;
  default_account: boolean;
  balance: number;
}

export class AccountsList {
  list: Account[];

  constructor(list: Account[]) {
    this.list = list;
    this.list.sort((a, b) => a.id - b.id);
  }

  /**
   * Check if accounts list is empty
   */
  get isEmpty(): boolean {
    return this.list.length === 0;
  }

  /**
   * Get a single account by its id
   */
  get(id: number): Account | null {
    return this.list.find((a) => a.id === id) ?? null;
  }

  /**
   * Get default account (if any) returning null if none found
   */
  get default(): Account | null {
    return this.list.find((a) => a.default_account) ?? null;
  }

  /**
   * Update all accounts balances
   */
  mapBalances(balances: Balances): AccountsList {
    return new AccountsList(
      this.list.map((a) => {
        a.balance = balances[a.id] ?? 0;
        return a;
      })
    );
  }
}

export class AccountApi {
  /**
   * Get the current list of accounts of the user
   */
  static async GetList(): Promise<AccountsList> {
    const array = (
      await APIClient.exec({
        uri: `/accounts?include_balances=true`,
        method: "GET",
      })
    ).data;

    return new AccountsList(array);
  }

  /**
   * Set default account
   */
  static async SetDefaultAccount(account: Account): Promise<void> {
    await APIClient.exec({
      uri: `/account/${account.id}/default`,
      method: "PUT",
    });
  }

  /**
   * Create a new account
   */
  static async Create(name: string): Promise<void> {
    await APIClient.exec({
      uri: `/account`,
      method: "POST",
      jsonData: {
        name,
        type: ServerApi.Config.accounts_types[0].code,
      },
    });
  }

  /**
   * Update account
   */
  static async Update(account: Account): Promise<void> {
    await APIClient.exec({
      uri: `/account/${account.id}`,
      method: "PUT",
      jsonData: {
        name: account.name,
        type: account.type,
      },
    });
  }

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