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

import type {
  DataOption,
  ObjectSalaryRef,
} 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 $q = useQuasar();
const {
  date2Thai,
  dialogConfirm,
  showLoader,
  hideLoader,
  messageError,
  success,
  dialogRemove,
} = 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>("");
const formData = reactive({
  salaryType: "", //*ประเภทผัง (OFFICER->"ข้าราชการกรุงเทพมหานครสามัญ",EMPLOYEE->"ลูกจ้างประจำกรุงเทพมหานคร")
  posTypeId: "", //*ประเภทของตำแหน่ง
  posLevelId: "", //*ระดับของตำแหน่ง
  isActive: false, //*สถานะการใช้งาน
  date: null, //ให้ไว้ ณ วันที่
  startDate: null, //วันที่มีผลบังคับใช้
  endDate: null, //วันที่สิ้นสุดบังคับใช้
  details: "", //คำอธิบาย
});

/** ตัวแปร ref สำหรับแสดง validate */
const salaryTypeRef = ref<Object | null>(null);
const posTypeRef = ref<Object | null>(null);
const posLevelRef = ref<Object | null>(null);
const dateRef = ref<Object | null>(null);
const startDateRef = ref<Object | null>(null);
const endDateRef = ref<Object | null>(null);

const ObjectRef: ObjectSalaryRef = {
  salaryType: salaryTypeRef,
  posTypId: posTypeRef,
  posLevelId: posLevelRef,
  date: dateRef,
  startDate: startDateRef,
  endDate: endDateRef,
};

const salaryTypeOption = ref<DataOption[]>([
  { id: "OFFICER", name: "ข้าราชการกรุงเทพมหานครสามัญ" },
  { id: "EMPLOYEE", name: "ลูกจ้างประจำกรุงเทพมหานคร" },
]);

const posType = ref<SalaryPosType[]>([]);
const salaryPosTypeOption = ref<DataOption[]>([]);
const salaryPosLevelOption = ref<DataOption[]>([]);

const documentFile = ref<any>(null);
const itemsDocument = ref<any>([]);

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

  return name;
});

async function fetchPosType() {
  await 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;
    })
    .catch((err) => {
      messageError($q, err);
    });
}

async 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;
  if (!listOption.some((e: DataOption) => e.id === formData.posLevelId)) {
    formData.posLevelId = "";
  }
}

async function fetchSalaryDetail(id: string) {
  showLoader();
  await http
    .get(config.API.salaryChartByid(id))
    .then((res) => {
      const data = res.data.result;
      formData.salaryType = data.salaryType;
      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;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

async function fetchDocumentFile(id: string) {
  await http
    .get(config.API.salaryChartFile(id))
    .then((res) => {
      const list = res.data.map((e: any) => ({ name: e.fileName }));
      itemsDocument.value = list;
    })
    .catch((err) => {});
}

watch(
  () => modal.value,
  async () => {
    if (modal.value) {
      if (salaryPosTypeOption.value.length === 0) {
        await fetchPosType();
      }

      if (props.typeAction === "edit") {
        await showLoader();
        if (props.data) {
          salaryId.value = props.data.id;
          await fetchDocumentFile(props.data.id);
          await fetchSalaryDetail(props.data.id);
          await fetchPosLevel(props.data.posTypeId);
        }
      }
    }
  }
);

function closeDialog() {
  modal.value = !modal.value;
  clearFormData();
}

function clearFormData() {
  formData.salaryType = "";
  formData.posTypeId = "";
  formData.posLevelId = "";
  formData.isActive = false;
  formData.date = null;
  formData.startDate = null;
  formData.endDate = null;
  formData.details = "";
  documentFile.value = null;
  itemsDocument.value = [];
}

function onClickSubmit() {
  const hasError = [];
  for (const key in ObjectRef) {
    if (Object.prototype.hasOwnProperty.call(ObjectRef, key)) {
      const property = ObjectRef[key];
      if (property.value && typeof property.value.validate === "function") {
        const isValid = property.value.validate();
        hasError.push(isValid);
      }
    }
  }
  if (hasError.every((result) => result === true)) {
    createSalary();
  }
}

function createSalary() {
  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);
      success($q, "บันทีกข้อมูลสำเร็จ");
      props.fetchData?.();
    } catch (err) {
      messageError($q, err);
    } finally {
      hideLoader();
      closeDialog();
    }
  });
}

async function uploadDocumentFile() {
  const fileName = documentFile.value.name.replace(/\.(xlsx|docx|pdf)$/, "");
  showLoader();
  const formData = new FormData();
  formData.append("file", documentFile.value);
  const body = {
    replace: false,
    fileList: {
      fileName: fileName,
    },
  };
  await http
    .post(config.API.salaryChartFile(salaryId.value), body)
    .then((res) => {
      console.log(res);
      const foundKey: any = Object.keys(res.data).find(
        (key) =>
          res.data[key]?.fileName !== undefined &&
          res.data[key]?.fileName !== ""
      );
      const link = res.data[foundKey]?.uploadUrl;
      fileUpLoad(link);
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}
/**
 * function อัปโหลดไฟล์
 * @param url link อัปโหลด
 */
function fileUpLoad(url: string) {
  axios
    .put(url, documentFile.value, {
      headers: { "Content-Type": documentFile.value?.type },
      onUploadProgress: (e) => console.log(e),
    })
    .then(() => {
      success($q, "อัปโหลดไฟล์สำเร็จ");
      documentFile.value = null;
      fetchDocumentFile(salaryId.value);
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {});
}

function onClickDeleteFile(fileName: string) {
  dialogRemove($q, async () => {
    showLoader();
    await http
      .delete(config.API.salaryChartDelFile(salaryId.value, fileName))
      .then(() => {
        setTimeout(() => {
          fetchDocumentFile(salaryId.value);
          success($q, "ลบไฟล์สำเร็จ");
        }, 1000);
      })
      .catch((err) => {
        messageError($q, err);
      })
      .finally(() => {
        setTimeout(() => {
          hideLoader();
        }, 1000);
      });
  });
}

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

async function onClickDonwload(fileName: string) {
  showLoader();
  await http
    .get(config.API.salaryChartDelFile(salaryId.value, fileName))
    .then((res) => {
      const data = res.data;
      downloadFile(data.downloadUrl, data.fileType, fileName);
    })
    .catch((err) => {
      messageError($q, err);
      hideLoader();
    });
}

/**
 * function เรียกไฟล์ PDF
 * @param url  link PDF
 * @param type  ประเภทไฟล์
 * @param fileName  ชือไฟล์
 */
async function downloadFile(url: string, type: string, fileName: string) {
  await axios
    .get(url, {
      method: "GET",
      responseType: "blob",
      headers: {
        "Content-Type": "application/json",
        Accept: type, // ถ้ามีการระบุเมื่ออัปโหลด
      },
    })
    .then(async (res) => {
      const a = document.createElement("a");
      a.href = window.URL.createObjectURL(res.data);
      a.download = fileName;
      a.click();
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}
</script>

<template>
  <q-dialog v-model="modal" persistent>
    <q-card class="col-12" style="width: 80%">
      <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-xs-12 col-md-4">
            <q-select
              ref="salaryTypeRef"
              dense
              hide-bottom-space
              outlined
              option-label="name"
              option-value="id"
              emit-value
              map-options
              v-model="formData.salaryType"
              :options="salaryTypeOption"
              label="ประเภทผังบัญชีเงินเดือน"
              :rules="[
                (val) => !!val || 'กรุณาเลือกประเภทผังบัญชีเงินเดือน',
              ]"
              lazy-rules
            />
          </div>

          <div class="col-xs-12 col-md-3">
            <q-select
              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) => !!val || 'กรุณาเลือกประเภทตำแหน่ง/กลุ่ม']"
              lazy-rules
              @update:model-value="fetchPosLevel"
            />
          </div>

          <div class="col-xs-12 col-md-3">
            <q-select
              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) => !!val || 'กรุณาเลือกระดับ']"
              lazy-rules
              :disable="formData.posTypeId === ''"
            />
          </div>

          <div
            class="col-xs-12 col-md-2"
            style="display: flex; justify-content: flex-end"
          >
            <q-toggle
              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"
            >
              <template #year="{ year }">
                {{ year + 543 }}
              </template>
              <template #year-overlay-value="{ value }">
                {{ parseInt(value + 543) }}
              </template>
              <template #trigger>
                <q-input
                  ref="dateRef"
                  outlined
                  dense
                  hide-bottom-space
                  :model-value="
                    formData.date != null ? date2Thai(formData.date) : null
                  "
                  label="ให้ไว ณ วันที่"
                  :rules="[
                    (val) =>
                      !!val || `${'กรุณาเลือกวันที่ ให้ไว ณ วันที่'}`,
                  ]"
                  lazy-rules
                >
                  <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
              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
                  ref="startDateRef"
                  outlined
                  dense
                  hide-bottom-space
                  :model-value="
                    formData.startDate != null
                      ? date2Thai(formData.startDate)
                      : null
                  "
                  label="วันที่มีผลบังคับใช้"
                  :rules="[
                    (val) => !!val || `${'กรุณาเลือกวันที่มีผลบังคับใช้'}`,
                  ]"
                  lazy-rules
                >
                  <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
              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
                  ref="endDateRef"
                  outlined
                  dense
                  hide-bottom-space
                  :model-value="
                    formData.endDate != null
                      ? date2Thai(formData.endDate)
                      : null
                  "
                  label="วันที่สิ้นสุดบังคับใช้"
                  :rules="[
                    (val) =>
                      !!val || `${'กรุณาเลือกวันที่สิ้นสุดบังคับใช้'}`,
                  ]"
                  lazy-rules
                >
                  <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
              v-model="formData.details"
              outlined
              dense
              type="textarea"
              label="คำอธิบาย"
            />
          </div>
          
          <div class="col-xs-12 col-md-12">
            <q-card bordered style="border: 1px solid #d6dee1">
              <div
                class="col-12 text-weight-medium bg-grey-1 q-py-sm q-px-md"
              >
                อัปโหลดเอกสารอ้างอิง
              </div>
              <div class="col-12"><q-separator /></div>
              <div class="row col-12 q-col-gutter-y-sm q-pa-sm">
                <div class="col-12 row">
                  <q-file
                    v-if="props.typeAction === 'edit'"
                    class="col-12"
                    outlined
                    dense
                    v-model="documentFile"
                    label="เอกสารอ้างอิง"
                    hide-bottom-space
                  >
                    <template v-slot:prepend>
                      <q-icon name="attach_file" color="primary" />
                    </template>
                    <template v-slot:after>
                      <q-btn
                        v-if="documentFile"
                        size="14px"
                        flat
                        round
                        dense
                        color="add"
                        icon="mdi-upload"
                        @click="uploadDocumentFile"
                        ><q-tooltip>อัปโหลดเอกสาร</q-tooltip></q-btn
                      >
                    </template>
                  </q-file>
                </div>

                <div v-if="itemsDocument.length > 0" class="col-xs-12 row">
                  <q-list
                    class="full-width rounded-borders"
                    bordered
                    separator
                  >
                    <q-item
                      v-for="file in itemsDocument"
                      :key="file.id"
                      clickable
                      v-ripple
                    >
                      <q-item-section>{{ file.name }}</q-item-section>
                      <q-item-section avatar>
                        <div class="row q-col-gutter-md">
                          <div>
                            <q-btn
                              dense
                              flat
                              round
                              size="12px"
                              color="blue"
                              icon="mdi-download-outline"
                              @click="onClickDonwload(file.name)"
                            >
                              <q-tooltip>ดาวน์โหลดไฟล์</q-tooltip>
                            </q-btn>
                          </div>
                          <div>
                            <q-btn
                              dense
                              flat
                              round
                              size="12px"
                              color="red"
                              icon="mdi-delete-outline"
                              @click="onClickDeleteFile(file.name)"
                              ><q-tooltip>ลบไฟล์</q-tooltip></q-btn
                            >
                          </div>
                        </div>
                      </q-item-section>
                    </q-item>
                  </q-list>
                </div>

                <div class="col-12" v-else>
                  <q-card class="q-pa-md" bordered>
                    ไม่มีรายการเอกสาร
                  </q-card>
                </div>
              </div>
            </q-card>
          </div>
        </div>
      </q-card-section>
      <q-separator/>
      <q-card-section class="text-right">
        <q-btn label="บันทึก" color="secondary" @click="onClickSubmit">
          <q-tooltip>บันทึกข้อมูล</q-tooltip>
        </q-btn>
      </q-card-section>

      
    </q-card>
  </q-dialog>
</template>

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