import { AppDataSource } from "../database/data-source";
import { CommandRecive } from "../entities/CommandRecive";
import { Command } from "../entities/Command";
import { OrgRoot } from "../entities/OrgRoot";
import { Profile } from "../entities/Profile";

export interface PosNumCodeSitResult {
  posNumCodeSit: string;
  posNumCodeSitAbb: string;
  commandTypeName: string;
  commandNo: string;
  commandYear: number;
  commandExcecuteDate: Date;
}

/**
 * เรียงลำดับผู้ได้รับคำสั่งใหม่หลังจากลบรายการ และอัพเดทสถานะคำสั่งถ้าไม่มีผู้ได้รับคำสั่งเหลือ
 * @param reciveId commandRecive.Id ของผู้ได้รับคำสั่ง
 * @param code ประเภทคำสั่ง
 * @returns Promise<void>
 */
export async function reOrderCommandRecivesAndDelete(
  reciveId: string
): Promise<void> {
  const commandReciveRepo = AppDataSource.getRepository(CommandRecive);
  const commandRepo = AppDataSource.getRepository(Command);

  // ค้นหาข้อมูลผู้ได้รับคำสั่งตาม reciveId
  const commandRecive = await commandReciveRepo.findOne({
    where: { id: reciveId }
  });

  if (commandRecive == null)
    return;

  const commandId = commandRecive.commandId;
  // ลบตาม refId
  await commandReciveRepo.delete(commandRecive.id);
  
  const commandReciveList = await commandReciveRepo.find({
    where: { commandId: commandId },
    order: { order: "ASC" },
  });
  // ลำดับผู้ได้รับคำสั่งใหม่
  if (commandReciveList.length > 0) {
    await Promise.all(
      commandReciveList.map(async (p, i) => {
        p.order = i + 1;
        await commandReciveRepo.save(p);
      })
    );
  } else {
    // ถ้าไม่มีผู้ได้รับคำสั่งเหลือเลย ให้ยกเลิกคำสั่ง
    await commandRepo.update({ id: commandId }, { status: "CANCEL" });
  }

}

/**
 * ดึงข้อมูล posNumCodeSit และ posNumCodeSitAbb จาก commandId
 * @param commandId ID ของคำสั่ง
 * @param status สถานะของคำสั่ง (ไม่บังคับส่ง)
 * @returns Promise<PosNumCodeSitResult> ข้อมูลชื่อหน่วยงานและชื่อย่อ
 */
export async function getPosNumCodeSit(
  commandId: string,
  status?: string
): Promise<PosNumCodeSitResult> {
  const commandRepo = AppDataSource.getRepository(Command);
  const orgRootRepo = AppDataSource.getRepository(OrgRoot);
  const profileRepo = AppDataSource.getRepository(Profile);

  let posNumCodeSit:string = "";
  let posNumCodeSitAbb:string = "";
  let commandTypeName:string = "";
  let commandNo:string = "";
  let commandYear:number = 0;
  let commandExcecuteDate:Date = new Date;


  let _command: Command | null;
  if (!status) {
    _command = await commandRepo.findOne({
      where: { id: commandId },
      relations: { commandType: true }
    });
  }
  else {
    _command = await commandRepo.findOne({
      where: { id: commandId, status: status },
      relations: { commandType: true }
    });
  }
  
  if (_command) {
    if (_command?.isBangkok?.toLocaleUpperCase() == "OFFICE") {
      const orgRootDeputy = await orgRootRepo.findOne({
        where: {
          isDeputy: true,
          orgRevision: {
            orgRevisionIsCurrent: true,
            orgRevisionIsDraft: false,
          },
        },
        relations: ["orgRevision"],
      });
      posNumCodeSit = orgRootDeputy ? orgRootDeputy?.orgRootName : "สำนักปลัดกรุงเทพมหานคร";
      posNumCodeSitAbb = orgRootDeputy ? orgRootDeputy?.orgRootShortName : "สนป.";
    } else if (_command?.isBangkok?.toLocaleUpperCase() == "BANGKOK") {
      posNumCodeSit = "กรุงเทพมหานคร";
      posNumCodeSitAbb = "กทม.";
    } else {
      let _profileAdmin = await profileRepo.findOne({
        where: {
          keycloak: _command?.createdUserId.toString(),
          current_holders: {
            orgRevision: {
              orgRevisionIsCurrent: true,
              orgRevisionIsDraft: false,
            },
          },
        },
        relations: ["current_holders", "current_holders.orgRevision", "current_holders.orgRoot"],
      });
      posNumCodeSit =
        _profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootName)?.orgRoot.orgRootName ??
        "";
      posNumCodeSitAbb =
        _profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootShortName)?.orgRoot
          .orgRootShortName ?? "";
    }
    commandTypeName = _command?.commandType?.name ?? "";
    commandNo = _command?.commandNo ?? "";
    commandYear = _command?.commandYear;
    commandExcecuteDate = _command?.commandExcecuteDate;
  }

  return {
    posNumCodeSit,
    posNumCodeSitAbb,
    commandTypeName,
    commandNo,
    commandYear,
    commandExcecuteDate,
  };
}
