import {
  Controller,
  Post,
  Put,
  Delete,
  Route,
  Security,
  Tags,
  Body,
  Path,
  Request,
  Response,
  Get,
  Query,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
import HttpStatusCode from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
import { CommandType, CreateCommandType, UpdateCommandType } from "../entities/CommandType";
import { CommandSys } from "../entities/CommandSys";
import { Brackets } from "typeorm";

@Route("api/v1/org/commandType")
@Tags("CommandType")
@Security("bearerAuth")
@Response(
  HttpStatusCode.INTERNAL_SERVER_ERROR,
  "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class CommandTypeController extends Controller {
  private commandTypeRepository = AppDataSource.getRepository(CommandType);
  private commandSysRepository = AppDataSource.getRepository(CommandSys);

  /**
   * API  list รายการประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   */
  @Get("list")
  async Get() {
    const _commandType = await this.commandTypeRepository.find({
      where: { isActive: true },
      select: [
        "id",
        "name",
        "commandSysId",
        "code",
        "fileCover",
        "fileAttachment",
        "detailHeader",
        "detailBody",
        "detailFooter",
        "subtitle",
        "isSalary",
        "isAttachment",
        "isUploadAttachment",
        "createdAt",
        "lastUpdatedAt",
        "createdFullName",
        "lastUpdateFullName",
      ],
      order: { order: "ASC" },
    });
    return new HttpSuccess(_commandType);
  }

  /**
   * API  list รายการประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   */
  @Get("admin")
  async GetAdmin(
    @Query("page") page: number = 1,
    @Query("pageSize") pageSize: number = 10,
    @Query("keyword") keyword?: string | null,
    @Query() isActive?: boolean | null,
  ) {
    const [commandTypes, total] = await this.commandTypeRepository
      .createQueryBuilder("commandType")
      .andWhere(
        isActive != null && isActive != undefined ? "commandType.isActive = :isActive" : "1=1",
        {
          isActive:
            isActive == null || isActive == undefined ? null : `${isActive == true ? 1 : 0}`,
        },
      )
      .andWhere(
        new Brackets((qb) => {
          qb.where(keyword != null && keyword != "" ? "commandType.name LIKE :keyword" : "1=1", {
            keyword: `%${keyword}%`,
          }).orWhere(
            keyword != null && keyword != "" ? "commandType.detailBody LIKE :keyword" : "1=1",
            {
              keyword: `%${keyword}%`,
            },
          );
        }),
      )
      .orderBy("commandType.order", "ASC")
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();
    return new HttpSuccess({ commandTypes, total });
  }

  /**
   * API รายละเอียดรายการประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id  ประเภทคำสั่ง
   */
  @Get("{id}")
  async GetById(@Path() id: string) {
    let _commandType = await this.commandTypeRepository.findOne({
      where: { id },
      select: [
        "id",
        "name",
        "commandSysId",
        "code",
        "fileCover",
        "fileAttachment",
        "isActive",
        "detailHeader",
        "detailBody",
        "detailFooter",
        "subtitle",
        "isAttachment",
        "isUploadAttachment",
      ],
    });
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
    }
    if (_commandType.code == "C-PM-10") {
      let _commandType10: any;
      _commandType10 = {
        id: _commandType.id,
        name: _commandType.name,
        commandSysId: _commandType.commandSysId,
        code: _commandType.code,
        fileCover: _commandType.fileCover,
        fileAttachment: _commandType.fileAttachment,
        isActive: _commandType.isActive,
        detailHeader: _commandType.detailHeader,
        detailBody: _commandType.detailBody,
        detailFooter: _commandType.detailFooter,
        subtitle: _commandType.subtitle,
        isAttachment: _commandType.isAttachment,
        isUploadAttachment: _commandType.isUploadAttachment,
        name1: "๑. ..........................ประธาน",
        name2: "๒. ..........................กรรมการ",
        name3: "๓. ..........................กรรมการ",
        name4: "๔. ..........................กรรมการ",
      };
      _commandType = _commandType10;
    } else if (["C-PM-21", "C-PM-23"].includes(_commandType.code)) {
      let _commandType21and23: any;
      _commandType21and23 = {
        id: _commandType.id,
        name: _commandType.name,
        commandSysId: _commandType.commandSysId,
        code: _commandType.code,
        fileCover: _commandType.fileCover,
        fileAttachment: _commandType.fileAttachment,
        isActive: _commandType.isActive,
        detailHeader: _commandType.detailHeader,
        detailBody: _commandType.detailBody,
        detailFooter: _commandType.detailFooter,
        subtitle: _commandType.subtitle,
        isAttachment: _commandType.isAttachment,
        isUploadAttachment: _commandType.isUploadAttachment,
        name1: "๑. ..........................ประธาน",
        name2: "๒. ..........................กรรมการ",
        name3: "๓. ..........................กรรมการ",
        name4: "๔. ..........................กรรมการ",
        persons: [
          {
            no: "",
            org: "",
            fullName: "",
            citizenId: "",
            position: "",
            posLevel: "",
            posNo: "",
            amount: "",
            dateRetire: "",
            dateExecute: "",
            remark: "",
          },
        ],
      };
      _commandType = _commandType21and23;
    }
    return new HttpSuccess(_commandType);
  }

  /**
   * API สร้างรายการ body ประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   */
  @Post()
  async Post(
    @Body()
    requestBody: CreateCommandType,
    @Request() request: { user: Record<string, any> },
  ) {
    const _commandType = Object.assign(new CommandType(), requestBody);
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
    }

    // const checkName = await this.commandTypeRepository.findOne({
    //   where: { name: requestBody.name },
    // });

    // if (checkName) {
    //   throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อนี้มีอยู่ในระบบแล้ว");
    // }

    const checkNameSys = await this.commandSysRepository.findOne({
      where: { id: requestBody.commandSysId },
    });

    if (!checkNameSys) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อประเภทนี้มีอยู่ในระบบ");
    }

    _commandType.createdUserId = request.user.sub;
    _commandType.createdFullName = request.user.name;
    _commandType.lastUpdateUserId = request.user.sub;
    _commandType.lastUpdateFullName = request.user.name;
    _commandType.createdAt = new Date();
    _commandType.lastUpdatedAt = new Date();
    await this.commandTypeRepository.save(_commandType);
    return new HttpSuccess(_commandType.id);
  }

  /**
   * API  แก้ไขรายการ body ประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id ประเภทคำสั่ง
   */
  @Put("{id}")
  async Put(
    @Path() id: string,
    @Body()
    requestBody: UpdateCommandType,
    @Request() request: { user: Record<string, any> },
  ) {
    const _commandType = await this.commandTypeRepository.findOne({ where: { id: id } });
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทคำสั่งชื่อนี้");
    }
    // const checkName = await this.commandTypeRepository.findOne({
    //   where: { id: Not(id), name: requestBody.name },
    // });
    // if (checkName) {
    //   throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อนี้มีอยู่ในระบบแล้ว");
    // }

    const checkNameSys = await this.commandSysRepository.findOne({
      where: { id: requestBody.commandSysId },
    });

    if (!checkNameSys) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อประเภทนี้มีอยู่ในระบบ");
    }

    _commandType.lastUpdateUserId = request.user.sub;
    _commandType.lastUpdateFullName = request.user.name;
    _commandType.lastUpdatedAt = new Date();
    Object.assign(_commandType, requestBody);
    await this.commandTypeRepository.save(_commandType);
    return new HttpSuccess(_commandType.id);
  }

  /**
   * API  แก้ไขรายการ body ประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id ประเภทคำสั่ง
   */
  @Put("text/{id}")
  async PutText(
    @Path() id: string,
    @Body()
    requestBody: { detailHeader: string; detailBody: string; detailFooter: string },
    @Request() request: { user: Record<string, any> },
  ) {
    const _commandType = await this.commandTypeRepository.findOne({ where: { id: id } });
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทคำสั่งชื่อนี้");
    }

    _commandType.lastUpdateUserId = request.user.sub;
    _commandType.lastUpdateFullName = request.user.name;
    _commandType.lastUpdatedAt = new Date();
    this.commandTypeRepository.merge(_commandType, requestBody);
    await this.commandTypeRepository.save(_commandType);
    return new HttpSuccess(_commandType.id);
  }

  /**
   * API  แก้ไขรายการ body ประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id ประเภทคำสั่ง
   */
  @Put("cover/{id}")
  async PutCover(
    @Path() id: string,
    @Body()
    requestBody: { name: string },
    @Request() request: { user: Record<string, any> },
  ) {
    const _commandType = await this.commandTypeRepository.findOne({ where: { id: id } });
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทคำสั่งชื่อนี้");
    }
    _commandType.fileCover = requestBody.name;
    _commandType.lastUpdateUserId = request.user.sub;
    _commandType.lastUpdateFullName = request.user.name;
    _commandType.lastUpdatedAt = new Date();
    await this.commandTypeRepository.save(_commandType);
    return new HttpSuccess(_commandType.id);
  }

  /**
   * API  แก้ไขรายการ body ประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id ประเภทคำสั่ง
   */
  @Put("attachment/{id}")
  async PutAttachment(
    @Path() id: string,
    @Body()
    requestBody: { name: string },
    @Request() request: { user: Record<string, any> },
  ) {
    const _commandType = await this.commandTypeRepository.findOne({ where: { id: id } });
    if (!_commandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทคำสั่งชื่อนี้");
    }
    _commandType.fileAttachment = requestBody.name;
    _commandType.lastUpdateUserId = request.user.sub;
    _commandType.lastUpdateFullName = request.user.name;
    _commandType.lastUpdatedAt = new Date();
    await this.commandTypeRepository.save(_commandType);
    return new HttpSuccess(_commandType.id);
  }

  /**
   * API ลบรายการประเภทคำสั่ง
   *
   * @summary ORG_056 - CRUD ประเภทคำสั่ง (ADMIN) #61
   *
   * @param {string} id  Id ประเภทคำสั่ง
   */
  @Delete("{id}")
  async Delete(@Path() id: string) {
    const _delCommandType = await this.commandTypeRepository.findOne({
      where: { id: id },
    });
    if (!_delCommandType) {
      throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทคำสั่งชื่อนี้");
    }
    await this.commandTypeRepository.delete(_delCommandType.id);
    return new HttpSuccess();
  }
}
