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

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

/** importType*/
import type { QTableProps } from "quasar";
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
import type { ResponseObject } from "@/components/information/interface/response/OldName";
import type { DataProfile } from "@/modules/04_registryPerson/interface/response/Main";
import type { FormChangeName } from "@/modules/04_registryPerson/interface/request/Main";

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

/** use*/
const $q = useQuasar();
const route = useRoute();
const store = useProfileDataStore();

const { fetchPerson } = store;
const {
  date2Thai,
  success,
  dialogConfirm,
  messageError,
  showLoader,
  hideLoader,
  pathRegistryEmp,
  onSearchDataTable,
  dialogRemove,
} = useCounterMixin();

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

const profileId = ref<string>(route.params.id.toString()); //id Profile
const empType = ref<string>(pathRegistryEmp(route.name?.toString() ?? "")); // ประเภทข้าราชการ

const submitDisable = ref<boolean>(true); //แเสดงปุ่มบันทึก
const editId = ref<string>("");
const dialog = ref<boolean>(false); // แสดง popup เปลี่ยนชื่อ-นามสกุล
const dialogStatus = ref<string>("create"); // สถานะแก้ไข สร้าง
const filterSearch = ref<string>(""); // คำค้นหา
// ฟอร์มการเปลี่ยนชื่อ
const changeNameData = reactive<FormChangeName>({
  profileId: profileId.value,
  prefixId: "", // id คำนำหน้า
  prefix: "", // คำนำหน้า
  firstName: "", // ชื่อ
  lastName: "", // นามสกุล
  status: "", // สถานะ
  documentId: "", // ไฟล์หลักฐาน
});

const selection = ref<string[]>([]); // ตัวเลือก
const prefixChange = ref<string | null | undefined>(""); // เปลี่ยนคำนำหน้า
const firstNameChange = ref<string | null | undefined>(""); // เปลียนชื่อ
const lastNameChange = ref<string | null | undefined>(""); // เปลี่ยนนามสกุล

const profileInfo = ref<DataProfile>(); // ข้อมูล Profile

const statusOption = ref<string[]>([
  "เปลี่ยนคำนำหน้าชื่อ",
  "เปลี่ยนชื่อ",
  "เปลี่ยนนามสกุล",
  "เปลี่ยนชื่อ-นามสกุล",
  "เปลี่ยนคำนำหน้าชื่อ และชื่อ",
  "เปลี่ยนคำนำหน้าชื่อ และนามสกุล",
  "เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล",
]);
const statusOptionFilter = ref<string[]>([
  "เปลี่ยนคำนำหน้าชื่อ",
  "เปลี่ยนชื่อ",
  "เปลี่ยนนามสกุล",
  "เปลี่ยนชื่อ-นามสกุล",
  "เปลี่ยนคำนำหน้าชื่อ และชื่อ",
  "เปลี่ยนคำนำหน้าชื่อ และนามสกุล",
  "เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล",
]);
const alertUpload = ref<boolean>(false);

// Table
const rows = ref<ResponseObject[]>([]);
const rowsMain = ref<ResponseObject[]>([]);
const columns = ref<QTableProps["columns"]>([
  {
    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: "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: "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",
    format: (v) => date2Thai(v, false, true),
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
]);
const visibleColumns = ref<string[]>([
  "prefix",
  "firstName",
  "lastName",
  "lastUpdateFullName",
  "lastUpdatedAt",
]);
const pagination = ref({
  sortBy: "lastUpdatedAt",
});

const uploadUrl = ref<string>("");
const subId = ref<string>("");
const fileUpload = ref<File | undefined>(undefined);

/** ฟังก์ชันดึงข้อมูลส่วนตัว*/
async function fetchDataPersonal() {
  await http
    .get(config.API.registryNewByProfileId(profileId.value, empType.value))
    .then(async (res) => {
      const data = await res.data.result;
      profileInfo.value = data;
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/**
 * ฟังก์ชันดึงข้อมูลรายการประวัติการเปลี่ยนชื่อ-นามสกุล
 * @param id id profile
 */
async function fetchData(id: string) {
  await http
    .get(config.API.profileNewChangeNameByProfileId(id, empType.value))
    .then(async (res) => {
      rowsMain.value = await res.data.result;
      searchDataTable();
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/** ฟังก์ชันยืนยันการบันทึกข้อมูล*/
function onSubmit() {
  if (!!fileUpload.value) {
    dialogConfirm(
      $q,
      async () => {
        showLoader();
        await http
          .post(config.API.profileNewChangeName(empType.value), {
            profileId: empType.value === "" ? profileId.value : undefined,
            profileEmployeeId:
              empType.value !== "" ? profileId.value : undefined,
            prefixId: changeNameData.prefixId,
            prefix: changeNameData.prefix,
            firstName: changeNameData.firstName,
            lastName: changeNameData.lastName,
            status: changeNameData.status,
            documentId: changeNameData.documentId,
          })
          .then(async (res) => {
            subId.value = await res.data.result;
            await Promise.all([
              uploadProfile(res.data.result),
              fetchData(profileId.value),
              props?.fetchDataPersonal?.(),
              fetchDataPersonal(),
            ]);

            closeDialog();
            success($q, "บันทึกข้อมูลสำเร็จ");
          })
          .catch((err) => {
            messageError($q, err);
          })
          .finally(() => {
            hideLoader();
          });
      },
      "ยืนยันการบันทึกข้อมูล",
      "ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
    );
  }
}

/**
 * ฟังก์ชันส้ราง Path อัปโหลดไฟล์
 * @param id
 */
async function uploadProfile(id: string) {
  await http
    .post(
      config.API.subFile(
        "ทะเบียนประวัติ",
        "ประวัติการเปลี่ยนชื่อ-นามสกุล",
        profileId.value,
        id
      ),
      {
        replace: true,
        fileList: [
          {
            fileName: "เอกสารหลักฐาน",
          },
        ],
      }
    )
    .then(async (res) => {
      uploadUrl.value = res.data["เอกสารหลักฐาน"].uploadUrl;
      await uploadFileURL(uploadUrl.value, fileUpload.value as File);
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/**
 * ฟังก์ชันอัปโหลดำไฟล์
 * @param uploadUrl Path อัปโหลดไฟล์
 * @param file ไฟล์เอกสาร
 */
async function uploadFileURL(uploadUrl: string, file: File) {
  await axios
    .put(uploadUrl, file, {
      headers: {
        "Content-Type": file.type,
      },
    })
    .then(() => {
      fileUpload.value = undefined;
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/**
 * ฟังก์ชันโหลไฟลเอกสารหลักฐาน
 * @param id รายการที่ต้องการโหลด
 */
async function onDownloadFile(id: string) {
  showLoader();
  await http
    .get(
      config.API.subFileByFileName(
        "ทะเบียนประวัติ",
        "ประวัติการเปลี่ยนชื่อ-นามสกุล",
        profileId.value,
        id,
        "เอกสารหลักฐาน"
      )
    )
    .then(async (res) => {
      const data = res.data.downloadUrl;
      window.open(data, "_blank");
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/** ฟังกชันเพิ่มการเปลี่ยนชื่อ - นามสกุล */
async function addData() {}

/**
 * ฟังกชันค้นหาข้อมูลใน select
 * @param val  คำที่ต้องการค้นหา
 * @param update function
 * @param refData ประเภทตัวเลือก
 */
function filterSelector(val: string, update: Function, refData: string) {
  switch (refData) {
    case "statusOptions":
      update(() => {
        statusOption.value = statusOptionFilter.value.filter(
          (v: string) => v.indexOf(val) > -1
        );
      });
      break;
    case "prefixOps":
      update(() => {
        store.Ops.prefixOps = store.OpsFilter.prefixOps.filter(
          (v: DataOption) => v.name.indexOf(val) > -1
        );
      });
      break;
    default:
      break;
  }
}

/** ฟังก์ชันปิด popup เปลี่ยนชื่อ-นามสกุล*/
function closeDialog() {
  selection.value = [];
  alertUpload.value = false;
  dialog.value = false;
}

/** ฟังก์ค้นหาข้อมูลรายการประวัติการเปลีียนชื่อ-นามสกุล*/
function searchDataTable() {
  rows.value = onSearchDataTable(
    filterSearch.value,
    rowsMain.value,
    columns.value ? columns.value : []
  );
}

function handleDelete(id: string) {
  dialogRemove($q, async () => {
    showLoader();
    try {
      await http.patch(
        config.API.profileNewChangeNameUpdateDelete(empType.value) + `${id}`
      );
      await fetchData(profileId.value);
      success($q, "ลบข้อมูลสำเร็จ");
    } catch (err) {
      messageError($q, err);
    } finally {
      hideLoader();
    }
  });
}

/** ดูการเปลี่ยนแปลงของข้อมูลฟอร์ท เปลี่ยนชื่อ-นามสกุล*/
watch(
  () => [
    changeNameData.prefix,
    changeNameData.firstName,
    changeNameData.lastName,
  ],
  () => {
    submitDisable.value =
      changeNameData.prefix === prefixChange.value &&
      changeNameData.firstName === firstNameChange.value &&
      changeNameData.lastName === lastNameChange.value;
  }
);

watch(
  () => selection.value,
  () => {
    if (!selection.value.includes("prefix")) {
      changeNameData.prefix = prefixChange.value;
    }
    if (!selection.value.includes("firstname")) {
      changeNameData.firstName = firstNameChange.value;
    }
    if (!selection.value.includes("lastname")) {
      changeNameData.lastName = lastNameChange.value;
    }
  }
);
/** ทำงานเมื่อ Components ถูกเรียกใช้งาน*/
onMounted(async () => {
  // เช็ค ตัวเลือก ถ้าไม่มีให้ ดึงข้อมูลใหท่
  showLoader();
  if (
    store.Ops.prefixOps.length === 0 ||
    store.Ops.genderOps.length === 0 ||
    store.Ops.bloodOps.length === 0 ||
    store.Ops.statusOps.length === 0 ||
    store.Ops.religionOps.length === 0
  ) {
    await fetchPerson();
  }
  try {
    await Promise.all([fetchData(profileId.value), fetchDataPersonal()]);
  } finally {
    hideLoader();
  }
});
</script>

<template>
  <div class="row items-center q-gutter-x-sm q-pb-sm">
    <q-btn
      v-if="isLeave == false && checkPermission($route)?.attrIsUpdate"
      round
      flat
      color="primary"
      dense
      icon="add"
      @click="
        () => {
          changeNameData.prefix = profileInfo?.prefixMain;
          changeNameData.firstName = profileInfo?.firstName;
          changeNameData.lastName = profileInfo?.lastName;
          prefixChange = changeNameData.prefix;
          firstNameChange = changeNameData.firstName;
          lastNameChange = changeNameData.lastName;
          changeNameData.status = '';
          dialogStatus = 'create';
          submitDisable = true;
          dialog = true;
        }
      "
    >
      <q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
    >

    <q-space />
    <q-input
      dense
      outlined
      label="ค้นหา"
      class="q-mr-sm"
      v-model="filterSearch"
      @keydown.enter.prevent="searchDataTable"
    >
      <template v-slot:append>
        <q-icon name="search" />
      </template>
    </q-input>

    <q-select
      dense
      multiple
      outlined
      emit-value
      map-options
      options-dense
      option-value="name"
      style="min-width: 140px"
      v-model="visibleColumns"
      :options="columns"
      :display-value="$q.lang.table.columns"
    />
  </div>

  <d-table
    flat
    dense
    bordered
    virtual-scroll
    ref="table"
    :rows="rows"
    :columns="columns"
    :visible-columns="visibleColumns"
    :virtual-scroll-sticky-size-start="48"
    v-model:pagination="pagination"
  >
    <template v-slot:header="props">
      <q-tr :props="props">
        <q-th auto-width />
        <q-th v-for="col in props.cols" :key="col.name" :props="props">
          <span class="text-weight-medium">{{ col.label }}</span>
        </q-th>
        <q-th auto-width />
      </q-tr>
    </template>

    <template v-slot:body="props">
      <q-tr :props="props">
        <q-td auto-width>
          <q-btn
            v-if="checkPermission($route)?.attrIsDelete"
            color="red"
            flat
            dense
            round
            icon="delete"
            @click="handleDelete(props.row.id)"
          >
            <q-tooltip>ลบข้อมูล</q-tooltip>
          </q-btn>
        </q-td>
        <q-td
          v-for="(col, index) in props.cols"
          :key="col.name"
          :class="props.row.isEntry ? 'text-grey' : ''"
        >
          <div class="table_ellipsis">
            {{ col.value }}
          </div>
        </q-td>

        <q-td auto-width>
          <q-btn
            v-if="props.row.documentId !== null"
            color="green"
            flat
            dense
            round
            icon="mdi-file-document-outline"
            @click="onDownloadFile(props.row.id)"
          >
            <q-tooltip>ดาวน์โหลด</q-tooltip>
          </q-btn>
        </q-td>
      </q-tr>
    </template>
  </d-table>

  <q-dialog v-model="dialog" persistent>
    <q-card>
      <q-form @submit.prevent greedy @validation-success="onSubmit()">
        <DialogHeader tittle="เปลี่ยนชื่อ - นามสกุล" :close="closeDialog" />
        <q-separator />
        <q-card-section>
          <div class="row q-mb-sm">
            <div class="col-12">
              <div class="row">
                <div class="q-gutter-sm">
                  <q-checkbox
                    v-model="selection"
                    val="prefix"
                    label="เปลี่ยนคำนำหน้าชื่อ"
                  />
                  <q-checkbox
                    v-model="selection"
                    val="firstname"
                    label="เปลี่ยนชื่อ"
                  />
                  <q-checkbox
                    v-model="selection"
                    val="lastname"
                    label="เปลี่ยนนามสกุล"
                  />
                </div>
              </div>
            </div>
          </div>
          <div class="row q-gutter-sm q-mb-md">
            <div class="col">
              <q-select
                :readonly="!selection.includes('prefix')"
                v-model="changeNameData.prefix"
                :options="store.Ops.prefixOps"
                label="คำนำหน้าชื่อ"
                dense
                :class="!selection.includes('prefix') ? '' : 'inputgreen'"
                outlined
                use-input
                hide-selected
                fill-input
                lazy-rules
                emit-value
                map-options
                :rules="[(val:string) => !!val || `${'กรุณาเลือกคำนำหน้าชื่อ'}`]"
                hide-bottom-space
                input-debounce="0"
                option-label="name"
                option-value="name"
                @filter="(inputValue:string,
                    doneFn:Function) => filterSelector(inputValue, doneFn,'prefixOps'
                    ) "
              />
            </div>
            <div class="col">
              <q-input
                :readonly="!selection.includes('firstname')"
                outlined
                v-model="changeNameData.firstName"
                label="ชื่อ"
                bg-color="white"
                dense
                :class="!selection.includes('firstname') ? '' : 'inputgreen'"
                :rules="[(val:string) => !!val || `${'กรุณากรอกชื่อ'}`]"
                hide-bottom-space
              />
            </div>
            <div class="col">
              <q-input
                :readonly="!selection.includes('lastname')"
                outlined
                v-model="changeNameData.lastName"
                label="นามสกุล"
                bg-color="white"
                dense
                :class="!selection.includes('lastname') ? '' : 'inputgreen'"
                :rules="[(val:string) => !!val || `${'กรุณากรอกนามสกุล'}`]"
                hide-bottom-space
              />
            </div>
          </div>
          <div class="row">
            <q-uploader
              color="gray"
              type="file"
              flat
              ref="uploader"
              class="full-width"
              text-color="white"
              :max-size="10000000"
              accept=".jpg,.png,.pdf,.csv,.doc,.docx"
              bordered
              label="[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
              @added="(v:any) => (fileUpload = v[0])"
            >
              <template v-slot:header="scope">
                <div class="row no-wrap items-center q-pa-sm q-gutter-xs">
                  <q-btn
                    v-if="scope.queuedFiles.length > 0"
                    icon="clear_all"
                    @click="scope.removeQueuedFiles, (fileUpload = undefined)"
                    round
                    dense
                    flat
                  >
                    <q-tooltip>ลบทั้งหมด</q-tooltip>
                  </q-btn>
                  <q-btn
                    v-if="scope.uploadedFiles.length > 0"
                    icon="done_all"
                    @click="scope.removeUploadedFiles, (fileUpload = undefined)"
                    round
                    dense
                    flat
                  >
                    <q-tooltip>ลบไฟล์ที่อัปโหลด</q-tooltip>
                  </q-btn>
                  <q-spinner
                    v-if="scope.isUploading"
                    class="q-uploader__spinner"
                  />
                  <div class="col">
                    <div class="q-uploader__title">
                      {{ "[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]" }}
                    </div>
                    <div class="q-uploader__subtitle">
                      {{ scope.uploadSizeLabel }} /
                      {{ scope.uploadProgressLabel }}
                    </div>
                  </div>
                  <q-btn
                    v-if="scope.canAddFiles"
                    type="a"
                    icon="add_box"
                    @click="scope.pickFiles"
                    round
                    dense
                    flat
                  >
                    <q-uploader-add-trigger />
                    <q-tooltip>เลือกไฟล์</q-tooltip>
                  </q-btn>
                  <q-btn
                    v-if="scope.isUploading"
                    icon="clear"
                    @click="scope.abort, (fileUpload = undefined)"
                    round
                    dense
                    flat
                  >
                    <q-tooltip>ยกเลิกการอัปโหลด</q-tooltip>
                  </q-btn>
                </div>
              </template>

              <template v-slot:list="scope">
                <q-list separator>
                  <q-item v-for="file in scope.files" :key="file.__key">
                    <q-item-section>
                      <q-item-label class="full-width ellipsis">
                        {{ file.name }}
                      </q-item-label>

                      <q-item-label caption>
                        {{ file.__sizeLabel }} / {{ file.__progressLabel }}
                      </q-item-label>
                    </q-item-section>

                    <q-item-section top side>
                      <q-btn
                        class="gt-xs"
                        size="12px"
                        flat
                        dense
                        round
                        icon="delete"
                        @click="
                          scope.removeFile(file), (fileUpload = undefined)
                        "
                      />
                    </q-item-section>
                  </q-item>
                </q-list>
              </template>
            </q-uploader>
            <div
              v-if="alertUpload && dialogStatus === 'create'"
              class="row text-negative items-center q-mt-sm"
            >
              กรุณาอัปโหลดเอกสาร
              <q-icon name="mdi-alert-circle q-ml-sm" size="24px" />
            </div>
          </div>
        </q-card-section>
        <q-separator />
        <q-card-actions align="right">
          <q-btn
            id="onSubmit"
            type="submit"
            :disable="submitDisable"
            label="บันทึก"
            color="public"
            class="q-px-md"
            @click="
              () => {
                if (!!fileUpload && dialogStatus === 'create') {
                  alertUpload = false;
                } else {
                  alertUpload = true;
                }
              }
            "
          >
            <q-tooltip>บันทึกข้อมูล</q-tooltip>
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style scoped></style>
