<script setup lang="ts">
import { ref, reactive, watch, computed } from "vue";
import { useQuasar } from "quasar";

import http from "@/plugins/http";
import config from "@/app.config";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";

import type {
  FormDataAgency,
  DataOption,
} from "@/modules/02_organization/interface/index/Main";

import DialogHeader from "@/components/DialogHeader.vue";

/**
 * use
 */
const $q = useQuasar();
const store = useOrganizational();
const mixin = useCounterMixin();
const { dialogConfirm, showLoader, hideLoader, messageError, success } = mixin;

/**
 * props
 */
const level = defineModel<number>("orgLevel", { required: true });
const actionType = defineModel<string>("actionType", { required: true });
const props = defineProps({
  modal: {
    type: Boolean,
    require: true,
  },
  close: {
    type: Function,
    require: true,
  },
  fetchDataTree: {
    type: Function,
    require: true,
    default: () => "",
  },
  fetchDataTable: {
    type: Function,
    require: true,
    default: () => "",
  },
  dataNode: {
    type: Object,
    require: true,
  },
  edit: {
    type: Function,
    require: true,
  },
});

//ตัวเลือกระดับส่วนราชการหลัก
const orgLevelOptionMain = ref<DataOption[]>([
  { name: "ระดับสำนัก", id: "DEPARTMENT" },
  {
    name: "ระดับกอง/สำนักงาน/ส่วนราชการ/โรงพยาบาล/เทียบเท่ากอง",
    id: "OFFICE",
  },
  { name: "ระดับส่วน/กลุ่มภารกิจ", id: "DIVISION" },
  { name: "ระดับฝ่าย/กลุ่มงาน", id: "SECTION" },
]);
const orgLevelOption = ref<DataOption[]>([]); //ตัวเลือกระดับส่วนราชการ
const orgLevelSubOptionMain = ref<DataOption[]>([]); //ตัวเลือกระดับส่วนราชการซับ

// ฟอร์มข้อมูล
const formData = reactive<FormDataAgency>({
  orgName: "",
  orgShortName: "",
  orgCode: "",
  orgPhoneEx: "",
  orgPhoneIn: "",
  orgFax: "",
  orgLevel: "",
  orgLevelSub: "",
  responsibility: "",
  isOfficer: false,
  isDeputy: false,
});

/**
 * ฟังก์ชันบันทึกข้อมูลส่วนราชการ
 *
 * ถ้า actionType.value === "ADD" จะบันทึกการเพิ่มข้อมูลส่วนราชการ ไม่ จะบันทึกการแก้ไขข้อมูลส่วนราชการ
 **/
function onSubmit() {
  dialogConfirm($q, async () => {
    showLoader();
    const type = await store.checkLevel(level.value);
    const nameId =
      level.value === 0
        ? "orgRevisionId"
        : level.value === 1
        ? "orgRootId"
        : level.value === 2
        ? "orgChild1Id"
        : level.value === 3
        ? "orgChild2Id"
        : "orgChild3Id";

    let rootId: string = "";
    if (actionType.value === "ADD") {
      rootId = level.value === 0 ? store.draftId : props.dataNode?.orgTreeId;
    } else {
      rootId = level.value === 0 ? store.draftId : props.dataNode?.orgRootId;
    }

    let body = {
      ["org" + type + "Name"]: formData.orgName,
      ["org" + type + "ShortName"]: formData.orgShortName,
      ["org" + type + "Code"]: formData.orgCode,
      ["org" + type + "PhoneEx"]: formData.orgPhoneEx,
      ["org" + type + "PhoneIn"]: formData.orgPhoneIn,
      ["org" + type + "Fax"]: formData.orgFax,
      ["org" + type + "Rank"]: formData.orgLevel,
      ["org" + type + "RankSub"]: formData.orgLevelSub,
      [nameId]: rootId,
      responsibility:
        formData.responsibility != null ? formData.responsibility : "",
    };

    if (type === "Root") {
      body = {
        ...body,
        isDeputy:
          formData.isDeputy !== undefined ? String(formData.isDeputy) : "",
      };
    }
    if (type === "Child1") {
      body = {
        ...body,
        isOfficer:
          formData.isOfficer !== undefined ? String(formData.isOfficer) : "",
      };
    }

    //เพิ่มข้อมูล
    if (actionType.value === "ADD") {
      await http
        .post(config.API.createOrgLevel(type.toLocaleLowerCase()), body)
        .then(async () => {
          await props.fetchDataTree(store.draftId);
          await success($q, "บันทึกข้อมูลสำเร็จ");
          closeClear();
        })
        .catch((err) => {
          messageError($q, err);
        })
        .finally(() => {
          hideLoader();
        });
    } else {
      // แก่้ไขข้อมูล
      props.dataNode &&
        (await http
          .put(
            config.API.orgLevelByid(
              type.toLocaleLowerCase(),
              props.dataNode.orgTreeId
            ),
            body
          )
          .then(async () => {
            await props.fetchDataTree(store.draftId);
            await props.edit?.(
              props.dataNode?.orgTreeId,
              type,
              body,
              props.dataNode?.orgRootCode
            );
            await props.fetchDataTable(
              props?.dataNode?.orgTreeId,
              props?.dataNode?.orgLevel,
              false
            );
            await success($q, "บันทึกข้อมูลสำเร็จ");
            closeClear();
          })
          .catch((err) => {
            messageError($q, err);
          })
          .finally(() => {
            hideLoader();
          }));
    }
  });
}

/**
 * ฟังก์ชันเช็ต formdata กลับไปค่าว่าง และปิด popup
 */
function closeClear() {
  formData.orgName = "";
  formData.orgShortName = "";
  formData.orgCode = "";
  formData.orgPhoneEx = "";
  formData.orgPhoneIn = "";
  formData.orgFax = "";
  formData.orgLevel = "";
  formData.responsibility = "";
  formData.isOfficer = false;
  props.close?.();
}

/**
 * ฟังก์ชันเลือกระดับของส่วนราชการ
 * @param val ระดับของส่วนราชการ
 * @param status
 *
 * กำหนดตัวเลือกของระดับของส่วนราชการ(ซับ )ตามประเภทระดับของส่วนราชการ
 */
function selectOrgLevele(val: string, status: boolean = true) {
  formData.orgLevelSub = status ? "" : formData.orgLevelSub;
  switch (val) {
    case "DEPARTMENT":
      orgLevelSubOptionMain.value = [
        { name: "สำนัก", id: "BUREAU" },
        { name: "สำนักงาน", id: "OFFICE" },
        { name: "สำนักงานเขต", id: "DISTRICT" },
      ];
      break;
    case "OFFICE":
      orgLevelSubOptionMain.value = [
        { name: "กอง", id: "DIVISION" },
        {
          name: "สำนักงาน",
          id: "OFFICE",
        },
        { name: "ส่วนราชการ", id: "GOVERNMENT" },
        { name: "โรงพยาบาล", id: "HOSPITAL" },
        { name: "เทียบเท่ากอง", id: "EQUIVALENT" },
      ];

      break;
    case "DIVISION":
      orgLevelSubOptionMain.value = [
        { name: "ส่วน", id: "SECTION" },
        {
          name: "กลุ่มภารกิจ",
          id: "MISSION",
        },
      ];

    case "SECTION":
      orgLevelSubOptionMain.value = [
        { name: "ฝ่าย", id: "FACTION" },
        {
          name: "กลุ่มงาน",
          id: "WORK",
        },
        {
          name: "สถานีดับเพลิงและกู้ภัย",
          id: "FIRESTATION",
        },
        {
          name: "โรงเรียน",
          id: "SCHOOL",
        },
      ];

    default:
      break;
  }
}

/**
 * กำหนด Title ของ popup จะถูกตั้งตามประเภทการดำเนินการและระดับที่กำหนด
 */
const tittleName = computed(() => {
  let name = "";
  if (actionType.value === "ADD") {
    name = level.value === 0 ? "เพิ่มหน่วยงาน" : "เพิ่มส่วนราชการ";
  } else {
    name = level.value === 0 ? "แก้ไขหน่วยงาน" : "แก้ไขส่วนราชการ";
  }

  return name;
});

const checkIsOfficer = ref<boolean>(false); // เช็คว่าในโครงสร้างแบบร่างมีการเลือก สกจ. ไหม true = มี false = ไม่มี
const checkIsDeputy = ref<boolean>(false); // เช็คว่าในโครงสร้างแบบร่างมีการเลือก สำนักปลัด ไหม true = มี false = ไม่มี

/** ฟังก์ชั่นเช็คว่าในโครงสร้างแบบร่างมีการเลือก สกจ. หรือยัง */
async function checkOfficer() {
  await http
    .get(config.API.checkIsOfficer(store.draftId ?? ""))
    .then((res) => {
      checkIsOfficer.value = res.data.result;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/** ฟังก์ชั่นเช็คว่าในโครงสร้างแบบร่างมีการเลือก สกจ. หรือยัง */
async function onCheckIsDeputy() {
  await http
    .get(config.API.checkIsDeputys(store.draftId ?? ""))
    .then((res) => {
      checkIsDeputy.value = res.data.result;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/**
 * callback function ทำงานเมื่อ props.modal เป็น true
 */
watch(
  () => props.modal,
  () => {
    if (props.modal === true) {
      // ถ้าเป็นการเพิ่มข้อมูล
      if (actionType.value === "ADD") {
        props.dataNode?.orgLevel === 0 && checkOfficer();
        props.dataNode?.orgLevel === 0 && onCheckIsDeputy();

        if (props.dataNode) {
          formData.isDeputy = false;
          formData.orgCode =
            props?.dataNode?.orgLevel !== 0
              ? props?.dataNode.orgTreeCode
              : undefined;
          formData.orgShortName =
            props?.dataNode?.orgLevel !== 0
              ? props?.dataNode.orgTreeShortName
              : undefined;
        }

        if (level.value === 0) {
          formData.orgLevel = "DEPARTMENT";
          orgLevelOption.value = orgLevelOptionMain.value;
        } else {
          orgLevelOption.value = orgLevelOptionMain.value.slice(1, 4);
          formData.orgLevel = "";
        }

        formData.orgLevel == "DEPARTMENT" ? selectOrgLevele("DEPARTMENT") : "";
      }
      // ถ้าเป็นการแก้ไขข้อมูล
      else {
        props.dataNode?.orgLevel === 1 && checkOfficer();
        if (props.dataNode) {
          formData.orgName = props.dataNode.orgTreeName;
          formData.orgShortName = props.dataNode.orgTreeShortName;
          formData.orgCode = props.dataNode.orgTreeCode;
          formData.orgPhoneEx = props.dataNode.orgTreePhoneEx;
          formData.orgPhoneIn = props.dataNode.orgTreePhoneIn;
          formData.orgFax = props.dataNode.orgTreeFax;
          formData.orgLevel = props.dataNode.orgTreeRank;
          formData.orgLevelSub = props.dataNode.orgTreeRankSub;
          formData.responsibility = props.dataNode.responsibility;
          formData.isOfficer = props.dataNode.isOfficer ?? false;
          formData.isDeputy = props.dataNode.isDeputy ?? false;
          orgLevelOption.value =
            props.dataNode.orgTreeRank === "DEPARTMENT"
              ? orgLevelOptionMain.value
              : orgLevelOptionMain.value.slice(1, 4);
          selectOrgLevele(formData.orgLevel, false);
        }
      }
    }
  }
);

/** ถ้ามีการเลือก สกจ. และเคยมีเลือกไปแล้วระบบจะถามและให้ยืนยันการเลือกสกจ. */
function onChangeIsOfficer() {
  if (formData.isOfficer === true && checkIsOfficer.value === true) {
    dialogConfirm(
      $q,
      () => (formData.isOfficer = true),
      "ยืนยันการแก้ไข",
      "คุณต้องการแก้ไข สกจ. เป็นส่วนราชการนี้ใช่หรือไม่?",
      () => (formData.isOfficer = false)
    );
  }
}

/** ถ้ามีการเลือก สำนักปลัด และเคยมีเลือกไปแล้วระบบจะถามและให้ยืนยันการเลือกสำนักปลัด */
function onChangeIsDeputy() {
  if (formData.isDeputy == true && checkIsDeputy.value == true) {
    dialogConfirm(
      $q,
      () => (formData.isDeputy = true),
      "ยืนยันการแก้ไข",
      "คุณต้องการแก้ไข สำนักปลัด เป็นส่วนราชการนี้ใช่หรือไม่?",
      () => (formData.isDeputy = false)
    );
  }
}
</script>

<template>
  <template>
    <q-dialog v-model="props.modal" persistent>
      <q-card style="min-width: 60vw">
        <q-form greedy @submit.prevent @validation-success="onSubmit">
          <DialogHeader :tittle="tittleName" :close="closeClear" />
          <q-separator />
          <q-card-section>
            <div class="row q-col-gutter-sm">
              <div class="col-4">
                <q-input
                  v-model="formData.orgName"
                  ref="orgNameRef"
                  dense
                  outlined
                  for="#ocName"
                  :label="level == 0 ? 'ชื่อหน่วยงาน' : 'ชื่อส่วนราชการ'"
                  hide-bottom-space
                  :rules="[
                    (val:string) =>
                      !!val ||
                      `${
                        level == 0
                          ? 'กรุณากรอกชื่อหน่วยงาน'
                          : 'กรุณากรอกชื่อส่วนราชการ'
                      }`,
                  ]"
                />
              </div>
              <div class="col-2">
                <q-input
                  v-model="formData.orgShortName"
                  :readonly="
                    (actionType === 'ADD' &&
                      props?.dataNode?.orgLevel !== 0 &&
                      level !== 0) ||
                    (actionType === 'EDIT' && props?.dataNode?.orgLevel > 1)
                  "
                  ref="orgShortNameRef"
                  dense
                  outlined
                  for="#shortName"
                  label="อักษรย่อ"
                  hide-bottom-space
                  :rules="[(val:string) => !!val || `${'กรุณากรอกอักษรย่อ'}`]"
                />
              </div>
              <div class="col-2">
                <q-input
                  :readonly="
                    (actionType === 'ADD' &&
                      props?.dataNode?.orgLevel !== 0 &&
                      level !== 0) ||
                    (actionType === 'EDIT' && props?.dataNode?.orgLevel > 1)
                  "
                  mask="##"
                  v-model="formData.orgCode"
                  ref="orgCodeRef"
                  dense
                  outlined
                  for="#ocNo"
                  :label="level == 0 ? 'รหัสหน่วยงาน' : 'รหัสส่วนราชการ'"
                  hide-bottom-space
                  :rules="[
                    (val:string) =>
                      !!val ||
                      `${
                        level == 0
                          ? 'กรุณากรอกรหัสหน่วยงาน'
                          : 'กรุณากรอกรหัสส่วนราชการ'
                      }`,
                  ]"
                />
              </div>
              <div class="col-4">
                <q-select
                  :readonly="level === 0 || formData.orgLevel === 'DEPARTMENT'"
                  for="#ocLevel"
                  ref="orgLevelRef"
                  dense
                  hide-bottom-space
                  outlined
                  option-label="name"
                  option-value="id"
                  emit-value
                  map-options
                  v-model="formData.orgLevel"
                  @update:model-value="selectOrgLevele"
                  :options="orgLevelOption"
                  :label="
                    level == 0 ? 'ระดับของหน่วยงาน' : 'ระดับของส่วนราชการ'
                  "
                  :rules="[
                    (val:string) =>
                      !!val ||
                      `${
                        level == 0
                          ? 'กรุณาเลือกระดับของหน่วยงาน'
                          : 'กรุณาเลือกระดับของส่วนราชการ'
                      }`,
                  ]"
                  lazy-rules
                />
              </div>
              <div class="col-4" v-if="formData.orgLevel !== ''">
                <q-select
                  ref="orgLevelSubRef"
                  dense
                  hide-bottom-space
                  outlined
                  option-label="name"
                  option-value="id"
                  emit-value
                  map-options
                  v-model="formData.orgLevelSub"
                  :options="orgLevelSubOptionMain"
                  label="ระดับของส่วนราชการ(ซับ)"
                  :rules="[
                    (val:string) => !!val || 'กรุณาเลือกระดับของส่วนราชการ (ซับ)',
                  ]"
                  lazy-rules
                />
              </div>
              <div class="col-4">
                <q-input
                  v-model="formData.orgPhoneEx"
                  ref="orgPhoneExRef"
                  dense
                  outlined
                  for="#telOut"
                  label="หมายเลขโทรศัพท์ที่ติดต่อจากภายนอก"
                  hide-bottom-space
                />
              </div>
              <div class="col-4">
                <q-input
                  v-model="formData.orgPhoneIn"
                  ref="orgPhoneInRef"
                  dense
                  outlined
                  for="#telIn"
                  label="หมายเลขโทรศัพท์ที่ติดต่อจากภายใน"
                  hide-bottom-space
                />
              </div>
              <div class="col-4">
                <q-input
                  v-model="formData.orgFax"
                  ref="orgFaxRef"
                  dense
                  outlined
                  for="#tel"
                  label="หมายเลขโทรสาร"
                  hide-bottom-space
                />
              </div>
              <div class="col-12">
                <q-input
                  v-model="formData.responsibility"
                  ref="responsibilityRef"
                  dense
                  outlined
                  for="#tel"
                  label="หน้าที่ความรับผิดชอบ"
                  hide-bottom-space
                  type="textarea"
                  rows="4"
                />
              </div>
              <div
                v-if="
                  (actionType === 'ADD' && props.dataNode?.orgLevel === 0) ||
                  (actionType === 'EDIT' && props.dataNode?.orgLevel === 1)
                "
                class="col-12"
              >
                <q-checkbox
                  keep-color
                  color="primary"
                  dense
                  v-model="formData.isOfficer"
                  label="สกจ."
                  class="q-ml-sm"
                  @update:model-value="onChangeIsOfficer"
                />
              </div>
              <div
                v-if="
                  (actionType === 'ADD' && level === 0) ||
                  (actionType === 'EDIT' && props.dataNode?.orgLevel === 0)
                "
                class="col-12"
              >
                <q-checkbox
                  keep-color
                  color="primary"
                  dense
                  v-model="formData.isDeputy"
                  label="สำนักปลัด"
                  class="q-ml-sm"
                  @update:model-value="onChangeIsDeputy"
                />
              </div>
            </div>
          </q-card-section>
          <q-separator />
          <q-card-actions align="right">
            <q-btn type="submit" :label="`บันทึก`" color="public">
              <q-tooltip>บันทึกข้อมูล</q-tooltip></q-btn
            >
          </q-card-actions>
        </q-form>
      </q-card>
    </q-dialog>
  </template>
</template>

<style scoped></style>
