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

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

import type {
  Address as AddressType,
  AddressData,
  AddressOps,
  Address,
  optionData,
} from "@/modules/05_placement/interface/index/Main";
import type { zipCodeOption } from "@/modules/05_placement/components/PersonalDetail/profileType";

const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError } = mixin;

const props = defineProps({
  selectProvince: Function,
});
const registAddress = defineModel<AddressData>("registAddress", {
  required: true,
});
const Ops = defineModel<AddressOps>("opsAddress", { required: true });
const OpsFilter = defineModel<AddressOps>("opsFilterAddress", {
  required: true,
});
const addressData = defineModel<Address>("addressData", { required: true });
const currentAddress = defineModel<AddressData>("currentAddress", {
  required: true,
});

/**
 * ฟังก์ชันดึงข้อมูลอำเภอ
 * @param id จังหวัด
 * @param position  ที่อยู่ตามทะเบียนบ้าน , ที่อยู่ปัจจุบัน
 */
async function fetchDistrict(id: string | null, position: string) {
  if (id != null && id != "") {
    await http
      .get(config.API.orgProvince + `/${id}`)
      .then(async (res) => {
        const data = res.data.result.districts;
        let option: optionData[] = [];
        data.map((r: any) => {
          option.push({ id: r.id, name: r.name });
        });
        if (position == "1") {
          Ops.value.districtOps = option;
          OpsFilter.value.districtOps = option;

          // ที่อยู่ เช็คอำเภอว่ามี id ใน array ไหม ถ้ามีค่อยกำหนดค่าไปในตัวแปรใหม่เพิ่มแสดงผล
          const checkRegistDistrictId = option.find(
            (e: any) => e.id === addressData.value.registDistrictId
          );

          if (checkRegistDistrictId) {
            registAddress.value.districtId = addressData.value.registDistrictId;
          }
        } else {
          Ops.value.districtCOps = option;
          OpsFilter.value.districtCOps = option;

          // ที่อยู่ปัจจุบัน เช็คอำเภอว่ามี id ใน array ไหม ถ้ามีค่อยกำหนดค่าไปในตัวแปรใหม่เพิ่มแสดงผล
          const checkCurrentDistrictId = await option.find(
            (e: any) => e.id === addressData.value.currentDistrictId
          );
          if (checkCurrentDistrictId) {
            currentAddress.value.districtId =
              addressData.value.currentDistrictId;
          }
        }
      })
      .catch((e) => {
        messageError($q, e);
      })
      .finally(() => {});
  }
}

/**
 * ฟังก์ชันค้นหาข้อมูลในรายการตัวเลือก
 * @param val คำค้นหา
 * @param update ฟังก์ชัน
 * @param refData ประเภทของตัวเลือก
 */
function filterSelector(val: string, update: Function, refData: string) {
  switch (refData) {
    case "provinceOps":
      update(() => {
        Ops.value.provinceOps = OpsFilter.value.provinceOps.filter(
          (v: optionData) => v.name.indexOf(val) > -1
        );
      });
      break;
    case "districtOps":
      update(() => {
        Ops.value.districtOps = OpsFilter.value.districtOps.filter(
          (v: optionData) => v.name.indexOf(val) > -1
        );
      });
      break;
    case "districtCOps":
      update(() => {
        Ops.value.districtCOps = OpsFilter.value.districtCOps.filter(
          (v: optionData) => v.name.indexOf(val) > -1
        );
      });
      break;
    case "subdistrictOps":
      update(() => {
        Ops.value.subdistrictOps = OpsFilter.value.subdistrictOps.filter(
          (v: optionData) => v.name.indexOf(val) > -1
        );
      });
      break;
    case "subdistrictCOps":
      update(() => {
        Ops.value.subdistrictCOps = OpsFilter.value.subdistrictCOps.filter(
          (v: optionData) => v.name.indexOf(val) > -1
        );
      });
      break;

    default:
      break;
  }
}

/**
 * ฟังก์ชันดึงข้อมูลจังหวัด
 */
async function fetchProvince() {
  showLoader();
  await http
    .get(config.API.orgProvince)
    .then(async (res) => {
      const data = res.data.result;
      let option: optionData[] = [];
      data.map((r: any) => {
        option.push({ id: r.id, name: r.name });
      });
      Ops.value.provinceOps = option;
      OpsFilter.value.provinceOps = option;

      const checkRegistProvinceId = await option.find(
        (e: any) => e.id === addressData.value.registProvinceId
      );

      // ที่อยู่ถ้า id จังหวัดว่างไม่ดึงค่าอำเภอ ตำบล และรหัสไปรษณีย์
      if (
        addressData.value.registProvinceId == "" ||
        addressData.value.registProvinceId ==
          "00000000-0000-0000-0000-000000000000" ||
        !checkRegistProvinceId
      ) {
        registAddress.value.subDistrictId = "";
        registAddress.value.zipCode = "";
        registAddress.value.districtId = "";
        hideLoader();
      } else {
        registAddress.value.provinceId = await addressData.value
          .registProvinceId;
        registAddress.value.zipCode = await addressData.value.registZipCode;

        await fetchDistrict(addressData.value.registProvinceId, "1");
        if (
          addressData.value.registDistrictId != null &&
          addressData.value.registDistrictId !=
            "00000000-0000-0000-0000-000000000000"
        ) {
          await fetchSubDistrict(addressData.value.registDistrictId, "1");
        }
      }

      const checkCurrentProvinceId = await option.find(
        (e: any) => e.id === addressData.value.currentProvinceId
      );

      // ที่อยู่ปัจจุบันถ้า id จังหวัดว่างไม่ดึงค่าอำเภอ ตำบล และรหัสไปรษณีย์
      if (
        addressData.value.currentProvinceId == "" ||
        addressData.value.currentProvinceId ==
          "00000000-0000-0000-0000-000000000000" ||
        !checkCurrentProvinceId
      ) {
        currentAddress.value.subDistrictId = "";
        currentAddress.value.zipCode = "";
        currentAddress.value.districtId = "";
        hideLoader();
      } else {
        currentAddress.value.provinceId = addressData.value.currentProvinceId;
        currentAddress.value.zipCode = addressData.value.currentZipCode;

        await fetchDistrict(addressData.value.currentProvinceId, "2");
        if (
          addressData.value.currentDistrictId != null &&
          addressData.value.currentDistrictId !=
            "00000000-0000-0000-0000-000000000000"
        ) {
          await fetchSubDistrict(addressData.value.currentDistrictId, "2");
        }
      }
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {});
}

/**
 * ฟังก์ชันดึงข้อมูลตำบล
 * @param id อำเภอ
 * @param position  ที่อยู่ตามทะเบียนบ้าน , ที่อยู่ปัจจุบัน
 */
async function fetchSubDistrict(id: string | null, position: string) {
  if (id != null && id != "") {
    await http
      .get(config.API.orgDistrict + `/${id}`)
      .then(async (res) => {
        const data = res.data.result.subDistricts;
        let option: zipCodeOption[] = [];
        data.map((r: any) => {
          option.push({
            id: r.id,
            name: r.name,
            zipCode: r.zipCode,
          });
        });
        if (position == "1") {
          Ops.value.subdistrictOps = option;
          OpsFilter.value.subdistrictOps = option;

          // ที่อยู่ เช็คตำบลว่ามี id ใน array ไหม ถ้ามีค่อยกำหนดค่าไปในตัวแปรใหม่เพิ่มแสดงผล
          const checkRegistSubDistrictId = await option.find(
            (e: any) => e.id === addressData.value.registSubDistrictId
          );
          if (checkRegistSubDistrictId) {
            registAddress.value.subDistrictId =
              addressData.value.registSubDistrictId;
          }
        } else {
          Ops.value.subdistrictCOps = option;
          OpsFilter.value.subdistrictCOps = option;

          // ที่อยู่ปัจจุบัน เช็คตำบลว่ามี id ใน array ไหม ถ้ามีค่อยกำหนดค่าไปในตัวแปรใหม่เพิ่มแสดงผล
          const checkCurrentSubDistrictId = await option.find(
            (e: any) => e.id === addressData.value.currentSubDistrictId
          );
          if (checkCurrentSubDistrictId) {
            currentAddress.value.subDistrictId =
              addressData.value.currentSubDistrictId;
          }
        }
      })
      .catch((e) => {
        messageError($q, e);
      })
      .finally(() => {
        hideLoader();
      });
  }
}

/**
 * ฟังก์ชันเลือกข้อมูลจังหวัด
 * @param e id จังหวัด
 * @param name ที่อยู่ตามทะเบียนบ้าน , ที่อยู่ปัจจุบัน
 */
async function selectProvince(e: string | null, name: string) {
  if (e != null) {
    if (name == "1") {
      registAddress.value.subDistrictId = "";
      registAddress.value.zipCode = "";
      registAddress.value.districtId = "";
    } else {
      currentAddress.value.subDistrictId = "";
      currentAddress.value.zipCode = "";
      currentAddress.value.districtId = "";
    }
    await fetchDistrict(e, name);
  }
}

/**
 * ฟังก์ชันเลือกข้อมูลตำบล
 * @param e id ตำบล
 * @param name ที่อยู่ตามทะเบียนบ้าน , ที่อยู่ปัจจุบัน
 */
async function selectSubDistrict(e: string | null, name: string) {
  if (e != null) {
    if (name == "1") {
      const findcode = Ops.value.subdistrictOps.filter((r) => r.id == e);
      const namecode = findcode.length > 0 ? findcode[0].zipCode : "";
      registAddress.value.zipCode = namecode;
    } else {
      const findcode = Ops.value.subdistrictCOps.filter((r) => r.id == e);
      const namecode = findcode.length > 0 ? findcode[0].zipCode : "";
      currentAddress.value.zipCode = namecode;
    }
  }
}

/**
 * ฟังก์ชันลือกข้อมูลอำเภอ
 * @param e id อำเภอ
 * @param name ที่อยู่ตามทะเบียนบ้าน , ที่อยู่ปัจจุบัน
 */
async function selectDistrict(e: string | null, name: string) {
  if (e != null) {
    if (name == "1") {
      registAddress.value.subDistrictId = "";
      registAddress.value.zipCode = "";
    } else {
      currentAddress.value.subDistrictId = "";
      currentAddress.value.zipCode = "";
    }
    await fetchSubDistrict(e, name);
  }
}

onMounted(() => {
  fetchProvince();
});
</script>
<template>
  <div class="row q-col-gutter-sm">
    <div class="col-12 text-tooltip text-weight-medium">ข้อมูลที่อยู่</div>
    <div class="col-xs-12">
      <q-input
        class="inputgreen"
        hide-bottom-space
        outlined
        dense
        lazy-rules
        type="textarea"
        autogrow
        v-model="addressData.registAddress"
        :rules="[(val: string) => !!val || `${'กรุณากรอก ที่อยู่ตามทะเบียนบ้าน'}`]"
        :label="`${'ที่อยู่ตามทะเบียนบ้าน'}`"
      />
    </div>
    <div class="col-xs-6 col-sm-3 col-md-3">
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
        outlined
        dense
        lazy-rules
        v-model="registAddress.provinceId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.provinceOps"
        option-value="id"
        :label="`${'จังหวัด'}`"
        @update:model-value="(value: string) => selectProvince(value, '1')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'provinceOps'
              )"
      />
    </div>
    <div class="col-xs-6 col-sm-3 col-md-3">
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือกแขวง/ตำบล'}`]"
        outlined
        dense
        lazy-rules
        v-model="registAddress.districtId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.districtOps"
        option-value="id"
        :label="`${'เขต/อำเภอ'}`"
        @update:model-value="(value: string) => selectDistrict(value, '1')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'districtOps'
              )"
      />
    </div>
    <div class="col-xs-6 col-sm-3 col-md-3">
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือกแขวง/ตำบล '}`]"
        outlined
        dense
        lazy-rules
        v-model="registAddress.subDistrictId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.subdistrictOps"
        option-value="id"
        :label="`${'แขวง/ตำบล '}`"
        @update:model-value="(value: string) => selectSubDistrict(value, '1')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'subdistrictOps'
              )"
      />
    </div>
    <div class="col-xs-6 col-sm-3 col-md-3">
      <q-input
        class="inputgreen"
        hide-bottom-space
        dense
        lazy-rules
        readonly
        borderless
        v-model="registAddress.zipCode"
        style="padding: 0 12px"
        :label="`${'รหัสไปรษณีย์'}`"
      />
    </div>
    <div class="col-12 q-pt-lg"><q-separator /></div>
    <div class="col-xs-12 q-gutter-sm items-center flex q-my-sm">
      <label class="text-bold"
        >ที่อยู่ปัจจุบันตรงกับที่อยู่ตามทะเบียนบ้าน</label
      >
      <q-radio
        v-model="addressData.registSame"
        checked-icon="task_alt"
        unchecked-icon="panorama_fish_eye"
        val="1"
        label="ใช่"
        dense
      />
      <q-radio
        v-model="addressData.registSame"
        checked-icon="task_alt"
        unchecked-icon="panorama_fish_eye"
        val="0"
        label="ไม่"
        dense
      />
    </div>

    <div class="col-xs-12" v-if="addressData.registSame == '0'">
      <q-input
        class="inputgreen"
        hide-bottom-space
        outlined
        dense
        lazy-rules
        type="textarea"
        autogrow
        v-model="addressData.currentAddress"
        :rules="[(val: string) => !!val || `${'กรุณากรอก ที่อยู่ปัจจุบัน'}`]"
        :label="`${'ที่อยู่ปัจจุบัน'}`"
      />
    </div>
    <div
      class="col-xs-6 col-sm-3 col-md-3"
      v-if="addressData.registSame == '0'"
    >
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
        outlined
        dense
        lazy-rules
        v-model="currentAddress.provinceId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.provinceOps"
        option-value="id"
        :label="`${'จังหวัด'}`"
        @update:model-value="(value: string) => selectProvince(value, '2')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'provinceOps'
              )"
      />
    </div>
    <div
      class="col-xs-6 col-sm-3 col-md-3"
      v-if="addressData.registSame == '0'"
    >
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือกแขวง/ตำบล'}`]"
        outlined
        dense
        lazy-rules
        v-model="currentAddress.districtId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.districtCOps"
        option-value="id"
        :label="`${'เขต/อำเภอ'}`"
        @update:model-value="(value: string) => selectDistrict(value, '2')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'districtCOps'
              )"
      />
    </div>
    <div
      class="col-xs-6 col-sm-3 col-md-3"
      v-if="addressData.registSame == '0'"
    >
      <q-select
        hide-bottom-space
        class="inputgreen"
        :rules="[(val: string) => !!val || `${'กรุณาเลือกแขวง/ตำบล '}`]"
        outlined
        dense
        lazy-rules
        v-model="currentAddress.subDistrictId"
        emit-value
        map-options
        option-label="name"
        :options="Ops.subdistrictCOps"
        option-value="id"
        :label="`${'แขวง/ตำบล '}`"
        @update:model-value="(value: string) => selectSubDistrict(value, '2')"
        use-input
        input-debounce="0"
        @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 'subdistrictCOps'
              )"
      />
    </div>
    <div
      class="col-xs-6 col-sm-3 col-md-3"
      v-if="addressData.registSame == '0'"
    >
      <q-input
        class="inputgreen"
        hide-bottom-space
        dense
        lazy-rules
        readonly
        borderless
        v-model="currentAddress.zipCode"
        style="padding: 0 12px"
        :label="`${'รหัสไปรษณีย์'}`"
      />
    </div>
  </div>
</template>
