import { AppDataSource } from "../database/data-source";
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster";
import { OrgRevision } from "../entities/OrgRevision";
import { PosMaster } from "../entities/PosMaster";
import { PosMasterEmployeeHistory } from "../entities/PosMasterEmployeeHistory";
import { PosMasterEmployeeTempHistory } from "../entities/PosMasterEmployeeTempHistory";
import { PosMasterHistory } from "../entities/PosMasterHistory";
import { ProfileEducation } from "../entities/ProfileEducation";
import { RequestWithUser } from "../middlewares/user";

export async function CreatePosMasterHistoryOfficer(
  posMasterId: string,
  request: RequestWithUser | null,
  type?: string | null,
): Promise<boolean> {
  try {
    await AppDataSource.transaction(async (manager) => {
      const repoPosmaster = manager.getRepository(PosMaster);
      const repoHistory = manager.getRepository(PosMasterHistory);
      const repoOrgRevision = manager.getRepository(OrgRevision);

      const pm = await repoPosmaster.findOne({
        where: { id: posMasterId },
        relations: [
          "positions",
          "positions.posLevel",
          "positions.posType",
          "positions.posExecutive",
          "orgRoot",
          "orgChild1",
          "orgChild2",
          "orgChild3",
          "orgChild4",
          "current_holder",
          "next_holder",
        ],
      });

      if (!pm) return false;
      if (!pm.ancestorDNA) return false;

      const checkCurrentRevision = await repoOrgRevision.findOne({
        where: {
          id: pm.orgRevisionId,
          orgRevisionIsCurrent: true,
          orgRevisionIsDraft: false
        }
      })
      const _null: any = null;
      const h = new PosMasterHistory();
      const selectedPosition =
        pm.positions.length > 0
          ? pm.positions.find((p) => p.positionIsSelected === true) ?? null
          : null;
      h.ancestorDNA = pm.ancestorDNA ? pm.ancestorDNA : _null;
      if (!type || type != "DELETE") {
        if (checkCurrentRevision) {
          h.prefix = pm.current_holder?.prefix || _null;
          h.firstName = pm.current_holder?.firstName || _null;
          h.lastName = pm.current_holder?.lastName || _null;
          h.profileId = pm.current_holder?.id || _null;
          h.rootDnaId = pm.orgRoot?.ancestorDNA || _null;
          h.child1DnaId = pm.orgChild1?.ancestorDNA || _null;
          h.child2DnaId = pm.orgChild2?.ancestorDNA || _null;
          h.child3DnaId = pm.orgChild3?.ancestorDNA || _null;
          h.child4DnaId = pm.orgChild4?.ancestorDNA || _null;
        } else {
          h.prefix = pm.next_holder?.prefix || _null;
          h.firstName = pm.next_holder?.firstName || _null;
          h.lastName = pm.next_holder?.lastName || _null;
        }
        h.position = selectedPosition?.positionName ?? _null;
        h.posType = selectedPosition?.posType?.posTypeName ?? _null;
        h.posLevel = selectedPosition?.posLevel?.posLevelName ?? _null;
      }
      h.posMasterNoPrefix = pm.posMasterNoPrefix ?? _null;
      h.posMasterNo = pm.posMasterNo ?? _null;
      h.posMasterNoSuffix = pm.posMasterNoSuffix ?? _null;
      h.posExecutive = selectedPosition?.posExecutive?.posExecutiveName ?? _null;
      h.shortName =
        [
          pm.orgChild4?.orgChild4ShortName,
          pm.orgChild3?.orgChild3ShortName,
          pm.orgChild2?.orgChild2ShortName,
          pm.orgChild1?.orgChild1ShortName,
          pm.orgRoot?.orgRootShortName,
        ].find((s) => typeof s === "string" && s.trim().length > 0) ?? _null;
      const userId = request?.user?.sub ?? "";
      const userName = request?.user?.name ?? "system";
      h.createdUserId = userId;
      h.createdFullName = userName;
      h.lastUpdateUserId = userId;
      h.lastUpdateFullName = userName;
      h.createdAt = new Date();
      h.lastUpdatedAt = new Date();
      await repoHistory.save(h);
    });

    return true;
  } catch (err) {
    console.error("CreatePosMasterHistoryOfficer transaction error:", err);
    return false;
  }
}

export async function CreatePosMasterHistoryEmployee(
  posMasterId: string,
  request: RequestWithUser | null,
): Promise<boolean> {
  try {
    await AppDataSource.transaction(async (manager) => {
      const repoPosmaster = manager.getRepository(EmployeePosMaster);
      const repoHistory = manager.getRepository(PosMasterEmployeeHistory);

      const pm = await repoPosmaster.findOne({
        where: { id: posMasterId },
        relations: [
          "positions",
          "positions.posLevel",
          "positions.posType",
          "positions.posExecutive",
          "orgRoot",
          "orgChild1",
          "orgChild2",
          "orgChild3",
          "orgChild4",
          "current_holder",
        ],
      });

      if (!pm) return false;
      if (!pm.ancestorDNA) return false;
      const _null: any = null;
      const h = new PosMasterEmployeeHistory();
      const selectedPosition =
        pm.positions.length > 0
          ? pm.positions.find((p) => p.positionIsSelected === true) ?? null
          : null;
      h.ancestorDNA = pm.ancestorDNA;
      h.prefix = pm.current_holder?.prefix || _null;
      h.firstName = pm.current_holder?.firstName || _null;
      h.lastName = pm.current_holder?.lastName || _null;
      h.posMasterNoPrefix = pm.posMasterNoPrefix ?? _null;
      h.posMasterNo = pm.posMasterNo ?? _null;
      h.posMasterNoSuffix = pm.posMasterNoSuffix ?? _null;
      h.position = selectedPosition?.positionName ?? _null;
      h.posType = selectedPosition?.posType?.posTypeName ?? _null;
      h.posLevel = selectedPosition?.posLevel?.posLevelName ?? _null;
      h.shortName =
        [
          pm.orgChild4?.orgChild4ShortName,
          pm.orgChild3?.orgChild3ShortName,
          pm.orgChild2?.orgChild2ShortName,
          pm.orgChild1?.orgChild1ShortName,
          pm.orgRoot?.orgRootShortName,
        ].find((s) => typeof s === "string" && s.trim().length > 0) ?? _null;
      const userId = request?.user?.sub ?? "";
      const userName = request?.user?.name ?? "system";
      h.createdUserId = userId;
      h.createdFullName = userName;
      h.lastUpdateUserId = userId;
      h.lastUpdateFullName = userName;
      h.createdAt = new Date();
      h.lastUpdatedAt = new Date();
      await repoHistory.save(h);
    });

    return true;
  } catch (err) {
    console.error("CreatePosMasterHistoryEmployee transaction error:", err);
    return false;
  }
}

export async function CreatePosMasterHistoryEmployeeTemp(
  posMasterId: string,
  request: RequestWithUser | null,
): Promise<boolean> {
  try {
    await AppDataSource.transaction(async (manager) => {
      const repoPosmaster = manager.getRepository(EmployeeTempPosMaster);
      const repoHistory = manager.getRepository(PosMasterEmployeeTempHistory);

      const pm = await repoPosmaster.findOne({
        where: { id: posMasterId },
        relations: [
          "positions",
          "positions.posLevel",
          "positions.posType",
          "positions.posExecutive",
          "orgRoot",
          "orgChild1",
          "orgChild2",
          "orgChild3",
          "orgChild4",
          "current_holder",
        ],
      });

      if (!pm) return false;
      if (!pm.ancestorDNA) return false;
      const _null: any = null;
      const h = new PosMasterEmployeeTempHistory();
      const selectedPosition =
        pm.positions.length > 0
          ? pm.positions.find((p) => p.positionIsSelected === true) ?? null
          : null;
      h.ancestorDNA = pm.ancestorDNA;
      h.prefix = pm.current_holder?.prefix || _null;
      h.firstName = pm.current_holder?.firstName || _null;
      h.lastName = pm.current_holder?.lastName || _null;
      h.posMasterNoPrefix = pm.posMasterNoPrefix ?? _null;
      h.posMasterNo = pm.posMasterNo ?? _null;
      h.posMasterNoSuffix = pm.posMasterNoSuffix ?? _null;
      h.position = selectedPosition?.positionName ?? _null;
      h.posType = selectedPosition?.posType?.posTypeName ?? _null;
      h.posLevel = selectedPosition?.posLevel?.posLevelName ?? _null;
      h.shortName =
        [
          pm.orgChild4?.orgChild4ShortName,
          pm.orgChild3?.orgChild3ShortName,
          pm.orgChild2?.orgChild2ShortName,
          pm.orgChild1?.orgChild1ShortName,
          pm.orgRoot?.orgRootShortName,
        ].find((s) => typeof s === "string" && s.trim().length > 0) ?? _null;
      const userId = request?.user?.sub ?? "";
      const userName = request?.user?.name ?? "system";
      h.createdUserId = userId;
      h.createdFullName = userName;
      h.lastUpdateUserId = userId;
      h.lastUpdateFullName = userName;
      h.createdAt = new Date();
      h.lastUpdatedAt = new Date();
      await repoHistory.save(h);
    });

    return true;
  } catch (err) {
    console.error("CreatePosMasterHistoryEmployeeTemp transaction error:", err);
    return false;
  }
}

export async function getTopDegrees(educations: ProfileEducation[]): Promise<string> {
  // filter เฉพาะ isUse==true หรือ isEducation==true
  const filtered = educations.filter((e) => e.isUse === true || e.isEducation === true);
  // sort: isEducation==true ก่อน, ถ้าเท่ากัน sort ด้วย level น้อยสุด
  const sorted = filtered.sort((a, b) => {
    const aEdu = !!a.isEducation ? 0 : 1;
    const bEdu = !!b.isEducation ? 0 : 1;
    if (aEdu !== bEdu) return aEdu - bEdu;
    const aLevel = typeof a.level === "number" ? a.level : Number.MAX_SAFE_INTEGER;
    const bLevel = typeof b.level === "number" ? b.level : Number.MAX_SAFE_INTEGER;
    return aLevel - bLevel;
  });

  return sorted
    .map((e) => [e.degree, e.field].filter(Boolean).join(" "))
    .filter(Boolean)
    .join("\n");
}
