<script setup lang="ts">
import { QSelect } from 'quasar';
import useOptionStore from 'stores/options';
import { selectFilterOptionRefMod } from 'stores/utils';
import { calculateAge, disabledAfterToday } from 'src/utils/datetime';
import { ref, onMounted, watch } from 'vue';
import { capitalize } from 'vue';
import DatePicker from '../shared/DatePicker.vue';

const optionStore = useOptionStore();
const prefixName = defineModel<string | null>('prefixName');
const firstName = defineModel<string>('firstName');
const lastName = defineModel<string>('lastName');
const firstNameEN = defineModel<string>('firstNameEN');
const lastNameEN = defineModel<string>('lastNameEN');
const telephoneNo = defineModel<string>('telephoneNo');
const email = defineModel<string>('email');
const gender = defineModel<string>('gender');
const birthDate = defineModel<Date | string | null>('birthDate');
const nationality = defineModel<string>('nationality');
const midName = defineModel<string | null>('midName');
const midNameEN = defineModel<string | null>('midNameEN');
const citizenId = defineModel<string>('citizenId');
const citizenIssue = defineModel<Date | null>('citizenIssue');
const citizenExpire = defineModel<Date | null>('citizenExpire');

const props = defineProps<{
  dense?: boolean;
  outlined?: boolean;
  readonly?: boolean;
  separator?: boolean;
  employee?: boolean;
  title?: string;
  prefixId: string;
}>();

const prefixNameOptions = ref<Record<string, unknown>[]>([]);
let prefixNameFilter: (
  value: string,
  update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;

const genderOptions = ref<Record<string, unknown>[]>([]);
let genderFilter: (
  value: string,
  update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;

const nationalityOptions = ref<Record<string, unknown>[]>([]);
let nationalityFilter: (
  value: string,
  update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;

onMounted(() => {
  prefixNameFilter = selectFilterOptionRefMod(
    ref(optionStore.globalOption?.prefix),
    prefixNameOptions,
    'label',
  );
  genderFilter = selectFilterOptionRefMod(
    ref(optionStore.globalOption?.gender),
    genderOptions,
    'label',
  );
  nationalityFilter = selectFilterOptionRefMod(
    ref(optionStore.globalOption?.nationality),
    nationalityOptions,
    'label',
  );
});

watch(
  () => optionStore.globalOption,
  () => {
    prefixNameFilter = selectFilterOptionRefMod(
      ref(optionStore.globalOption.prefix),
      prefixNameOptions,
      'label',
    );
    genderFilter = selectFilterOptionRefMod(
      ref(optionStore.globalOption.gender),
      genderOptions,
      'label',
    );
    nationalityFilter = selectFilterOptionRefMod(
      ref(optionStore.globalOption.nationality),
      nationalityOptions,
      'label',
    );
  },
);

watch(
  () => prefixName.value,
  (v) => {
    if (props.readonly) return;
    if (v === 'mr') gender.value = 'male';
    else if (v !== '') gender.value = 'female';
  },
);
</script>
<template>
  <div class="row col-12">
    <div class="col-12 q-pb-sm text-weight-bold text-body1">
      <q-icon
        flat
        size="xs"
        class="q-pa-sm rounded q-mr-xs"
        color="info"
        name="mdi-account-outline"
        style="background-color: var(--surface-3)"
      />
      {{ $t(`${title}`) }}
    </div>

    <div class="col-12 row q-col-gutter-sm">
      <q-input
        v-if="!employee"
        outlined
        class="col-md-5 col-12"
        hide-bottom-space
        v-model="citizenId"
        mask="#############"
        :readonly="readonly"
        :dense="dense"
        :label="$t('personnel.form.citizenId')"
        :rules="[
          (val) => (val && val.length > 0) || $t('form.error.required'),
          (val) =>
            (val && val.length === 13 && /[0-9]+/.test(val)) ||
            $t('form.error.invalidCustomeMessage', {
              msg: $t('form.error.requireLength', { msg: 13 }),
            }),
        ]"
        for="input-citizen-id"
      />
      <div class="col-12 row" style="display: flex; gap: var(--size-2)">
        <q-select
          outlined
          use-input
          fill-input
          emit-value
          map-options
          hide-selected
          hide-bottom-space
          input-debounce="0"
          option-label="label"
          option-value="value"
          hide-dropdown-icon
          class="col-md-1 col-6"
          :dense="dense"
          :readonly="readonly"
          :options="prefixNameOptions"
          :for="`${prefixId}-select-prefix-name`"
          :label="$t('personnel.form.prefixName')"
          @filter="prefixNameFilter"
          :model-value="readonly ? prefixName || '-' : prefixName"
          @update:model-value="
            (v) => (typeof v === 'string' ? (prefixName = v) : '')
          "
          @clear="prefixName = ''"
        >
          <template v-slot:no-option>
            <q-item>
              <q-item-section class="text-grey">
                {{ $t('general.noData') }}
              </q-item-section>
            </q-item>
          </template>
        </q-select>

        <q-input
          :for="`${prefixId}-input-first-name`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col"
          :label="$t('personnel.form.firstName')"
          v-model="firstName"
          :rules="[(val: string) => !!val || $t('form.error.required')]"
        />

        <q-input
          :for="`${prefixId}-input-mid-name`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col-md-3 col-6"
          :label="$t('personnel.form.middleName')"
          :model-value="readonly ? midName || '-' : midName"
          @update:model-value="
            (v) => (typeof v === 'string' ? (midName = v) : '')
          "
          @clear="midName = ''"
        />

        <q-input
          :for="`${prefixId}-input-last-name`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col"
          :label="$t('personnel.form.lastName')"
          v-model="lastName"
          :rules="[(val: string) => !!val || $t('form.error.required')]"
        />
      </div>

      <div class="col-12 row" style="display: flex; gap: var(--size-2)">
        <q-input
          :for="`${prefixId}-input-first-name`"
          :dense="dense"
          outlined
          hide-bottom-space
          :readonly="readonly"
          :disable="!readonly"
          class="col-md-1 col-6"
          label="Title"
          :model-value="
            readonly
              ? capitalize(prefixName || '') || '-'
              : capitalize(prefixName || '')
          "
          @update:model-value="
            (v) => (typeof v === 'string' ? (prefixName = v) : '')
          "
          @clear="prefixName = ''"
        />

        <q-input
          :for="`${prefixId}-input-first-name-en`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col"
          label="Name"
          v-model="firstNameEN"
          :rules="[
            (val: string) => !!val || $t('form.error.required'),
            (val: string) =>
              /^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
          ]"
        />
        <q-input
          :for="`${prefixId}-input-mid-name-en`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col-md-3 col-6"
          label="Mid Name"
          :model-value="readonly ? midNameEN || '-' : midNameEN"
          @update:model-value="
            (v) => (typeof v === 'string' ? (midNameEN = v) : '')
          "
          @clear="midNameEN = ''"
        />
        <q-input
          :for="`${prefixId}-input-last-name-en`"
          :dense="dense"
          outlined
          :readonly="readonly"
          hide-bottom-space
          class="col"
          label="Surname"
          v-model="lastNameEN"
          :rules="[
            (val: string) => !!val || $t('form.error.required'),
            (val: string) =>
              /^[A-Za-z]+$/.test(val) || $t('form.error.letterOnly'),
          ]"
        />
      </div>

      <q-input
        v-if="!employee"
        :for="`${prefixId}-input-telephone`"
        :dense="dense"
        outlined
        :readonly="readonly"
        class="col-md-3 col-6"
        :label="$t('form.telephone')"
        :mask="readonly ? '' : '##########'"
        :model-value="readonly ? telephoneNo || '-' : telephoneNo"
        @update:model-value="
          (v) => (typeof v === 'string' ? (telephoneNo = v) : '')
        "
        @clear="telephoneNo = ''"
      >
        <template #prepend>
          <q-icon
            size="xs"
            name="mdi-phone-outline"
            class="cursor-pointer"
            color="primary"
          />
        </template>
      </q-input>
      <q-input
        v-if="!employee"
        :for="`${prefixId}-input-email`"
        :dense="dense"
        outlined
        hide-bottom-space
        :readonly="readonly"
        :label="$t('form.email')"
        :rules="
          readonly
            ? undefined
            : [
                (v: string) =>
                  !v ||
                  /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g.test(v) ||
                  $t('form.error.invalid'),
              ]
        "
        class="col-md-3 col-6"
        :model-value="readonly ? email || '-' : email"
        @update:model-value="(v) => (typeof v === 'string' ? (email = v) : '')"
        @clear="email = ''"
      >
        <template #prepend>
          <q-icon
            size="xs"
            name="mdi-email-outline"
            class="cursor-pointer"
            color="primary"
          />
        </template>
      </q-input>

      <q-select
        v-if="!employee"
        outlined
        use-input
        fill-input
        emit-value
        map-options
        hide-selected
        hide-bottom-space
        input-debounce="0"
        option-label="label"
        option-value="value"
        class="col-md-2 col-6"
        :dense="dense"
        :readonly="readonly"
        :options="genderOptions"
        :hide-dropdown-icon="readonly"
        :for="`${prefixId}-select-gender`"
        :label="$t('form.gender')"
        @filter="genderFilter"
        :model-value="readonly ? gender || '-' : gender"
        @update:model-value="(v) => (typeof v === 'string' ? (gender = v) : '')"
        @clear="gender = ''"
      >
        <template v-slot:no-option>
          <q-item>
            <q-item-section class="text-grey">
              {{ $t('general.noData') }}
            </q-item-section>
          </q-item>
        </template>
      </q-select>

      <DatePicker
        v-model="birthDate"
        class="col-md-2 col-6"
        :id="`${prefixId}-input-birth-date`"
        :readonly="readonly"
        :label="$t('form.birthDate')"
        :disabled-dates="disabledAfterToday"
        :rules="[
          (val: string) =>
            !!val ||
            $t('form.error.selectField', { field: $t('form.birthDate') }),
        ]"
      />

      <q-input
        :for="`${prefixId}-input-age`"
        :id="`${prefixId}-input-age`"
        :dense="dense"
        outlined
        readonly
        :label="$t('personnel.age')"
        class="col-md-2 col-12"
        :model-value="
          birthDate?.toString() === 'Invalid Date' ||
          birthDate?.toString() === undefined
            ? ''
            : calculateAge(birthDate)
        "
      />

      <DatePicker
        v-if="!employee"
        v-model="citizenIssue"
        class="col-md-2 col-6"
        :id="`${prefixId}-input-citizen-issue`"
        :readonly="readonly"
        :label="$t('personnel.form.citizenIssue')"
        :disabled-dates="disabledAfterToday"
        :rules="[
          (val: string) =>
            !!val ||
            $t('form.error.selectField', {
              field: $t('personnel.form.citizenIssue'),
            }),
        ]"
      />

      <DatePicker
        v-if="!employee"
        v-model="citizenExpire"
        class="col-md-2 col-6"
        :id="`${prefixId}-input-citizen-expire`"
        :readonly="readonly"
        :label="$t('personnel.form.citizenExpire')"
        :disabled-dates="disabledAfterToday"
      />

      <q-select
        v-if="employee"
        outlined
        clearable
        use-input
        fill-input
        emit-value
        map-options
        hide-selected
        hide-bottom-space
        input-debounce="0"
        option-label="label"
        option-value="value"
        class="col-2"
        :dense="dense"
        v-model="gender"
        :readonly="readonly"
        :options="genderOptions"
        :hide-dropdown-icon="readonly"
        :for="`${prefixId}-select-gender`"
        :label="$t('form.gender')"
        :rules="[(val: string) => !!val || $t('form.error.required')]"
        @filter="genderFilter"
      >
        <template v-slot:no-option>
          <q-item>
            <q-item-section class="text-grey">
              {{ $t('general.noData') }}
            </q-item-section>
          </q-item>
        </template>
      </q-select>
      <q-select
        v-if="employee"
        outlined
        clearable
        use-input
        fill-input
        emit-value
        map-options
        hide-selected
        hide-bottom-space
        input-debounce="0"
        option-label="label"
        option-value="value"
        v-model="nationality"
        class="col-2"
        :dense="dense"
        :readonly="readonly"
        :options="nationalityOptions"
        :hide-dropdown-icon="readonly"
        :for="`${prefixId}-select-nationality`"
        :label="$t('general.nationality')"
        :rules="[(val: string) => !!val || $t('form.error.required')]"
        @filter="nationalityFilter"
      >
        <template v-slot:no-option>
          <q-item>
            <q-item-section class="text-grey">
              {{ $t('general.noData') }}
            </q-item-section>
          </q-item>
        </template>
      </q-select>
    </div>
  </div>
</template>
