import { dataSource } from "../data-source";
import { member } from "../entity/member";
import { membership } from "../entity/membership";
import InternalException from "../exceptions/internalException";

export default abstract class MemberService {
  /**
   * @description get all members
   * @returns {Promise<[Array<member>, number]>}
   */
  static async getAll(offset: number = 0, count: number = 25): Promise<[Array<member>, number]> {
    return await dataSource
      .getRepository(member)
      .createQueryBuilder("member")
      .leftJoinAndMapOne(
        "member.firstMembershipEntry",
        "member.memberships",
        "membership_first",
        "membership_first.memberId = member.id AND membership_first.start = (SELECT MIN(m.start) FROM membership m WHERE m.memberId = member.id)"
      )
      .leftJoinAndMapOne(
        "member.lastMembershipEntry",
        "member.memberships",
        "membership_last",
        "membership_last.memberId = member.id AND membership_last.start = (SELECT MAX(m.start) FROM membership m WHERE m.memberId = member.id)"
      )
      .offset(offset)
      .limit(count)
      .getManyAndCount()
      .then((res) => {
        return res;
      })
      .catch((err) => {
        throw new InternalException("members not found", err);
      });
  }

  /**
   * @description get member by id
   * @param {number} id
   * @returns {Promise<Array<member>>}
   */
  static async getById(id: number): Promise<member> {
    return await dataSource
      .getRepository(member)
      .createQueryBuilder("member")
      .leftJoinAndMapOne(
        "member.firstMembershipEntry",
        "member.memberships",
        "membership_first",
        "membership_first.memberId = member.id AND membership_first.start = (SELECT MIN(m.start) FROM membership m WHERE m.memberId = member.id)"
      )
      .leftJoinAndMapOne(
        "member.lastMembershipEntry",
        "member.memberships",
        "membership_last",
        "membership_last.memberId = member.id AND membership_last.start = (SELECT MAX(m.start) FROM membership m WHERE m.memberId = member.id)"
      )
      .where("member.id = :id", { id: id })
      .getOneOrFail()
      .then((res) => {
        return res;
      })
      .catch((err) => {
        throw new InternalException("member not found by id", err);
      });
  }
}