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

import { useSalaryEmployeeListSDataStore } from "@/modules/13_salary/store/SalaryEmployeeListsStore";
import { useCounterMixin } from "@/stores/mixin";
import config from "@/app.config";
import http from "@/plugins/http";

/** importType*/
import type {
  DataOption,
  DataOptionShort,
} from "@/modules/13_salary/interface/index/Main";
import type {
  DataRound,
  DataAgency,
  DataPeriodLatest,
} from "@/modules/13_salary/interface/response/SalaryList";

/** importComponents*/
import TabGroup from "@/modules/13_salary/components/05_salaryListsEmployee/TabMain.vue";
import ProcessStep from "@/modules/13_salary/components/05_salaryListsEmployee/ProcessStep.vue";
import PageDashBoard from "@/modules/13_salary/components/05_salaryListsEmployee/Dashboard.vue";
import DialogCommand from "@/modules/18_command/components/DialogCreateCommandORG.vue";

/** use*/
const store = useSalaryEmployeeListSDataStore();
const $q = useQuasar();
const { messageError, showLoader, hideLoader } = useCounterMixin();

/** ตัวแปร*/
const year = ref<number>(new Date().getFullYear()); //ปีงบประมาณ
const roundFilter = ref<any>(); //รอบการขึ้นเงินเดือน
const agencyFilter = ref<string>(""); //หน่วยงาน
const snapFilter = ref<string>(""); //รอบ
const periodLatest = ref<DataPeriodLatest>();
const salaryPeriodId = ref<string>("");

//ตัวเลือก
const roundOptions = ref<DataOptionShort[]>([]); //ตัวเลือกรอบการขึ้นเงินเดือน
const snapOptions = ref<DataOption[]>([]); //รอบ
const agencyOptionsMain = ref<DataOption[]>([]); //ข้อมูลหน่วยงาน
const agencyOptions = ref<DataOption[]>([]); //หน่วยงาน

const isLoad = ref<boolean>(false);
const isDisable = ref<boolean>(false);

/** ตัวแปร select*/
const page = ref<number>(1);
const pageSize = ref<number>(50);
const lastPage = ref<number>(0);
const loading = ref(false);
const nextPage = ref<number>(1);

/** ออกคำสั่ง*/
const modalCommand = ref<boolean>(false);
const isOfficer = ref<boolean>(false);
const isStaff = ref<boolean>(false);
const titleCommand = computed(() => {
  let txt = "";
  switch (roundFilter.value?.shortCode) {
    case "OCT":
      txt = " 1 ตุลาคม";
      break;
    case "APR":
      txt = " 1 เมษายน";
      break;
    case "SPECIAL":
      txt = " รอบพิเศษ";
      break;
  }
  return `ปีงบประมาณ ${year.value + 543} รอบการขึ้นค่าจ้าง${txt}`;
});

/**
 * function เรียกข้อมูลรอบการขึ้นค่าจ้าง
 */
async function getRound() {
  showLoader();
  isDisable.value = false;
  await http
    .get(
      config.API.salaryPeriodActive(year.value.toString()) +
        `?page=${page.value}&pageSize=${pageSize.value}&keyword=&year=0`
    )
    .then(async (res) => {
      roundOptions.value = [];
      roundFilter.value = [];
      const data = res.data.result.data;
      if (data.length !== 0) {
        isDisable.value = true;
        lastPage.value = Math.ceil(res.data.result.total / pageSize.value);
        roundOptions.value = await data.map((x: DataRound) => ({
          id: x.id,
          revisionId: x.revisionId,
          shortCode: x.period,
          isClose: x.isClose,
          year: x.year,
          name:
            x.period === "OCT"
              ? "รอบตุลาคม "
              : x.period === "SPECIAL"
              ? "รอบพิเศษ "
              : "รอบเมษายน ",
        }));

        roundFilter.value = await (roundOptions.value
          ? roundOptions.value[0]
          : "");
        salaryPeriodId.value = roundFilter.value.id;
        store.roundMainCode = roundFilter.value.shortCode;
        store.isClosedRound = roundFilter.value.isClose;

        await getSnap(roundFilter.value.shortCode);
        await getAgency(roundFilter.value.revisionId);
        await getAgencyPosition(roundFilter.value.revisionId);
      } else {
        isLoad.value = false;
        roundFilter.value = "ไม่มีข้อมูล";
        snapFilter.value = "ไม่มีข้อมูล";
        agencyFilter.value = "ไม่มีข้อมูล";
        hideLoader();
      }
    })
    .catch((e) => {
      messageError($q, e);
      hideLoader();
    });
}

/**
 * function เรียกรอบ
 */
async function getSnap(code: string) {
  snapOptions.value =
    code == "OCT"
      ? [
          {
            id: "SNAP1",
            name: "1 กันยายน",
          },
          {
            id: "SNAP2",
            name: "1 ตุลาคม",
          },
        ]
      : code === "APR"
      ? [
          {
            id: "SNAP1",
            name: "1 มีนาคม",
          },
          {
            id: "SNAP2",
            name: "1 เมษายน",
          },
        ]
      : [
          {
            id: "SNAP1",
            name: "พิเศษ 1",
          },
          {
            id: "SNAP2",
            name: "พิเศษ 2",
          },
        ];
  snapFilter.value = snapOptions.value[0].id;
}

/**
 * function เรียกข้อมูลหน่ยวงาน
 * @param id  revisionId
 */
async function getAgency(id: string) {
  id &&
    (await http
      .get(config.API.activeOrganizationRootById(id))
      .then(async (res) => {
        agencyOptions.value = [];
        agencyOptionsMain.value = [];
        const data = res.data.result;
        agencyOptionsMain.value = await [
          {
            id: "ALL",
            name: "ทั้งหมด",
          },
        ].concat(
          data.map((x: DataAgency) => ({
            id: x.id,
            name: x.orgRootName,
          }))
        );
        agencyOptions.value = agencyOptionsMain.value;
      })
      .catch((err) => {
        messageError($q, err);
      }));
}

/**
 * function เรียกข้อมูลหน่ยวงานปจุบัน
 * @param id  revisionId
 */
async function getAgencyPosition(id: string) {
  if (id) {
    await http
      .get(config.API.keycloakPositionByid(id))
      .then(async (res) => {
        const data = await res.data.result;

        store.rootId = data.rootId;
        const position = agencyOptions.value?.find(
          (e: DataOption) => e.id === data.rootId
        );

        agencyFilter.value = position ? position.id : "ALL";

        if (agencyFilter.value && roundFilter.value.id && snapFilter.value) {
          await fetchSalalyPeriod(
            agencyFilter.value,
            roundFilter.value.id,
            snapFilter.value
          );
        }
      })
      .catch((err) => {
        messageError($q, err);
      });
  } else agencyFilter.value = "";
}

/**
 *
 * @param rootId id หน่วยงาน
 * @param periodId id รอบการขึ้นค่าจ้าง
 * @param snap id รอบ
 */
async function fetchSalalyPeriod(
  rootId: string,
  periodId: string,
  snap: string
) {
  if (rootId) {
    isLoad.value = false;
    const body = {
      rootId: rootId,
      salaryPeriodId: periodId,
      snapshot: snap,
    };

    await http
      .post(config.API.salaryListPeriodLatestEmp, body)
      .then(async (res) => {
        const data = res.data.result;
        data && store.fetchPeriodLatest(data, store.tabGroup);
        periodLatest.value = data;
        isLoad.value = data.group1id ? true : false;
      })
      .catch((err) => {
        messageError($q, err);
      });
  }
}

/**
 * function เปลี่ยนรอบการขั้นค่าจ้าง
 */
async function onChangeRound() {
  // เก็บสถานะการปิดรอบในตัวแปร isClosedRound เพื่อใช้ในการเช็ค
  store.isClosedRound = roundFilter.value.isClose;
  salaryPeriodId.value = roundFilter.value.id;
  await getSnap(roundFilter.value.shortCode);
  await getAgency(roundFilter.value.revisionId);
  await getAgencyPosition(roundFilter.value.revisionId);

  if (agencyFilter.value && roundFilter.value.id && snapFilter.value) {
    store.tabType = "PENDING";
    store.roundMainCode = roundFilter.value.shortCode;
  } else {
    isLoad.value = false;
  }
}

/**
 * function เปลี่ยนรอบ
 */
async function onChangeSnap() {
  if (agencyFilter.value && roundFilter.value.id && snapFilter.value) {
    await fetchSalalyPeriod(
      agencyFilter.value,
      roundFilter.value.id,
      snapFilter.value
    );
  }
}

/**
 * function เปลี่ยนหน่วยงาน
 */
async function onChangeAgency() {
  store.rootId = agencyFilter.value;

  if (
    agencyFilter.value !== "ALL" &&
    roundFilter.value.id &&
    snapFilter.value
  ) {
    await fetchSalalyPeriod(
      agencyFilter.value,
      roundFilter.value.id,
      snapFilter.value
    );
  }
}

/**
 * function onScrollSelect รอบการขึ้นค่าจ้าง
 */
function onScroll({ to, ref }: { to: number; ref: any }) {
  const lastIndex = roundOptions.value.length - 1;

  if (
    loading.value !== true &&
    nextPage.value < lastPage.value &&
    to === lastIndex
  ) {
    loading.value = true;

    setTimeout(() => {
      nextPage.value++;
      page.value = nextPage.value;
      getRound();
      nextTick(() => {
        ref.refresh();
        loading.value = false;
      });
    }, 500);
  }
}

/**
 *  function fetch PeriodQuota
 */
function getQuota() {
  fetchSalalyPeriod(agencyFilter.value, roundFilter.value.id, snapFilter.value);
}

/**
 * functioon ค้นหาข้อมูลรายการหน่วยงาน
 * @param val คำค้นหา
 * @param update function
 * @param refData typeSelector
 */
function filterSelector(val: string, update: Function, refData: string) {
  switch (refData) {
    case "agencyFilter":
      update(() => {
        agencyOptions.value = agencyOptionsMain.value.filter(
          (v: DataOption) => v.name.indexOf(val) > -1
        );
      });

    default:
      break;
  }
}

async function fetchCheckisOfficer() {
  http
    .get(config.API.workflowKeycloakSystem(`SYS_WAGE`))
    .then((res) => {
      const data = res.data.result;
      isOfficer.value = data.isOfficer;
      isStaff.value = data.isStaff;
    })
    .catch((e) => {
      messageError($q, e);
    });
}

onMounted(async () => {
  await Promise.all([getRound(), fetchCheckisOfficer()]);
});
</script>

<template>
  <div class="row items-center">
    <div class="toptitle text-dark row items-center q-py-xs">
      รายการเลื่อนค่าจ้างลูกจ้างประจำ
    </div>
  </div>

  <div class="row items-center">
    <q-space />
    <div class="row q-col-gutter-sm items-center q-py-xs">
      <div v-if="isOfficer || isStaff">
        <q-btn
          flat
          round
          dense
          color="add"
          icon="mdi-account-arrow-right"
          @click.pervent="modalCommand = true"
        >
          <q-tooltip>ส่งไปออกคำสั่ง</q-tooltip>
        </q-btn>
      </div>
      <datepicker
        menu-class-name="modalfix"
        v-model="year"
        :locale="'th'"
        autoApply
        year-picker
        :enableTimePicker="false"
        style="width: 150px"
        @update:model-value="getRound"
      >
        <template #year="{ year }">{{ year + 543 }}</template>
        <template #year-overlay-value="{ value }">{{
          parseInt(value + 543)
        }}</template>
        <template #trigger>
          <q-input
            dense
            outlined
            :model-value="Number(year) + 543"
            :label="`${'ปีงบประมาณ'}`"
            bg-color="white"
          >
            <template v-slot:prepend>
              <q-icon
                name="event"
                class="cursor-pointer"
                style="color: var(--q-primary)"
              >
              </q-icon>
            </template>
          </q-input>
        </template>
      </datepicker>

      <q-select
        v-model="roundFilter"
        label="รอบการขึ้นค่าจ้าง"
        dense
        outlined
        map-options
        option-label="name"
        option-value="id"
        :options="roundOptions"
        lazy-rules
        hide-bottom-space
        bg-color="white"
        @update:model-value="onChangeRound"
        :loading="loading"
        @virtual-scroll="onScroll"
        :disable="!isDisable"
      >
        <template v-slot:option="scope">
          <q-item v-bind="scope.itemProps">
            <q-item-section>
              <q-item-label>{{ scope.opt.name }}</q-item-label>
            </q-item-section>
          </q-item>
        </template>
      </q-select>
      <q-select
        v-if="roundFilter ? roundFilter.shortCode !== 'SPECIAL' : false"
        v-model="snapFilter"
        label="ราชชื่อรอบ"
        dense
        outlined
        emit-value
        map-options
        option-label="name"
        option-value="id"
        :options="snapOptions"
        lazy-rules
        hide-bottom-space
        bg-color="white"
        @update:model-value="onChangeSnap"
        :disable="!isDisable"
      />
      <q-select
        v-model="agencyFilter"
        label="หน่วยงาน"
        dense
        outlined
        emit-value
        map-options
        option-label="name"
        option-value="id"
        hide-selected
        fill-input
        :options="agencyOptions"
        lazy-rules
        hide-bottom-space
        bg-color="white"
        @update:model-value="onChangeAgency"
        :disable="!isDisable"
        use-input
        @filter="(inputValue:string,
      doneFn:Function) => filterSelector(inputValue, doneFn,'agencyFilter'
      ) "
      >
        <template v-if="agencyFilter !== 'ALL'" v-slot:append>
          <q-icon
            name="cancel"
            @click.stop.prevent="
              (agencyOptions = agencyOptionsMain), (agencyFilter = 'ALL')
            "
            class="cursor-pointer"
          /> </template
      ></q-select>
    </div>
  </div>

  <q-card flat bordered>
    <div v-if="agencyFilter !== 'ALL'">
      <TabGroup
        v-if="isLoad"
        :period-latest="periodLatest"
        :period-id="roundFilter.id"
        :root-id="agencyFilter"
        :round-filter="roundFilter"
      />
      <q-card v-else class="q-pa-sm">
        <div class="q-pa-sm">
          <q-banner inline-actions rounded class="bg-grey-1 text-center">
            ไม่มีข้อมูล
          </q-banner>
        </div>
      </q-card>
    </div>
    <div v-else>
      <PageDashBoard
        :year="year"
        :snap-shot="snapFilter"
        :round-filter="roundFilter"
      />
    </div>
  </q-card>

  <q-card
    v-if="isLoad && !store.isClosedRound"
    flat
    bordered
    class="row col-12 q-mt-xs"
  >
    <ProcessStep
      v-if="agencyFilter !== 'ALL'"
      :period-id="roundFilter.id"
      :root-id="agencyFilter"
      :get-data="getQuota"
    />
  </q-card>

  <DialogCommand
    v-model:modal="modalCommand"
    v-model:root-id="agencyFilter"
    v-model:is-officer="isOfficer"
    v-model:is-staff="isStaff"
    system-name="SALARY_EMP"
    :command-type-code-array="['C-PM-36', 'C-PM-37']"
    :salary-period-id="salaryPeriodId"
    :title-command="titleCommand"
  />
</template>

<style lang="sass" scoped>
.my-card
  width: 100%
  max-width: 200px
</style>
