import { dataSource } from "../data-source";
import { award } from "../entity/award";
import { member } from "../entity/member";
import { memberAwards } from "../entity/memberAwards";
import InternalException from "../exceptions/internalException";
import { CreateMemberAwardCommand, DeleteMemberAwardCommand, UpdateMemberAwardCommand } from "./memberAwardCommand";

export default abstract class MemberAwardCommandHandler {
  /**
   * @description create memberAward
   * @param CreateMemberAwardCommand
   * @returns {Promise<number>}
   */
  static async create(createMemberAward: CreateMemberAwardCommand): Promise<number> {
    return await dataSource
      .createQueryBuilder()
      .insert()
      .into(memberAwards)
      .values({
        given: createMemberAward.given,
        note: createMemberAward.note,
        date: createMemberAward.date,
        member: await dataSource
          .getRepository(member)
          .createQueryBuilder("member")
          .where("id = :id", { id: createMemberAward.memberId })
          .getOneOrFail(),
        award: await dataSource
          .getRepository(award)
          .createQueryBuilder("award")
          .where("id = :id", { id: createMemberAward.awardId })
          .getOneOrFail(),
      })
      .execute()
      .then((result) => {
        return result.identifiers[0].id;
      })
      .catch((err) => {
        throw new InternalException("Failed creating memberAward", err);
      });
  }

  /**
   * @description update memberAward
   * @param UpdateMemberAwardCommand
   * @returns {Promise<void>}
   */
  static async update(updateMemberAward: UpdateMemberAwardCommand): Promise<void> {
    return await dataSource
      .createQueryBuilder()
      .update(memberAwards)
      .set({
        given: updateMemberAward.given,
        note: updateMemberAward.note,
        date: updateMemberAward.date,
        award: await dataSource
          .getRepository(award)
          .createQueryBuilder("award")
          .where("id = :id", { id: updateMemberAward.awardId })
          .getOneOrFail(),
      })
      .where("id = :id", { id: updateMemberAward.id })
      .andWhere("memberId = :memberId", { memberId: updateMemberAward.memberId })
      .execute()
      .then(() => {})
      .catch((err) => {
        throw new InternalException("Failed updating memberAward", err);
      });
  }

  /**
   * @description delete memberAward
   * @param DeleteMemberAwardCommand
   * @returns {Promise<void>}
   */
  static async delete(deletMemberAward: DeleteMemberAwardCommand): Promise<void> {
    return await dataSource
      .createQueryBuilder()
      .delete()
      .from(memberAwards)
      .where("id = :id", { id: deletMemberAward.id })
      .andWhere("memberId = :memberId", { memberId: deletMemberAward.memberId })
      .execute()
      .then(() => {})
      .catch((err) => {
        throw new InternalException("Failed deleting memberAward", err);
      });
  }
}