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

import { checkPermission } from "@/utils/permissions";
import { useRoute } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { useProfileDataStore } from "@/modules/04_registryPerson/stores/profile";
import { calculateAge } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";

/** importType*/
import type { QTableColumn } from "quasar";
import type { RequestObject } from "@/modules/04_registryPerson/interface/request/Profile";
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/Profile";

/** importComponents*/
import DialogHeader from "@/components/DialogHeader.vue";
import DialogHistory from "@/modules/04_registryPerson/components/detail/DialogHistory.vue";

/** use*/
const $q = useQuasar();
const route = useRoute();
const store = useProfileDataStore();
const { fetchPerson, filterSelector } = store;
const {
  success,
  showLoader,
  hideLoader,
  date2Thai,
  messageError,
  dialogConfirm,
  dialogMessageNotify,
  convertDateToAPI,
} = useCounterMixin();

/** props*/
const isLeave = defineModel<boolean>("isLeave", {
  required: true,
});
const props = defineProps({
  fetchDataPersonal: { type: Function, require: true },
});

const profileId = ref<string>(
  route.params.id ? route.params.id.toString() : ""
);
const empType = ref<string>(
  route.name === "registryNewByid"
    ? ""
    : route.name === "registry-employeeId"
    ? "-temp"
    : "-employee"
);

const id = ref<string>("");
const modal = ref<boolean>(false); // แสดงฟอร์มแก้ไขประวัติส่วนตัว
const informaData = ref<ResponseObject>(); // ข้อมูลส่วนคัว
const modalHistory = ref<boolean>(false); // แสดงช้อมูลรายการประวัติการแก้ไข
const age = ref<string | null>(""); //อายุ
const formData = reactive<RequestObject>(store.defaultProfile); //ฟอร์มข้อมูลการแก้ไข
const emailVerify = ref<string | null>("");

/** ข้อมูล Label*/
const dataLabel = {
  citizenId: "เลขประจำตัวประชาชน",
  name: "ชื่อ - สกุล",
  birthDate: "วัน/เดือน/ปีเกิด",
  age: "อายุ",
  gender: "เพศ",
  relationship: "สถานภาพ",
  nationality: "สัญชาติ",
  ethnicity: "เชื้อชาติ",
  religion: "ศาสนา",
  bloodGroup: "หมู่เลือด",
  phone: "เบอร์โทร",
  email: "อีเมล",
  prefix: "คำนำหน้าชื่อ",
  rank: "ยศ",
  firstName: "ชื่อ",
  lastName: "นามสกุล",
};

/** ข้อมูล Table ประวัติแการก้ไขข้อมูลส่วนตัว*/
const columnsHistory = ref<QTableColumn[]>([
  {
    name: "citizenId",
    align: "left",
    label: "เลขประจำตัวประชาชน",
    sortable: true,
    field: "citizenId",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "prefix",
    align: "left",
    label: "คำนำหน้าชื่อ",
    sortable: true,
    field: "prefix",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "rank",
    align: "left",
    label: "ยศ",
    sortable: true,
    field: "rank",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "firstName",
    align: "left",
    label: "ชื่อ",
    sortable: true,
    field: "firstName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastName",
    align: "left",
    label: "นามสกุล",
    sortable: true,
    field: "lastName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "birthDate",
    align: "left",
    label: "วัน/เดือน/ปี เกิด",
    sortable: true,
    field: "birthDate",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    format: (v) => {
      return v ? date2Thai(v) : "";
    },
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "gender",
    align: "left",
    label: "เพศ",
    sortable: true,
    field: "gender",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "relationship",
    align: "left",
    label: "สถานภาพ",
    sortable: true,
    field: "relationship",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "bloodGroup",
    align: "left",
    label: "หมู่เลือด",
    sortable: true,
    field: "bloodGroup",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "nationality",
    align: "left",
    label: "สัญชาติ",
    sortable: true,
    field: "nationality",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "ethnicity",
    align: "left",
    label: "เชื้อชาติ",
    sortable: true,
    field: "ethnicity",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "religion",
    align: "left",
    label: "ศาสนา",
    sortable: true,
    field: "religion",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "phone",
    align: "left",
    label: "เบอร์โทร",
    sortable: true,
    field: "phone",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdateFullName",
    align: "left",
    label: "ผู้ดำเนินการ",
    sortable: true,
    field: "lastUpdateFullName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdatedAt",
    align: "left",
    label: "วันที่แก้ไข",
    sortable: true,
    field: "lastUpdatedAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    format: (v) => date2Thai(v, false, true),
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
]);
const visibleColumnsHistory = ref<string[]>([
  "citizenId",
  "prefix",
  "rank",
  "firstName",
  "lastName",
  "birthDate",
  "gender",
  "relationship",
  "bloodGroup",
  "nationality",
  "ethnicity",
  "religion",
  "phone",
  "lastUpdateFullName",
  "lastUpdatedAt",
]);

/** function เรียกข้อมูลข้อมูลส่วนตัว*/
async function getData() {
  showLoader();
  await http
    .get(config.API.registryNewByProfileId(profileId.value, empType.value))
    .then((res) => {
      informaData.value = res.data.result;
      id.value = res.data.result.id;
      emailVerify.value = res.data.result.statusEmail;
      if (res.data.result.birthDate) {
        // กำหนดอายุ ส่งวันเกิดไปคำนวน
        age.value = calculateAge(res.data.result.birthDate);
      } else {
        age.value = null;
      }
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {
      hideLoader();
    });
}

/** function แก้ไขข้อมูลประวัติส่วนตัว*/
function onClickOpenDialog() {
  if (!informaData.value) return;
  modal.value = true;

  id.value = informaData.value.id;
  age.value = calculateAge(informaData.value.birthDate);
  formData.citizenId = informaData.value.citizenId;
  formData.prefix = informaData.value.prefixMain;
  formData.rank = informaData.value.rank;
  formData.firstName = informaData.value.firstName;
  formData.lastName = informaData.value.lastName;
  formData.birthDate = informaData.value.birthDate;
  formData.gender = informaData.value.gender;
  formData.relationship = informaData.value.relationship;
  formData.nationality = informaData.value.nationality;
  formData.ethnicity = informaData.value.ethnicity;
  formData.religion = informaData.value.religion;
  formData.bloodGroup = informaData.value.bloodGroup;
  formData.phone = informaData.value.phone;
}

/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
  dialogConfirm(
    $q,
    async () => {
      showLoader();
      http
        .put(config.API.profileNewProfileById(id.value, empType.value), {
          ...formData,
          employeeClass:
            route.name === "registry-employeeId" ? "TEMP" : undefined,
          birthDate: convertDateToAPI(formData.birthDate),
        })
        .then(async () => {
          await props.fetchDataPersonal?.();
          await getData();
          await success($q, "บันทึกข้อมูลสำเร็จ");
          modal.value = false;
        })
        .catch((e) => {
          messageError($q, e);
        })
        .finally(() => {
          hideLoader();
        });
    },
    "ยืนยันการบันทึกข้อมูล",
    "ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
  );
}

/** function ดูข้อมูลประวัติแก้ไขข้อมูลส่วนตัว*/
async function clickHistory() {
  modalHistory.value = true;
}

async function fetchDataHistory() {
  showLoader();
  try {
    const res = await http.get(
      config.API.profileNewProfileHisById(id.value, empType.value)
    );
    const data = await res.data.result;
    return data;
  } catch (e) {
    messageError($q, e);
  } finally {
    hideLoader();
  }
}

/**
 * function  เช็คเลขประจำตัวประชาชนช้ำ
 * @param citizenId เลขประจำตัวประชาชน
 */
function changeCardID(citizenId: string | number | null) {
  if (citizenId != null && typeof citizenId == "string") {
    if (citizenId.length == 13 && citizenId) {
      http
        .put(config.API.profileNewCitizenId(profileId.value), {
          citizenId: citizenId,
        })
        .then(() => {})
        .catch((err) => {
          if (err.response.data.status === 500) {
            dialogMessageNotify($q, err.response.data.message);
          } else {
            messageError($q, err);
          }
        });
    }
  }
}

/** function เช็คอายุไม่เกิน 18 ปี*/
function calculateMaxDate() {
  const today = new Date();
  today.setFullYear(today.getFullYear() - 18);
  return today;
}

/** function เช็คอายุไม่เกิน 60 ปี*/
function calculateMinDate() {
  const today = new Date();
  today.setFullYear(today.getFullYear() - 60); // ลดปีลงไป 60 ปี
  return today;
}

function prefixRankRule() {
  return [
    () => !!formData.rank || !!formData.prefix || "กรุณาเลือกคำนำหน้าชื่อ หรือยศ",
  ];
}

/** ดูการเปลี่ยนแปลงของวันเกิดเมื่อมีการเปลี่ยนแปลงจะคำนวนอายูใหม่*/
watch(
  () => formData.birthDate,
  (v) => {
    if (v) {
      age.value = calculateAge(v);
    }
  }
);

/** ทำงานเมื่อ Components ถูกเรียกใช้งาน*/
onMounted(() => {
  const promises = [];

  // Add the getData() promise
  promises.push(getData());

  // Check the condition and add fetchPerson() if needed
  if (store.Ops && store.Ops.prefixOps && store.Ops.prefixOps.length === 0) {
    promises.push(fetchPerson());
  }

  Promise.all(promises);
});
</script>

<template>
  <div class="row q-gutter-sm items-center">
    <div class="toptitle col text-right">
      <q-btn
        v-if="!isLeave && checkPermission($route)?.attrIsUpdate"
        flat
        round
        dense
        icon="edit"
        color="edit"
        @click="onClickOpenDialog"
      >
        <q-tooltip>แก้ไขข้อมูล</q-tooltip>
      </q-btn>
      <q-btn
        dense
        flat
        round
        icon="mdi-history"
        color="deep-purple"
        @click="clickHistory"
      >
        <q-tooltip>ประวัติแก้ไขข้อมูลส่วนตัว</q-tooltip>
      </q-btn>
    </div>
  </div>

  <q-card bordered class="my-card bg-grey-1 q-pa-md">
    <div v-if="informaData" :class="$q.screen.gt.xs ? 'row' : 'column'">
      <!-- column 1 -->
      <div class="col-md-7 col-12 row">
        <div class="col-5 text-grey-6 text-weight-medium">
          <div
            v-for="label in Object.keys(dataLabel).slice(0, 6)"
            class="q-py-xs"
          >
            {{ dataLabel[label as keyof typeof dataLabel] }}
          </div>
        </div>
        <!-- data -->
        <div class="col-7">
          <div class="q-py-xs">
            {{ informaData.citizenId }}
          </div>
          <div class="q-py-xs">
            {{
              `${
                informaData.prefix == "ไม่ระบุคำนำหน้าชื่อ"
                  ? ""
                  : informaData.prefix ?? ""
              }${informaData.firstName} ${informaData.lastName}`
            }}
          </div>
          <div class="q-py-xs">
            {{ informaData.birthDate ? date2Thai(informaData.birthDate) : "" }}
          </div>
          <div class="q-py-xs">
            {{ age ? age : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.gender ? informaData.gender : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.relationship ? informaData.relationship : "-" }}
          </div>
        </div>
      </div>

      <!-- column 2 -->
      <div class="col-md-5 col-12 row">
        <div class="col-5 col text-grey-6 text-weight-medium">
          <div
            v-for="label in Object.keys(dataLabel).slice(6, 12)"
            class="q-py-xs"
          >
            {{ dataLabel[label as keyof typeof dataLabel] }}
          </div>
        </div>
        <!-- data -->
        <div class="col-7">
          <div class="q-py-xs">
            {{ informaData.nationality ? informaData.nationality : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.ethnicity ? informaData.ethnicity : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.religion ? informaData.religion : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.bloodGroup ? informaData.bloodGroup : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.phone ? informaData.phone : "-" }}
          </div>
          <div class="q-py-xs">
            {{ informaData.email ? informaData.email : "-"
            }}<q-icon
              v-if="emailVerify == 'NOT_VERIFIED'"
              name="mdi-alert-box"
              color="warning"
              size="sm"
              ><q-tooltip>รอยืนยันอีเมล</q-tooltip></q-icon
            >
          </div>
        </div>
      </div>
    </div>
  </q-card>

  <!-- แก้ไขประวัติส่วนตัว -->
  <q-dialog v-model="modal" persistent>
    <q-card>
      <q-form greedy @submit.prevent @validation-success="onSubmit">
        <DialogHeader
          tittle="แก้ไขประวัติส่วนตัว"
          :close="() => (modal = false)"
        />

        <q-separator />
        <q-card-section>
          <div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                maxlength="13"
                mask="#############"
                v-model="formData.citizenId"
                :class="
                  checkPermission($route)?.attrOwnership !== 'OWNER'
                    ? ''
                    : 'inputgreen'
                "
                :label="dataLabel.citizenId"
                :rules="[
                (val: string) => !!val || `${'กรุณากรอก เลขประจำตัวประชาชน'}`,
                (val: string) =>
                  val.length >= 13 ||
                  `${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,
              ]"
                @update:model-value="changeCardID"
                :readonly="checkPermission($route)?.attrOwnership !== 'OWNER'"
              />
            </div>

            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                use-input
                hide-selected
                fill-input
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                input-debounce="0"
                option-label="name"
                option-value="name"
                v-model="formData.prefix"
                clearable
                class="inputgreen"
                :options="store.Ops.prefixOps"
                :label="dataLabel.prefix"
                :rules="prefixRankRule()"
                reactive-rules
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'prefixOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                clearable
                use-input
                hide-selected
                fill-input
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                input-debounce="0"
                option-label="name"
                option-value="name"
                :rules="prefixRankRule()"
                reactive-rules
                v-model="formData.rank"
                class="inputgreen"
                :options="store.Ops.rankOps"
                :label="dataLabel.rank"
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'rankOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                v-model="formData.firstName"
                class="inputgreen"
                :label="dataLabel.firstName"
                :rules="[(val: string) => !!val || `${'กรุณากรอก ชื่อ'}`]"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                v-model="formData.lastName"
                class="inputgreen"
                :label="dataLabel.lastName"
                :rules="[(val: string) => !!val || `${'กรุณากรอก นามสกุล'}`]"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <datepicker
                autoApply
                :max-date="calculateMaxDate()"
                :min-date="calculateMinDate()"
                borderless
                :enableTimePicker="false"
                week-start="0"
                menu-class-name="modalfix"
                v-model="formData.birthDate"
                :locale="'th'"
              >
                <template #year="{ year }">
                  {{ year + 543 }}
                </template>
                <template #year-overlay-value="{ value }">
                  {{ parseInt(value + 543) }}
                </template>
                <template #trigger>
                  <q-input
                    for="inputDatereceive"
                    ref="dateReceivedRef"
                    outlined
                    dense
                    hide-bottom-space
                    class="inputgreen"
                    :model-value="
                      formData.birthDate ? date2Thai(formData.birthDate) : null
                    "
                    :label="dataLabel.birthDate"
                    :rules="[
                      (val:string) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`,
                    ]"
                  >
                    <template v-slot:prepend>
                      <q-icon
                        name="event"
                        class="cursor-pointer"
                        color="primary"
                      >
                      </q-icon>
                    </template>
                  </q-input>
                </template>
              </datepicker>
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                readonly
                v-model="age"
                :label="dataLabel.age"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                use-input
                hide-selected
                fill-input
                clearable
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                input-debounce="0"
                option-label="name"
                option-value="name"
                v-model="formData.gender"
                class="inputgreen"
                :options="store.Ops.genderOps"
                :label="dataLabel.gender"
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'genderOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                use-input
                hide-selected
                fill-input
                clearable
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                option-value="name"
                option-label="name"
                input-debounce="0"
                class="inputgreen"
                v-model="formData.relationship"
                :options="store.Ops.statusOps"
                :label="dataLabel.relationship"
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'statusOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                class="inputgreen"
                v-model="formData.nationality"
                :label="dataLabel.nationality"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                class="inputgreen"
                v-model="formData.ethnicity"
                :label="dataLabel.ethnicity"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                use-input
                hide-selected
                fill-input
                clearable
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                option-value="name"
                option-label="name"
                input-debounce="0"
                v-model="formData.religion"
                class="inputgreen"
                :options="store.Ops.religionOps"
                :label="dataLabel.religion"
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'religionOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-select
                dense
                outlined
                use-input
                hide-selected
                fill-input
                clearable
                lazy-rules
                emit-value
                map-options
                hide-bottom-space
                option-value="name"
                option-label="name"
                input-debounce="0"
                v-model="formData.bloodGroup"
                class="inputgreen"
                :options="store.Ops.bloodOps"
                :label="dataLabel.bloodGroup"
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'bloodOps'
              )"
              />
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6">
              <q-input
                dense
                outlined
                lazy-rules
                hide-bottom-space
                mask="##########"
                class="inputgreen"
                v-model="formData.phone"
                :label="dataLabel.phone"
              />
            </div>
          </div>
        </q-card-section>

        <q-separator />

        <q-card-actions align="right">
          <q-btn
            label="บันทึก"
            id="onSubmit"
            type="submit"
            color="public"
            class="q-px-md"
          >
            <q-tooltip>บันทึกข้อมูล</q-tooltip>
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>

  <DialogHistory
    v-model:modal="modalHistory"
    :visible-columns="visibleColumnsHistory"
    :title="`ประวัติแก้ไขข้อมูลส่วนตัว`"
    :columns="columnsHistory"
    :fetch-data="fetchDataHistory"
  />
</template>

<style lang="scss">
.modalfix {
  position: fixed !important;
}
</style>
