import { dataSource } from "../../../data-source";
import { calendar } from "../../../entity/club/calendar";
import { calendarType } from "../../../entity/settings/calendarType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import InternalException from "../../../exceptions/internalException";
import { CreateCalendarCommand, DeleteCalendarCommand, UpdateCalendarCommand } from "./calendarCommand";

export default abstract class CalendarCommandHandler {
  /**
   * @description create calendar
   * @param {CreateCalendarCommand} createCalendar
   * @returns {Promise<number>}
   */
  static async create(createCalendar: CreateCalendarCommand): Promise<number> {
    return await dataSource
      .createQueryBuilder()
      .insert()
      .into(calendar)
      .values({
        starttime: createCalendar.starttime,
        endtime: createCalendar.endtime,
        title: createCalendar.title,
        content: createCalendar.content,
        location: createCalendar.location,
        allDay: createCalendar.allDay,
        type: await dataSource
          .getRepository(calendarType)
          .createQueryBuilder("type")
          .where("id = :id", { id: createCalendar.typeId })
          .getOneOrFail(),
      })
      .execute()
      .then((result) => {
        return result.identifiers[0].id;
      })
      .catch((err) => {
        throw new DatabaseActionException("CREATE", "calendar", err);
      });
  }

  /**
   * @description update calendar
   * @param {UpdateCalendarCommand} updateCalendar
   * @returns {Promise<void>}
   */
  static async update(updateCalendar: UpdateCalendarCommand): Promise<void> {
    let sequence = await dataSource
      .getRepository(calendar)
      .createQueryBuilder("calendar")
      .where("id = :id", { id: updateCalendar.id })
      .getOneOrFail()
      .then((res) => {
        return res.sequence;
      });
    return await dataSource
      .createQueryBuilder()
      .update(calendar)
      .set({
        starttime: updateCalendar.starttime,
        endtime: updateCalendar.endtime,
        title: updateCalendar.title,
        content: updateCalendar.content,
        location: updateCalendar.location,
        allDay: updateCalendar.allDay,
        type: await dataSource
          .getRepository(calendarType)
          .createQueryBuilder("type")
          .where("id = :id", { id: updateCalendar.typeId })
          .getOneOrFail(),
        sequence: sequence + 1,
      })
      .where("id = :id", { id: updateCalendar.id })
      .execute()
      .then(() => {})
      .catch((err) => {
        throw new DatabaseActionException("UPDATE", "calendar", err);
      });
  }

  /**
   * @description delete calendar
   * @param {DeleteCalendarCommand} deleteCalendar
   * @returns {Promise<void>}
   */
  static async delete(deleteCalendar: DeleteCalendarCommand): Promise<void> {
    return await dataSource
      .createQueryBuilder()
      .delete()
      .from(calendar)
      .where("id = :id", { id: deleteCalendar.id })
      .execute()
      .then(() => {})
      .catch((err) => {
        throw new DatabaseActionException("DELETE", "calendar", err);
      });
  }
}