<script setup lang="ts">
import { computed, ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";

import type {
  DataOption,
  FormData,
} from "@/modules/13_salary/interface/index/Main";
import type {
  SalaryPosType,
  SalaryPosLevel,
} from "@/modules/13_salary/interface/response/Main";

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

import { useCounterMixin } from "@/stores/mixin";

const isReadonly = ref<boolean>(false);
const $q = useQuasar();
const {
  date2Thai,
  dialogConfirm,
  showLoader,
  hideLoader,
  messageError,
  success,
} = useCounterMixin();

const modal = defineModel<boolean>("modal", { required: true });
const props = defineProps({
  typeAction: {
    type: String,
    required: true,
  },
  data: {
    type: Object,
    defult: [],
  },
  fetchData: {
    type: Function,
    defult: () => {},
  },
});

const salaryId = ref<string>(""); //id รายการผังบัญชีเงินเดือน
const formData = reactive<FormData>({
  name: "", //*ชื่อผังบัญชีอัตราเงินเดือน
  posTypeId: "", //*ประเภทของตำแหน่ง
  posLevelId: "", //*ระดับของตำแหน่ง
  isActive: false, //*สถานะการใช้งาน
  date: null, //ให้ไว้ ณ วันที่
  startDate: null, //วันที่มีผลบังคับใช้
  endDate: null, //วันที่สิ้นสุดบังคับใช้
  details: "", //คำอธิบาย
  isSpecial: false,
});

const posType = ref<SalaryPosType[]>([]); //ข้อมูลประเภทตำแหน่ง
const salaryPosTypeOptionMain = ref<DataOption[]>([]); //ข้อมูลรายการประเภทตำแหน่ง
const salaryPosTypeOption = ref<DataOption[]>([]); //ตัวเลือกรายการประเภทตำแหน่ง
const salaryPosLevelOptionMain = ref<DataOption[]>([]); //ข้อมูลรายการระดับตำแหน่ง
const salaryPosLevelOption = ref<DataOption[]>([]); //ตัวเลือกรายการระดับตำแหน่ง

//ชื่อ popup
const title = computed(() => {
  const name =
    props.typeAction === "add"
      ? "เพิ่มผังบัญชีเงินเดือน"
      : props.typeAction === "edit"
      ? "แก้ไขผังบัญชีเงินเดือน"
      : props.typeAction === "view"
      ? "รายละเอียด"
      : "บัญชีเงินเดือน";

  return name;
});

/**
 * fiunction fetch ข้อมูลประเภทตำแหน่ง
 */
function fetchPosType() {
  http
    .get(config.API.salaryPosType)
    .then((res) => {
      posType.value = res.data.result;
      const listOption = res.data.result.map((e: SalaryPosType) => ({
        id: e.id,
        name: e.posTypeName,
      }));
      salaryPosTypeOption.value = listOption;
      salaryPosTypeOptionMain.value = listOption;
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/**
 * fiunction fetch ข้อมูลระดับตำแหน่ง
 */
function fetchPosLevel(id: string) {
  const filterLevel = posType.value.find((e: SalaryPosType) => e.id === id);
  const listOption =
    filterLevel?.posLevels.map((e: SalaryPosLevel) => ({
      id: e.id,
      name: e.posLevelName,
    })) || [];

  salaryPosLevelOption.value = listOption;
  salaryPosLevelOptionMain.value = listOption;
  if (!listOption.some((e: DataOption) => e.id === formData.posLevelId)) {
    formData.posLevelId = "";
  }
}

/**
 *  function fetch ข้อมูลผังบัญชีเงินเดือน
 * @param id ผังบัญชีเงินเดือน
 */
function fetchSalaryDetail(id: string) {
  showLoader();
  http
    .get(config.API.salaryChartByid(id))
    .then(async (res) => {
      const data = await res.data.result;
      formData.name = data.name;
      formData.posTypeId = data.posTypeId;
      formData.posLevelId = data.posLevelId;
      formData.isActive = data.isActive;
      formData.date = data.date;
      formData.startDate = data.startDate;
      formData.endDate = data.endDate;
      formData.details = data.details;
      formData.isSpecial = data.isSpecial;
      isReadonly.value = props.typeAction === "view" ? true : data.isActive;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/**
 * callbackFunction ทำการ fetch ข้อมูลไฟล์เมื่อเปิด Dialog
 */
watch(
  () => modal.value,
  async () => {
    if (modal.value) {
      fetchPosType();

      if (props.typeAction === "edit" || props.typeAction === "view") {
        showLoader();
        setTimeout(() => {
          if (props.data) {
            salaryId.value = props.data.id;
            fetchPosLevel(props?.data?.posTypeId);
            fetchSalaryDetail(props.data.id);
          }
        }, 1000);
      }
    }
  }
);

/**
 * function ปืด Dialog
 */
function closeDialog() {
  modal.value = !modal.value;
  clearFormData();
}

/**
 * function เคลียข้อมูล form
 */
function clearFormData() {
  formData.name = "";
  formData.posTypeId = "";
  formData.posLevelId = "";
  formData.isSpecial = false;
  formData.isActive = false;
  formData.date = null;
  formData.startDate = null;
  formData.endDate = null;
  formData.details = "";
  isReadonly.value = false;
}

/**
 * function บันทึกข้อมูลผังบัญชีเงินเดือน
 */
function onSubmit() {
  dialogConfirm($q, async () => {
    showLoader();
    try {
      const url =
        props.typeAction === "add"
          ? config.API.salaryChart
          : config.API.salaryChartByid(salaryId.value);
      await http[props.typeAction === "add" ? "post" : "put"](url, formData);
      await props.fetchData?.();
      await success($q, "บันทีกข้อมูลสำเร็จ");
      closeDialog();
    } catch (err) {
      messageError($q, err);
    } finally {
      hideLoader();
    }
  });
}

/**
 *  function checkEndDate
 */
function checkEndDate() {
  if (formData.endDate !== null && formData.startDate !== null) {
    if (formData.endDate < formData.startDate) {
      formData.endDate = null;
    }
  }
}

/**
 * function ค้นหาคำใน select
 * @param val คำค้นหา
 * @param update function
 * @param type ประเภท select
 */
function filterSelector(val: string, update: Function, type: string) {
  switch (type) {
    case "posType":
      update(() => {
        formData.posTypeId = "";
        salaryPosTypeOption.value = salaryPosTypeOptionMain.value.filter(
          (v: DataOption) => v.name.toLowerCase().indexOf(val) > -1
        );
      });
      break;
    case "posLevel":
      update(() => {
        formData.posLevelId = "";
        salaryPosLevelOption.value = salaryPosLevelOptionMain.value.filter(
          (v: DataOption) => v.name.toLowerCase().indexOf(val) > -1
        );
      });
      break;

    default:
      break;
  }
}

/**
 * class จัดรูปแบบแสดงระหว่างข้อมูลที่แก้ไขหรือแสดงเฉยๆ
 * @param val ข้อมูล input สำหรับแก้ไขหรือไม่
 */
const getClass = (val: boolean) => {
  return {
    "full-width inputgreen cursor-pointer": val,
    "full-width cursor-pointer": !val,
  };
};
</script>

<template>
  <q-dialog v-model="modal" persistent>
    <q-card class="col-12" style="width: 55%">
      <q-form greedy @submit.prevent @validation-success="onSubmit">
        <Header :tittle="title" :close="closeDialog" />
        <q-separator />
        <q-card-section class="scroll" style="max-height: 70vh">
          <div class="row col-12 q-col-gutter-sm">
            <div class="col-md-12">
              <div class="row col-12 q-col-gutter-sm">
                <div class="col-xs-12 col-md-4">
                  <q-input
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                    ref="nameRef"
                    dense
                    hide-bottom-space
                    outlined
                    v-model="formData.name"
                    label="ชื่อผังบัญชีอัตราเงินเดือน"
                    :rules="[
                      (val:string) => !!val || 'กรุณากรอกชื่อผังบัญชีอัตราเงินเดือน',
                    ]"
                    lazy-rules
                  />
                </div>

                <div class="col-xs-12 col-md-4">
                  <q-select
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                    ref="posTypeRef"
                    dense
                    hide-bottom-space
                    outlined
                    option-label="name"
                    option-value="id"
                    emit-value
                    map-options
                    v-model="formData.posTypeId"
                    :options="salaryPosTypeOption"
                    label="ประเภทตำแหน่ง/กลุ่ม"
                    :rules="[(val:string) => !!val || 'กรุณาเลือกประเภทตำแหน่ง/กลุ่ม']"
                    lazy-rules
                    use-input
                    @update:model-value="fetchPosLevel"
                    @filter="(inputValue: string,
            doneFn: Function) => filterSelector(inputValue, doneFn ,'posType')"
                  >
                    <template v-slot:no-option>
                      <q-item>
                        <q-item-section class="text-grey">
                          ไม่มีข้อมูล
                        </q-item-section>
                      </q-item>
                    </template>
                  </q-select>
                </div>

                <div class="col-xs-12 col-md-4">
                  <q-select
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                    ref="posLevelRef"
                    dense
                    hide-bottom-space
                    outlined
                    option-label="name"
                    option-value="id"
                    emit-value
                    map-options
                    v-model="formData.posLevelId"
                    :options="salaryPosLevelOption"
                    label="ระดับ"
                    :rules="[(val:string) => !!val || 'กรุณาเลือกระดับ']"
                    lazy-rules
                    use-input
                    :disable="formData.posTypeId === ''"
                    @filter="(inputValue: string,
            doneFn: Function) => filterSelector(inputValue, doneFn ,'posLevel')"
                  >
                    <template v-slot:no-option>
                      <q-item>
                        <q-item-section class="text-grey">
                          ไม่มีข้อมูล
                        </q-item-section>
                      </q-item>
                    </template></q-select
                  >
                </div>

                <div class="row col-12">
                  <q-checkbox
                    :disable="isReadonly"
                    size="md"
                    v-model="formData.isSpecial"
                    label="เฉพาะสายงานที่กำหนด"
                  />

                  <q-toggle
                    :disable="isReadonly"
                    color="primary"
                    label="สถานะการใช้งาน"
                    v-model="formData.isActive"
                  />
                </div>

                <div class="col-xs-12 col-md-4">
                  <datepicker
                    menu-class-name="modalfix"
                    v-model="formData.date"
                    :locale="'th'"
                    autoApply
                    borderless
                    :enableTimePicker="false"
                    week-start="0"
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                  >
                    <template #year="{ year }">
                      {{ year + 543 }}
                    </template>
                    <template #year-overlay-value="{ value }">
                      {{ parseInt(value + 543) }}
                    </template>
                    <template #trigger>
                      <q-input
                        :readonly="isReadonly"
                        outlined
                        dense
                        hide-bottom-space
                        :model-value="
                          formData.date != null
                            ? date2Thai(formData.date)
                            : null
                        "
                        label="ให้ไว้ ณ วันที่"
                      >
                        <template v-slot:prepend>
                          <q-icon
                            name="event"
                            class="cursor-pointer"
                            style="color: var(--q-primary)"
                          >
                          </q-icon>
                        </template>
                      </q-input>
                    </template>
                  </datepicker>
                </div>

                <div class="col-xs-12 col-md-4">
                  <datepicker
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                    menu-class-name="modalfix"
                    v-model="formData.startDate"
                    :locale="'th'"
                    autoApply
                    borderless
                    :enableTimePicker="false"
                    week-start="0"
                    @update:model-value="checkEndDate"
                  >
                    <template #year="{ year }">
                      {{ year + 543 }}
                    </template>
                    <template #year-overlay-value="{ value }">
                      {{ parseInt(value + 543) }}
                    </template>
                    <template #trigger>
                      <q-input
                        :readonly="isReadonly"
                        outlined
                        dense
                        hide-bottom-space
                        :model-value="
                          formData.startDate != null
                            ? date2Thai(formData.startDate)
                            : null
                        "
                        label="วันที่มีผลบังคับใช้"
                      >
                        <template v-slot:prepend>
                          <q-icon
                            name="event"
                            class="cursor-pointer"
                            style="color: var(--q-primary)"
                          >
                          </q-icon>
                        </template>
                      </q-input>
                    </template>
                  </datepicker>
                </div>

                <div class="col-xs-12 col-md-4">
                  <datepicker
                    :readonly="isReadonly"
                    :class="getClass(!isReadonly)"
                    menu-class-name="modalfix"
                    v-model="formData.endDate"
                    :locale="'th'"
                    autoApply
                    borderless
                    :enableTimePicker="false"
                    week-start="0"
                    :min-date="formData.startDate"
                  >
                    <template #year="{ year }">
                      {{ year + 543 }}
                    </template>
                    <template #year-overlay-value="{ value }">
                      {{ parseInt(value + 543) }}
                    </template>
                    <template #trigger>
                      <q-input
                        :readonly="isReadonly"
                        outlined
                        dense
                        :model-value="
                          formData.endDate != null
                            ? date2Thai(formData.endDate)
                            : null
                        "
                        label="วันที่สิ้นสุดบังคับใช้"
                      >
                        <template v-slot:prepend>
                          <q-icon
                            name="event"
                            class="cursor-pointer"
                            style="color: var(--q-primary)"
                          >
                          </q-icon>
                        </template>
                      </q-input>
                    </template>
                  </datepicker>
                </div>

                <div class="col-12">
                  <q-input
                    :class="getClass(!isReadonly)"
                    :readonly="isReadonly"
                    v-model="formData.details"
                    outlined
                    dense
                    type="textarea"
                    label="คำอธิบาย"
                  />
                </div>
              </div>
            </div>
          </div>
        </q-card-section>

        <q-separator />
        <q-card-actions align="right" v-if="!isReadonly">
          <q-btn label="บันทึก" color="secondary" type="submit"
            ><q-tooltip>บันทึกข้อมูล</q-tooltip></q-btn
          >
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style lang="scss" scoped></style>
