import { Body, Controller, Get, Path, Post, Put, Request, Route, Security, Tags } from "tsoa";
import { AppDataSource } from "../database/data-source";
import { RequestWithUser } from "../middlewares/user";
import HttpError from "../interfaces/http-error";
import HttpStatus from "../interfaces/http-status";
import HttpSuccess from "../interfaces/http-success";
import { Workflow } from "../entities/Workflow";
import { State } from "../entities/State";
import { StateOperator } from "../entities/StateOperator";
import { StateOperatorUser } from "../entities/StateOperatorUser";
import CallAPI from "../interfaces/call-api";
import { Profile } from "../entities/Profile";
import { StateUserComment } from "../entities/StateUserComment";
import { MetaWorkflow } from "../entities/MetaWorkflow";
import { MetaState } from "../entities/MetaState";
import { MetaStateOperator } from "../entities/MetaStateOperator";
import { PosMaster } from "../entities/PosMaster";
import { Brackets, In, IsNull, Not } from "typeorm";
import { Assign } from "../entities/Assign";
import { PosMasterAct } from "../entities/PosMasterAct";
import { getAllJSDocTagsOfKind } from "typescript";
import { viewDirectorActing } from "../entities/view/viewDirectorActing";
import { viewDirector } from "../entities/view/viewDirector";

@Route("api/v1/org/workflow")
@Tags("Workflow")
@Security("bearerAuth")
export class WorkflowController extends Controller {
  private workflowRepo = AppDataSource.getRepository(Workflow);
  private stateRepo = AppDataSource.getRepository(State);
  private stateOperatorRepo = AppDataSource.getRepository(StateOperator);
  private stateOperatorUserRepo = AppDataSource.getRepository(StateOperatorUser);
  private stateUserCommentRepo = AppDataSource.getRepository(StateUserComment);
  private profileRepo = AppDataSource.getRepository(Profile);

  private metaWorkflowRepo = AppDataSource.getRepository(MetaWorkflow);
  private metaStateRepo = AppDataSource.getRepository(MetaState);
  private metaStateOperatorRepo = AppDataSource.getRepository(MetaStateOperator);
  private posMasterRepo = AppDataSource.getRepository(PosMaster);
  private posMasterActRepo = AppDataSource.getRepository(PosMasterAct);
  private assignRepo = AppDataSource.getRepository(Assign);

  @Post("add-workflow")
  public async checkWorkflow(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      sysName: string;
      posLevelName: string;
      posTypeName: string;
    },
  ) {
    const profile = await this.profileRepo.findOne({
      where: {
        keycloak: req.user.sub,
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");

    const metaWorkflow = await this.metaWorkflowRepo.findOne({
      where: {
        sysName: body.sysName,
        posLevelName: body.posLevelName,
        posTypeName: body.posTypeName,
      },
    });
    if (!metaWorkflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบกระบวนการนี้ได้");

    const meta = {
      createdUserId: req.user.sub,
      createdFullName: req.user.name,
      lastUpdateUserId: req.user.sub,
      lastUpdateFullName: req.user.name,
      createdAt: new Date(),
      lastUpdatedAt: new Date(),
    };
    const workflow = new Workflow();
    Object.assign(workflow, {
      ...metaWorkflow,
      id: undefined,
      ...meta,
      ...body,
      system: body.sysName,
    });
    await this.workflowRepo.save(workflow);
    const metaState = await this.metaStateRepo.find({
      where: {
        metaWorkflowId: metaWorkflow.id,
      },
      order: { order: "ASC" },
    });

    await Promise.all(
      metaState.map(async (item) => {
        const state = new State();
        Object.assign(state, { ...item, id: undefined, workflowId: workflow.id, ...meta });
        await this.stateRepo.save(state);
        if (state.order == 1) {
          workflow.stateId = state.id;
          await this.workflowRepo.save(workflow);
        }
        const metaStateOperator = await this.metaStateOperatorRepo.find({
          where: {
            metaStateId: item.id,
          },
        });
        await Promise.all(
          metaStateOperator.map(async (item1) => {
            const stateOperator = new StateOperator();
            Object.assign(stateOperator, { ...item1, id: undefined, stateId: state.id, ...meta });
            await this.stateOperatorRepo.save(stateOperator);
          }),
        );
      }),
    );

    const stateOperatorUser = new StateOperatorUser();
    Object.assign(stateOperatorUser, {
      profileId: profile.id,
      operator: "Owner",
      order: 1,
      workflowId: workflow.id,
      ...meta,
    });
    await this.stateOperatorUserRepo.save(stateOperatorUser);

    const profileOfficer = await this.posMasterRepo.find({
      where: {
        posMasterAssigns: { assignId: body.sysName },
        orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
      },
      relations: ["orgChild1"],
    });
    await Promise.all(
      profileOfficer.map(async (item, i) => {
        if (item.orgChild1 == null || item.orgChild1.isOfficer == false) {
          const stateOperatorUser = new StateOperatorUser();
          Object.assign(stateOperatorUser, {
            profileId: item.current_holderId,
            operator: "Officer",
            order: i + 2,
            workflowId: workflow.id,
            ...meta,
          });
          await this.stateOperatorUserRepo.save(stateOperatorUser);
        } else {
          const stateOperatorUser = new StateOperatorUser();
          Object.assign(stateOperatorUser, {
            profileId: item.current_holderId,
            operator: "PersonnelOfficer",
            order: i + 2,
            workflowId: workflow.id,
            ...meta,
          });
          await this.stateOperatorUserRepo.save(stateOperatorUser);
        }
      }),
    );

    const _workflow = await this.workflowRepo.findOne({
      where: { id: workflow.id },
      relations: ["stateOperatorUsers"],
    });
    if (!_workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");

    const _state = await this.stateRepo.findOne({
      where: {
        id: _workflow.stateId,
      },
      relations: ["stateOperators"],
    });
    if (!_state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    let profileNow = _workflow.stateOperatorUsers
      .filter((x) => _state.stateOperators.map((s) => s.operator).includes(x.operator))
      .map((x) => ({
        receiverUserId: x.profileId,
        notiLink: "",
      }));
    await new CallAPI()
      .PostData(req, "/placement/noti/profiles", {
        subject: `รายการถูกส่ง`,
        body: `รายการถูกส่ง`,
        receiverUserIds: profileNow,
        payload: "", //แนบไฟล์
        isSendMail: true,
        isSendInbox: true,
        isSendNotification: true,
      })
      .catch((error) => {
        console.error("Error calling API:", error);
      });

    return new HttpSuccess();
  }

  @Post("check-iscan")
  public async checkIsCan(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      workflowId: string;
      stateId: string;
      profileId: string;
      action: string;
    },
  ) {
    const stateOperatorUser = await this.stateOperatorUserRepo.findOne({
      where: {
        profileId: body.profileId,
        workflowId: body.workflowId,
      },
    });
    if (!stateOperatorUser)
      throw new HttpError(HttpStatus.NOT_FOUND, "ผู้ใช้งานนี้ไม่มีหน้าที่ในกระบวนการนี้");

    const operator = await this.stateOperatorRepo.findOne({
      where: {
        operator: stateOperatorUser.operator,
        state: { id: body.stateId, workflow: { id: body.workflowId } },
      },
    });
    if (!operator) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");

    let isCan = false;
    switch (body.action.trim().toLocaleUpperCase()) {
      case "VIEW":
        isCan = operator.canView;
      case "UPDATE":
        isCan = operator.canUpdate;
      case "DELETE":
        isCan = operator.canDelete;
      case "CANCEL":
        isCan = operator.canCancel;
      case "OPERATE":
        isCan = operator.canOperate;
      case "CHANGESTATE":
        isCan = operator.canChangeState;
      case "COMMENT":
        isCan = operator.canComment;
      case "SIGN":
        isCan = operator.canSign;
      default:
        isCan = false;
    }
    if (isCan == false) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการได้");
    } else {
      return new HttpSuccess();
    }
  }

  @Post("check-state-now")
  public async checkStateNow(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      system: string;
    },
  ) {
    const workflow = await this.workflowRepo.findOne({
      where: {
        refId: body.refId,
        sysName: body.system,
      },
      relations: ["stateOperatorUsers"],
    });
    if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");

    const state = await this.stateRepo.findOne({
      where: {
        id: workflow.stateId,
      },
      relations: ["stateOperators"],
    });
    if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    return new HttpSuccess({
      stateId: state.id,
      stateNo: state.order,
      stateName: state.name,
    });
  }

  @Post("check-user-now")
  public async checkUserNow(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      system: string;
    },
  ) {
    const stateOperatorUser = await this.stateOperatorUserRepo.findOne({
      where: {
        workflow: {
          refId: body.refId,
          sysName: body.system,
        },
        profile: {
          keycloak: req.user.sub,
        },
      },
      relations: ["workflow"],
    });
    const workflow = await this.workflowRepo.findOne({
      where: {
        refId: body.refId,
        sysName: body.system,
      },
    });
    if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");
    const operator = await this.stateOperatorRepo.findOne({
      where: {
        operator: stateOperatorUser?.operator || "",
        stateId: workflow.stateId,
      },
      relations: ["state"],
    });
    if (!operator) {
      const state = await this.stateRepo.findOne({
        where: {
          id: workflow.stateId,
        },
      });
      return new HttpSuccess({
        stateId: state?.id || null,
        stateNo: state?.order || null,
        stateName: state?.name || null,
        operator: stateOperatorUser?.operator || null,
        can_view: false,
        can_update: false,
        can_operate: false,
        can_change_state: false,
        can_delete: false,
        can_cancel: false,
        can_sign: false,
      });
    }
    return new HttpSuccess({
      stateId: operator.state.id,
      stateNo: operator.state.order,
      stateName: operator.state.name,
      operator: operator.operator,
      can_view: operator.canView,
      can_update: operator.canUpdate,
      can_operate: operator.canOperate,
      can_change_state: operator.canChangeState,
      can_delete: operator.canDelete,
      can_cancel: operator.canCancel,
      can_sign: operator.canSign,
    });
  }

  @Post("check-state-all")
  public async checkStateAll(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      system: string;
    },
  ) {
    const state = await this.stateRepo.find({
      where: {
        workflow: {
          refId: body.refId,
          sysName: body.system,
        },
      },
      order: { order: "ASC", stateUserComments: { order: "ASC" } },
      relations: ["stateUserComments", "stateUserComments.profile"],
    });
    const _state = state.map((x) => ({
      stateId: x.id,
      stateNo: x.order,
      stateName: x.name,
      stateUserComments: x.stateUserComments.map((x) => ({
        id: x.id,
        prefix: x.profile.prefix,
        firstName: x.profile.firstName,
        lastName: x.profile.lastName,
        isComment: x.profile.keycloak == req.user.sub ? true : false,
        profileId: x.profileId,
        isAcceptSetting: x.isAcceptSetting,
        isApproveSetting: x.isApproveSetting,
        isReasonSetting: x.isReasonSetting,
        isAccept: x.isAccept,
        isApprove: x.isApprove,
        reason: x.reason,
      })),
    }));
    return new HttpSuccess(_state);
  }

  @Post("state-next")
  public async stateNext(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      system: string;
    },
  ) {
    const stateOperatorUserNow = await this.stateOperatorUserRepo.findOne({
      where: {
        workflow: {
          refId: body.refId,
          sysName: body.system,
        },
        profile: {
          keycloak: req.user.sub,
        },
      },
    });
    const stateOperatorUser = await this.stateOperatorUserRepo.find({
      where: {
        workflow: {
          refId: body.refId,
          sysName: body.system,
        },
        profile: {
          keycloak: Not(req.user.sub),
        },
        operator: stateOperatorUserNow?.operator || "",
      },
    });
    await this.stateOperatorUserRepo.remove(stateOperatorUser);

    const workflow = await this.workflowRepo.findOne({
      where: {
        refId: body.refId,
        sysName: body.system,
      },
      relations: ["stateOperatorUsers"],
    });
    if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");

    const state = await this.stateRepo.findOne({
      where: {
        id: workflow.stateId,
      },
      relations: ["stateOperators"],
    });
    if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    const _state = await this.stateRepo.findOne({
      where: {
        order: state.order + 1,
        workflowId: state.workflowId,
      },
      relations: ["stateOperators"],
    });
    //noti
    let profileNow = workflow.stateOperatorUsers
      .filter((x) => state.stateOperators.map((s) => s.operator).includes(x.operator))
      .map((x) => ({
        receiverUserId: x.profileId,
        notiLink: "",
      }));
    await new CallAPI()
      .PostData(req, "/placement/noti/profiles", {
        subject: `รายการถูกส่ง`,
        body: `รายการถูกส่ง`,
        receiverUserIds: profileNow,
        payload: "", //แนบไฟล์
        isSendMail: true,
        isSendInbox: true,
        isSendNotification: true,
      })
      .catch((error) => {
        console.error("Error calling API:", error);
      });
    if (_state != null) {
      let profileNext = workflow.stateOperatorUsers
        .filter((x) => _state.stateOperators.map((s) => s.operator).includes(x.operator))
        .map((x) => ({
          receiverUserId: x.profileId,
          notiLink: "",
        }));
      await new CallAPI()
        .PostData(req, "/placement/noti/profiles", {
          subject: `ได้รับรายการ`,
          body: `ได้รับรายการ`,
          receiverUserIds: profileNext,
          payload: "", //แนบไฟล์
          isSendMail: true,
          isSendInbox: true,
          isSendNotification: true,
        })
        .catch((error) => {
          console.error("Error calling API:", error);
        });
      workflow.stateId = _state.id;
      await this.workflowRepo.save(workflow);
    }

    return new HttpSuccess({
      stateId: _state?.id || null,
      stateNo: _state?.order || null,
      stateName: _state?.name || null,
      stateType: _state?.type || null,
    });
  }

  @Post("state-back")
  public async stateBack(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      stateId: string;
    },
  ) {
    const state = await this.stateRepo.findOne({
      where: {
        id: body.stateId,
      },
    });
    if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    const _state = await this.stateRepo.findOne({
      where: {
        order: state.order - 1,
        workflowId: state.workflowId,
      },
    });

    return new HttpSuccess({
      stateId: _state?.id || null,
      stateNo: _state?.order || null,
      stateName: _state?.name || null,
      stateType: _state?.type || null,
    });
  }

  @Post("add-step")
  public async addStep(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      stateId: string;
      profileId: string;
      isAcceptSetting: boolean;
      isApproveSetting: boolean;
      isReasonSetting: boolean;
    },
  ) {
    const profile = await this.profileRepo.findOne({
      where: {
        id: body.profileId,
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบผู้ใช้งานนี้");
    const state = await this.stateRepo.findOne({
      where: {
        id: body.stateId,
      },
      relations: ["stateUserComments", "workflow"],
    });
    if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");

    const stateUserComment = new StateUserComment();
    stateUserComment.order = state.stateUserComments.length + 1;
    stateUserComment.stateId = body.stateId;
    stateUserComment.profileId = body.profileId;
    stateUserComment.isAcceptSetting = body.isAcceptSetting;
    stateUserComment.isApproveSetting = body.isApproveSetting;
    stateUserComment.isReasonSetting = body.isReasonSetting;
    stateUserComment.createdUserId = req.user.sub;
    stateUserComment.createdFullName = req.user.name;
    stateUserComment.createdAt = new Date();
    stateUserComment.lastUpdateUserId = req.user.sub;
    stateUserComment.lastUpdateFullName = req.user.name;
    stateUserComment.lastUpdatedAt = new Date();
    await this.stateUserCommentRepo.save(stateUserComment);
    state.workflow.sysName;
    const assign = await this.assignRepo.findOne({
      where: {
        id: state.workflow.sysName,
      },
    });
    if (!assign) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    await new CallAPI()
      .PostData(req, "/placement/noti/profiles", {
        subject: `ได้รับรายการ`,
        body: `ได้รับรายการ`,
        receiverUserIds: [
          {
            receiverUserId: body.profileId,
            notiLink: `${assign.path}/${state.workflow.refId}`,
          },
        ],
        payload: "", //แนบไฟล์
        isSendMail: true,
        isSendInbox: true,
        isSendNotification: true,
      })
      .catch((error) => {
        console.error("Error calling API:", error);
      });

    return new HttpSuccess();
  }

  @Post("comment")
  public async createcomment(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      stateUserCommentId: string;
      isAccept?: boolean | null;
      isApprove?: boolean | null;
      reason?: string | null;
    },
  ) {
    const stateUserComment = await this.stateUserCommentRepo.findOne({
      where: {
        id: body.stateUserCommentId,
      },
      relations: ["state", "state.workflow", "state.stateOperators"],
    });
    if (!stateUserComment)
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
    stateUserComment.state.stateOperators;

    const workflow = await this.workflowRepo.findOne({
      where: {
        refId: stateUserComment.state.workflow.refId,
        sysName: stateUserComment.state.workflow.sysName,
      },
      relations: ["stateOperatorUsers"],
    });
    if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");
    let profileNow = workflow.stateOperatorUsers
      .filter((x) =>
        stateUserComment.state.stateOperators.map((s) => s.operator).includes(x.operator),
      )
      .map((x) => ({
        receiverUserId: x.profileId,
        notiLink: "",
      }));
    await new CallAPI()
      .PostData(req, "/placement/noti/profiles", {
        subject: `ผู้บังคับบัญชาดำเนินการ`,
        body: `ผู้บังคับบัญชาดำเนินการ`,
        receiverUserIds: profileNow,
        payload: "", //แนบไฟล์
        isSendMail: true,
        isSendInbox: true,
        isSendNotification: true,
      })
      .catch((error) => {
        console.error("Error calling API:", error);
      });
    let _null: any = null;
    stateUserComment.isAccept = body.isAccept == null ? _null : body.isAccept;
    stateUserComment.isApprove = body.isApprove == null ? _null : body.isApprove;
    stateUserComment.reason = body.reason == null ? _null : body.reason;
    stateUserComment.lastUpdateUserId = req.user.sub;
    stateUserComment.lastUpdateFullName = req.user.name;
    stateUserComment.lastUpdatedAt = new Date();
    await this.stateUserCommentRepo.save(stateUserComment);

    return new HttpSuccess();
  }

  @Post("comment-state")
  public async getCommentState(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      stateId: string;
    },
  ) {
    const state = await this.stateRepo.findOne({
      where: {
        id: body.stateId,
      },
      order: { stateUserComments: { order: "ASC" } },
      relations: ["stateUserComments"],
    });
    if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");

    return new HttpSuccess(state.stateUserComments);
  }

  @Post("comment-state-user")
  public async getCommentStateUser(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      stateId: string;
    },
  ) {
    const stateUserComment = await this.stateUserCommentRepo.findOne({
      where: {
        profile: {
          keycloak: req.user.sub,
        },
        stateId: body.stateId,
      },
    });

    return new HttpSuccess({
      id: stateUserComment?.id || null,
      isAccept: stateUserComment?.isAccept || null,
      isApprove: stateUserComment?.isApprove || null,
      reason: stateUserComment?.reason || null,
      isAcceptSetting: stateUserComment?.isAcceptSetting || null,
      isApproveSetting: stateUserComment?.isApproveSetting || null,
      isReasonSetting: stateUserComment?.isReasonSetting || null,
      order: stateUserComment?.order || null,
      stateId: stateUserComment?.stateId || null,
      profileId: stateUserComment?.profileId || null,
    });
  }

  /**
   *
   *
   */
  @Put("commander/{type}")
  async getProfilePlacement(
    @Request() request: RequestWithUser,
    @Path() type: string,
    @Body()
    body: {
      isAct: boolean;
      keyword: string;
      page: number;
      pageSize: number;
    },
  ) {
    const posMasterUser = await this.posMasterRepo.findOne({
      where: {
        orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
        current_holder: { keycloak: request.user.sub },
      },
      relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
    });
    if (!posMasterUser || !posMasterUser.orgRootId)
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");

    let condition: any = {
      isDirector: true,
      orgRootId: posMasterUser.orgRootId,
    };

    if (type.trim().toLowerCase() == "OPERATE") {
    } else {
      if (
        (posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญงาน") ||
        (posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติงาน") ||
        (posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติการ") ||
        (posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการ")
      ) {
        condition = {
          isDirector: true,
          orgRootId: posMasterUser.orgRootId,
          orgChild1Id: IsNull(),
          orgChild2Id: IsNull(),
          orgChild3Id: IsNull(),
          orgChild4Id: IsNull(),
        };
      } else if (
        (posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
          posMasterUser.current_holder.posLevel.posLevelName == "อาวุโส") ||
        (posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการพิเศษ") ||
        (posMasterUser.current_holder.posType.posTypeName == "อำนวยการ" &&
          posMasterUser.current_holder.posLevel.posLevelName == "ต้น")
      ) {
        condition = {
          isDirector: true,
          isDeputy: true,
          orgChild1Id: IsNull(),
          orgChild2Id: IsNull(),
          orgChild3Id: IsNull(),
          orgChild4Id: IsNull(),
        };
      } else {
      }
    }

    if (body.isAct == true) {
      const [lists, total] = await AppDataSource.getRepository(viewDirectorActing)
        .createQueryBuilder("viewDirectorActing")
        .andWhere(condition)
        .andWhere(
          new Brackets((qb) => {
            qb.orWhere(
              body.keyword != null && body.keyword != ""
                ? "CONCAT(viewDirectorActing.prefix,viewDirectorActing.firstName,' ',viewDirectorActing.lastName) LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirectorActing.citizenId LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirectorActing.position LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirectorActing.posLevel LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirectorActing.posType LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirectorActing.actFullName LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              );
          }),
        )
        .skip((body.page - 1) * body.pageSize)
        .take(body.pageSize)
        .getManyAndCount();
      return new HttpSuccess({ data: lists, total });
    } else {
      const [lists, total] = await AppDataSource.getRepository(viewDirector)
        .createQueryBuilder("viewDirector")
        .andWhere(condition)
        .andWhere(
          new Brackets((qb) => {
            qb.orWhere(
              body.keyword != null && body.keyword != ""
                ? "CONCAT(viewDirector.prefix,viewDirector.firstName,' ',viewDirector.lastName) LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirector.citizenId LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirector.position LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirector.posLevel LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              )
              .orWhere(
                body.keyword != null && body.keyword != ""
                  ? "viewDirector.posType LIKE :keyword"
                  : "1=1",
                {
                  keyword: `%${body.keyword}%`,
                },
              );
          }),
        )
        .skip((body.page - 1) * body.pageSize)
        .take(body.pageSize)
        .getManyAndCount();
      return new HttpSuccess({ data: lists, total });
    }
  }

  /**
   * API เช็ค สกจ
   *
   * @summary เช็ค สกจ
   *
   */
  @Get("keycloak/isofficer/{system}")
  async getIsOfficerByKeycloak(@Path() system: string, @Request() req: RequestWithUser) {
    const profile = await this.profileRepo.findOne({
      where: {
        keycloak: req.user.sub,
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");

    const profileOfficer = await this.posMasterRepo.findOne({
      where: {
        posMasterAssigns: { assignId: system },
        orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
        current_holderId: profile.id,
      },
      relations: ["orgChild1"],
    });
    const profileDirector = await this.posMasterRepo.findOne({
      where: {
        orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
        current_holderId: profile.id,
      },
    });
    if (!profileOfficer)
      return new HttpSuccess({
        isOfficer: false,
        isStaff: false,
        isDirector: profileDirector?.isDirector ?? false,
      });
    let isOfficer = profileOfficer.orgChild1 == null ? false : profileOfficer.orgChild1.isOfficer;
    return new HttpSuccess({
      isOfficer: isOfficer,
      isStaff: !isOfficer,
      isDirector: profileDirector?.isDirector ?? false,
    });
  }

  /**
   * API เช็ค สกจ
   *
   * @summary เช็ค สกจ
   *
   */
  @Get("keycloak/isofficer-root/{system}")
  async getIsOfficerByKeycloakRoot(@Path() system: string, @Request() req: RequestWithUser) {
    const profile = await this.profileRepo.findOne({
      where: {
        keycloak: req.user.sub,
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");

    const profileOfficer = await this.posMasterRepo.findOne({
      where: {
        posMasterAssigns: { assignId: system },
        orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
        current_holderId: profile.id,
      },
      relations: ["orgChild1"],
    });
    const profileDirector = await this.posMasterRepo.findOne({
      where: {
        orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
        current_holderId: profile.id,
      },
    });
    if (!profileOfficer)
      return new HttpSuccess({
        isOfficer: false,
        isStaff: false,
        isDirector: profileDirector?.isDirector ?? false,
      });
    let isOfficer = profileOfficer.orgChild1 == null ? false : profileOfficer.orgChild1.isOfficer;
    return new HttpSuccess({
      isOfficer: isOfficer,
      isStaff: !isOfficer,
      isDirector: profileDirector
        ? !profileDirector.orgChild1Id && profileDirector.orgRootId
          ? profileDirector.isDirector
          : false
        : false,
    });
  }

  /**
   * API เช็ค สกจ
   *
   * @summary เช็ค สกจ
   *
   */
  @Post("keycloak/isofficer")
  async checkPermissionWorkflow(
    @Request() req: RequestWithUser,
    @Body()
    body: {
      refId: string;
      sysName: string;
    },
  ) {
    const profile = await this.profileRepo.findOne({
      where: {
        keycloak: req.user.sub,
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");

    const profileOfficer = await this.workflowRepo.findOne({
      where: {
        states: { stateUserComments: { profile: { keycloak: req.user.sub } } },
        refId: body.refId,
        // sysName: body.sysName,
      },
    });
    if (!profileOfficer) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
    return new HttpSuccess();
  }
}
