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

import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";

import type { QTableProps } from "quasar";
import type { FormQuery } from "@/modules/01_metadata/interface/index/positionEmployee";
import type { DataOption } from "@/modules/01_metadata/interface/request/position/index";
import type {
  ResGroup,
  ResLevel,
  ResPossition,
} from "@/modules/01_metadata/interface/response/positionEmployee/Main";

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

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

//table
const rows = ref<ResPossition[]>([]);
const columns = ref<QTableProps["columns"]>([
  {
    name: "no",
    align: "left",
    label: "ลำดับ",
    sortable: false,
    field: "no",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "posDictName",
    align: "left",
    label: "ชื่อตำแหน่ง",
    sortable: true,
    field: "posDictName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "posTypeName",
    align: "left",
    label: "กลุ่มงาน",
    sortable: true,
    field: "posTypeName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "posLevelName",
    align: "left",
    label: "ระดับชั้นงาน",
    sortable: true,
    field: "posLevelName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "createdAt",
    align: "left",
    label: "วันที่สร้าง",
    sortable: true,
    field: "createdAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    format(val, row) {
      return date2Thai(val, false, true);
    },
  },
  {
    name: "lastUpdatedAt",
    align: "left",
    label: "วันที่แก้ไข",
    sortable: true,
    field: "lastUpdatedAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    format(val, row) {
      return date2Thai(val, false, true);
    },
  },
  {
    name: "lastUpdateFullName",
    align: "left",
    label: "ผู้ดำเนินการ",
    sortable: true,
    field: "lastUpdateFullName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
]);
const visibleColumns = ref<string[]>([
  "no",
  "posDictName",
  "posTypeName",
  "posLevelName",
  "createdAt",
  "lastUpdatedAt",
  "lastUpdateFullName",
]);
// ตัวเลือกค้นหา
const optionFilter = ref<DataOption[]>([
  { id: "positionName", name: "ชื่อตำแหน่ง" },
  { id: "positionType", name: "กลุ่มงาน" },
  { id: "positionLevel", name: "ระดับชั้นงาน" },
]);

const formQuery = reactive<FormQuery>({
  type: "positionName",
  keyword: "",
});

const modalDialog = ref<boolean>(false);
const isStatusEdit = ref<boolean>(false);
const posId = ref<string>("");

const formDataPos = reactive({
  posName: "",
  posTypeName: "",
  posLevelName: "",
});

const posTypeMain = ref<ResGroup[]>([]);
const posTypeOp = ref<DataOption[]>([]);
const posLevelOp = ref<DataOption[]>([]);

/**
 * ฟังก์ชันดึงข้อมูลรายการตำแหน่งจาก API
 * @param statusType สถานะการส่งประเภทค้นหา (true = ไม่ส่งประเภทค้นหา)
 *
 * เก็บข้อมูลรายการตำแหน่งจากไว้ใน rows.value
 */
async function fetchData(statusType: boolean = false) {
  showLoader();
  await http
    .get(
      config.API.orgEmployeePos +
        `?keyword=${formQuery.keyword}&type=${statusType ? "" : formQuery.type}`
    )
    .then(async (res) => {
      rows.value = await res.data.result;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/**
 * ฟังก์ชันยืนยันการบันทึกข้อมูลตำแหน่ง
 *
 * เมื่อ isStatusEdit เป็น false จะทำการเพิ่มข้อมูลรายการข้อมุลตำแหน่ง ถ้าไม่จะทำการแก้ไขข้อมูล
 * และเมื่อเพิ่มข้อมูลเสร็จจำทำการดึงข้อมูลรายการตำแหน่งใหม่
 */
function onSubmit() {
  dialogConfirm($q, async () => {
    const body = {
      posDictName: formDataPos.posName,
      posTypeId: formDataPos.posTypeName,
      posLevelId: formDataPos.posLevelName,
    };
    showLoader();
    //กำหนด Phat API
    const url = !isStatusEdit.value
      ? config.API.orgEmployeePos
      : config.API.orgEmployeePosById(posId.value);

    await http[!isStatusEdit.value ? "post" : "put"](url, body)
      .then(async () => {
        await fetchData();
        success($q, "บันทีกข้อมูลสำเร็จ");
        closeDialog();
      })
      .catch((err) => {
        messageError($q, err);
      })
      .finally(() => {
        hideLoader();
      });
  });
}

/**
 * ฟังก์ชันยืนยันการลบรายการข้อมูลตำแหน่ง
 *
 * @param id รายการข้อมูลตำแหน่งที่จะลบ
 * เมื่อลบข้อมูลเสร็จจำทำการดึงข้อมูลรายการตำแหน่งใหม่
 */
function deletePos(id: string) {
  dialogRemove($q, async () => {
    showLoader();
    await http
      .delete(config.API.orgEmployeePosById(id))
      .then(async () => {
        await fetchData();
        success($q, "ลบข้อมูลสำเร็จ");
      })
      .catch((err) => {
        messageError($q, err);
      })
      .finally(() => {
        hideLoader();
      });
  });
}

/**
 *  ฟังก์ชันเปิด popup เพื่อแก้ไขหรือคัดลอกข้อมูลตำแหน่ง
 * @param typeEdit สถานะการแก้ไข (true = แก้ไข, false = เพิ่มใหม่หรือคัดลอก)
 * @param data  ข้อมูลตำแหน่งที่ต้องการแก้ไขหรือคัดลอก
 */
async function onClickOpenDialog(
  typeEdit: boolean = false,
  data: ResPossition = {} as ResPossition
) {
  isStatusEdit.value = typeEdit;
  modalDialog.value = true;

  // ดึงข้อมูลกลุ่มงาน
  await fetchType();

  isStatusEdit.value = typeEdit;
  modalDialog.value = true;
  // อัพเดตข้อมูลประเภทตำแหน่งตาม id กลุ่มงาน
  await updatePosTypeName(data.posTypeId);

  if (data) {
    posId.value = data.id;
    formDataPos.posName = data.posDictName;
    formDataPos.posTypeName = data.posTypeId;
    formDataPos.posLevelName = data.posLevelId;
  }
}

/**
 *  ฟังก์ชันดึงข้อมูลกลุ่มงาน
 */
async function fetchType() {
  if (posTypeMain.value.length === 0) {
    showLoader();
    await http
      .get(config.API.orgEmployeeType)
      .then((res) => {
        const data = res.data.result;
        posTypeMain.value = data;
        posTypeOp.value = data.map((e: ResGroup) => ({
          id: e.id,
          name: e.posTypeName,
        }));
      })
      .catch((err) => {
        messageError($q, err);
      })
      .finally(() => {
        hideLoader();
      });
  }
}

/**
 * ฟังก์ชันหาตัวเลือกระดับชั้นงานตาม ID กลุ่มงาน
 * @param id กลุ่มงาน
 */
async function updatePosTypeName(id: string) {
  const posLevel = posTypeMain.value.find((e: ResGroup) => e.id === id);
  posLevelOp.value =
    posLevel?.posLevels.map((e: ResLevel) => ({
      id: e.id,
      name: e.posLevelName.toString(),
    })) ?? [];
  formDataPos.posLevelName = "";
}

/**
 *  ฟังก์ชันปิด Popup แก้ไขหรือคัดลอกข้อมูลตำแหน่ง
 * และกำหนด  formDataPos ไปเป็นค่าว่าง
 */
function closeDialog() {
  modalDialog.value = false;
  formDataPos.posName = "";
  formDataPos.posTypeName = "";
  formDataPos.posLevelName = "";
}

/**
 * hook ทำงานเมื่อ Components ถูกเรียกใช้งาน
 */
onMounted(async () => {
  await fetchData(true);
});
</script>
<template>
  <div class="row col-12 q-mb-sm q-col-gutter-sm">
    <div class="row col-12">
      <q-btn
        id="addComplaints"
        for="addComplaints"
        size="12px"
        flat
        round
        color="primary"
        icon="mdi-plus"
        @click="onClickOpenDialog()"
        ><q-tooltip>เพิ่มตำเเหน่ง </q-tooltip></q-btn
      >
    </div>

    <div class="row col-12 q-col-gutter-sm">
      <div class="row q-col-gutter-sm align-items-center">
        <div class="col-auto">
          <q-select
            label="ค้นหาจาก"
            v-model="formQuery.type"
            :options="optionFilter"
            emit-value
            dense
            map-options
            outlined
            option-label="name"
            option-value="id"
          />
        </div>

        <div class="col">
          <q-input
            ref="searchRef"
            v-model="formQuery.keyword"
            outlined
            dense
            lazy-rules
            label="คำค้น"
            hide-bottom-space
            @keydown.enter.prevent="fetchData()"
            style="min-width: 300px"
          >
            <template v-slot:append>
              <q-icon
                v-if="formQuery.keyword"
                name="cancel"
                @click="formQuery.keyword = ''"
                class="cursor-pointer"
              ></q-icon>
            </template>
          </q-input>
        </div>

        <div class="col-auto">
          <q-btn
            outline
            color="primary"
            icon="search"
            label="ค้นหา"
            class="full-width full-height"
            @click="fetchData()"
          />
        </div>
      </div>

      <q-space />
      <div class="row q-col-gutter-sm align-items-center">
        <div class="col-auto">
          <q-select
            v-model="visibleColumns"
            multiple
            outlined
            dense
            options-dense
            :display-value="$q.lang.table.columns"
            emit-value
            map-options
            :options="columns"
            option-value="name"
            style="min-width: 140px"
          />
        </div>
      </div>
    </div>
  </div>

  <div class="full-width q-mt-sm">
    <d-table
      ref="table"
      :columns="columns"
      :rows="rows"
      row-key="id"
      flat
      bordered
      :paging="true"
      dense
      class="custom-header-table"
      :visible-columns="visibleColumns"
    >
      <template v-slot:header="props">
        <q-tr :props="props">
          <q-th auto-width></q-th>
          <q-th
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
            style="color: #000000; font-weight: 500"
          >
            <span class="text-weight-medium">{{ col.label }}</span>
          </q-th>
        </q-tr>
      </template>
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-btn
              color="blue-6"
              flat
              dense
              round
              class="q-mr-xs"
              icon="mdi-content-copy"
              clickable
              @click.stop="
                () => {
                  onClickOpenDialog(false, props.row);
                }
              "
            >
              <q-tooltip>คัดลอกข้อมูล</q-tooltip>
            </q-btn>
            <q-btn
              color="edit"
              flat
              dense
              round
              icon="mdi-pencil"
              clickable
              @click.stop="onClickOpenDialog(true, props.row)"
              v-close-popup
            >
              <q-tooltip>แก้ไขข้อมูล</q-tooltip>
            </q-btn>
            <q-btn
              color="red"
              flat
              dense
              round
              icon="mdi-delete"
              clickable
              @click.stop="deletePos(props.row.id)"
              v-close-popup
            >
              <q-tooltip>ลบข้อมูล</q-tooltip>
            </q-btn>
          </q-td>
          <q-td v-for="col in props.cols" :key="col.name" :props="props">
            <div v-if="col.name == 'no'">
              {{ props.rowIndex + 1 }}
            </div>

            <div v-else>
              {{ col.value ? col.value : "-" }}
            </div>
          </q-td>
        </q-tr>
      </template>
    </d-table>
  </div>

  <q-dialog v-model="modalDialog" class="dialog" persistent>
    <q-card style="width: 350px">
      <q-form greedy @submit.prevent @validation-success="onSubmit">
        <DialogHeader
          :tittle="`${
            isStatusEdit
              ? 'แก้ไขข้อมูลตำแหน่งลูกจ้างประจำ'
              : 'เพิ่มข้อมูลตำแหน่งลูกจ้างประจำ'
          }`"
          :close="closeDialog"
        />
        <q-separator />

        <q-card-section>
          <div class="row q-col-gutter-sm col-12">
            <div class="col-12">
              <q-input
                ref="posNameRef"
                v-model="formDataPos.posName"
                dense
                outlined
                for="#positionName"
                label="ชื่อตำแหน่ง"
                lazy-rules
                hide-bottom-space
                :rules="[(val:string) => !!val || `${'กรุณากรอกชื่อตำแหน่ง'}`]"
                class="inputgreen"
              />
            </div>

            <div class="col-6">
              <q-select
                ref="posTypeNameRef"
                label="กลุ่มงาน"
                v-model="formDataPos.posTypeName"
                :options="posTypeOp"
                emit-value
                dense
                map-options
                outlined
                option-label="name"
                option-value="id"
                lazy-rules
                hide-bottom-space
                :rules="[(val:string) => !!val || `${'กรุณาเลือกกลุ่มงาน'}`]"
                @update:model-value="updatePosTypeName"
                class="inputgreen"
              />
            </div>

            <div class="col-6">
              <q-select
                ref="posLevelNameRef"
                label="ระดับชั้นงาน"
                v-model="formDataPos.posLevelName"
                :disable="formDataPos.posTypeName === ''"
                :options="posLevelOp"
                emit-value
                dense
                map-options
                outlined
                option-label="name"
                option-value="id"
                lazy-rules
                hide-bottom-space
                :rules="[(val:string) => !!val || `${'กรุณาเลือกระดับชั้นงาน'}`]"
                class="inputgreen"
              />
            </div>
          </div>
        </q-card-section>
        <q-separator />
        <q-card-actions align="right">
          <q-btn type="submit" :label="`บันทึก`" color="public" />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>
