<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { storeToRefs } from 'pinia';
import useUserStore from 'stores/user';
import useBranchStore from 'src/stores/branch';
import { dialog } from 'src/stores/utils';

import { User, UserCreate, UserTypeStats } from 'src/stores/user/types';
import { BranchUserStats } from 'src/stores/branch/types';
import useAddressStore from 'src/stores/address';

import PersonCard from 'components/home/PersonCard.vue';
import AppBox from 'components/app/AppBox.vue';
import StatCardComponent from 'components/StatCardComponent.vue';
import SelectorList from 'components/SelectorList.vue';
import AddButton from 'components/AddButton.vue';
import TooltipComponent from 'components/TooltipComponent.vue';
import FormDialog from 'src/components/FormDialog.vue';
import FormInformation from 'src/components/02_personnel-management/FormInformation.vue';
import FormPerson from 'src/components/02_personnel-management/FormPerson.vue';
import FormByType from 'src/components/02_personnel-management/FormByType.vue';
import DrawerInfo from 'src/components/DrawerInfo.vue';
import infoForm from 'src/components/02_personnel-management/infoForm.vue';
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';

const { locale } = useI18n();
const userStore = useUserStore();
const branchStore = useBranchStore();
const adrressStore = useAddressStore();
const { data: userData } = storeToRefs(userStore);

const defaultFormData = {
  provinceId: null,
  districtId: null,
  subDistrictId: null,
  telephoneNo: '',
  email: '',
  zipCode: '',
  gender: '',
  addressEN: '',
  address: '',
  trainingPlace: null,
  importNationality: null,
  sourceNationality: null,
  licenseExpireDate: null,
  licenseIssueDate: null,
  licenseNo: null,
  discountCondition: null,
  retireDate: null,
  startDate: null,
  registrationNo: null,
  lastNameEN: '',
  lastName: '',
  firstNameEN: '',
  firstName: '',
  userRole: '',
  userType: '',
  profileImage: null,
  birthDate: null,
  responsibleArea: null,
  username: '',
  status: 'CREATED',
};

const currentUser = ref<User>();
const infoPersonCardEdit = ref(false);
const infoPersonId = ref<string>('');
const infoPersonCard = ref();
const infoDrawer = ref(false);
const profileSubmit = ref(false);
const urlProfile = ref<string>();
const isEdit = ref(false);
const modal = ref(false);
const statusToggle = ref(true);
const statusFilter = ref<'all' | 'statusACTIVE' | 'statusINACTIVE'>('all');
const inputSearch = ref('');
const userId = ref<string>();
const selectorLabel = ref<string>('');
const hqId = ref<string>();
const brId = ref<string>();
const code = ref<string>();
const formDialogRef = ref();
const userStats = ref<BranchUserStats[]>();
const typeStats = ref<UserTypeStats>();
const formData = ref<UserCreate>({
  provinceId: null,
  districtId: null,
  subDistrictId: null,
  telephoneNo: '',
  email: '',
  zipCode: '',
  gender: '',
  addressEN: '',
  address: '',
  trainingPlace: null,
  importNationality: null,
  sourceNationality: null,
  licenseExpireDate: null,
  licenseIssueDate: null,
  licenseNo: null,
  discountCondition: null,
  retireDate: null,
  startDate: null,
  registrationNo: null,
  lastNameEN: '',
  lastName: '',
  firstNameEN: '',
  firstName: '',
  userRole: '',
  userType: '',
  profileImage: null,
  birthDate: null,
  responsibleArea: null,
  checkpoint: null,
  checkpointEN: null,
  username: '',
  status: 'CREATED',
});

const profileFile = ref<File | undefined>(undefined);
const inputFile = document.createElement('input');
inputFile.type = 'file';
inputFile.accept = 'image/*';

const reader = new FileReader();

reader.addEventListener('load', () => {
  if (typeof reader.result === 'string') {
    urlProfile.value = reader.result;
  }
});

watch(profileFile, () => {
  if (profileFile.value) reader.readAsDataURL(profileFile.value);
});

inputFile.addEventListener('change', (e) => {
  profileFile.value = (e.currentTarget as HTMLInputElement).files?.[0];
});

const selectorList = computed(() => [
  { label: 'USER', count: typeStats.value?.USER || 0 },
  { label: 'MESSENGER', count: typeStats.value?.MESSENGER || 0 },
  { label: 'DELEGATE', count: typeStats.value?.DELEGATE || 0 },
  { label: 'AGENCY', count: typeStats.value?.AGENCY || 0 },
]);

async function openDialog(action?: 'FORM' | 'INFO', idEdit?: string) {
  if (action === 'FORM') {
    modal.value = true;
  } else if (action === 'INFO') {
    infoDrawer.value = true;
    infoPersonCardEdit.value = false;
    if (!userData.value) return;
    const user = userData.value.result.find((x) => x.id === idEdit);
    infoPersonCard.value = user
      ? [
          {
            id: user.id,
            img: `${user.profileImageUrl}`,
            name:
              locale.value === 'en-US'
                ? `${user.firstNameEN} ${user.lastNameEN}`
                : `${user.firstName} ${user.lastName}`,
            male: user.gender === 'male',
            female: user.gender === 'female',
            badge: user.code,
            disabled: user.status === 'INACTIVE',
          },
        ]
      : [];
  }

  statusToggle.value = true;
  profileSubmit.value = false;
  userStore.userOption.brOpts = [];

  if (userStore.userOption.hqOpts.length === 0) {
    await userStore.fetchHqOption();
  }

  if (userStore.userOption.hqOpts.length === 1) {
    hqId.value = userStore.userOption.hqOpts[0].value;
  }

  if (userStore.userOption.roleOpts.length === 0) {
    await userStore.fetchRoleOption();
  }

  if (idEdit && userData.value) {
    assignFormData(idEdit);
  }
}

function undo() {
  if (!infoPersonId) return;
  infoPersonCardEdit.value = false;
  assignFormData(infoPersonId.value);
}

function onClose() {
  code.value = '';
  hqId.value = '';
  brId.value = '';
  userId.value = '';
  urlProfile.value = '';
  profileSubmit.value = false;
  modal.value = false;
  infoDrawer.value = false;
  isEdit.value = false;
  statusToggle.value = true;
  Object.assign(formData.value, defaultFormData);
  mapUserType(selectorLabel.value);
}

async function onSubmit() {
  console.log('hello');

  formData.value.profileImage = profileFile.value as File;
  if (isEdit.value === true && userId.value) {
    dialog({
      color: 'primary',
      icon: 'mdi-pencil-outline',
      title: 'ยืนยันการแก้ไขข้อมูล',
      actionText: 'ตกลง',
      persistent: true,
      message: 'คุณต้องการแก้ไขข้อมูล ใช่หรือไม่',
      action: async () => {
        if (!userId.value) return;

        const formDataEdit = {
          ...formData.value,
          status: !statusToggle.value ? 'INACTIVE' : 'ACTIVE',
        } as const;
        await userStore.editById(userId.value, formDataEdit);
        onClose();

        if (
          hqId.value &&
          currentUser.value?.branch[0] &&
          hqId.value !== currentUser.value.branch[0].id &&
          brId.value !== currentUser.value.branch[0].id
        ) {
          userStore.removeBranch(userId.value, currentUser.value.branch[0].id);
          await branchStore.addUser(
            !!brId.value ? brId.value : hqId.value,
            userId.value,
          );
        }

        userStore.fetchList({
          includeBranch: true,
          userType: selectorLabel.value ?? undefined,
        });
        typeStats.value = await userStore.typeStats();
      },
    });
  } else {
    dialog({
      color: 'primary',
      icon: 'mdi-account',
      title: 'ยืนยันการเพิ่มบุคลากร',
      actionText: 'ตกลง',
      persistent: true,
      message: 'คุณต้องการเพิ่มบุคลากร ใช่หรือไม่',
      action: async () => {
        if (!hqId.value) return;

        statusToggle.value
          ? (formData.value.status = 'CREATED')
          : (formData.value.status = 'INACTIVE');

        const result = await userStore.create(formData.value);
        if (result) {
          await branchStore.addUser(
            !!brId.value ? brId.value : hqId.value,
            result.id,
          );
        }
        onClose();
        userStore.fetchList({
          includeBranch: true,
          userType: selectorLabel.value ?? undefined,
        });
        typeStats.value = await userStore.typeStats();
      },
    });
  }
}

async function onDelete(id: string) {
  dialog({
    color: 'negative',
    icon: 'mdi-trash-can-outline',
    title: 'ยืนยันการลบข้อมูล',
    actionText: 'ตกลง',
    persistent: true,
    message: 'คุณต้องการลบข้อมูล ใช่หรือไม่',
    action: async () => {
      await userStore.deleteById(id);
      await userStore.fetchList({
        includeBranch: true,
        userType: selectorLabel.value ?? undefined,
      });
      typeStats.value = await userStore.typeStats();
    },
  });
}

function mapUserType(label: string) {
  const userTypeMap: { [key: string]: string } = {
    USER: 'USER',
    MESSENGER: 'MESSENGER',
    DELEGATE: 'DELEGATE',
    AGENCY: 'AGENCY',
  };

  formData.value.userType = userTypeMap[label];
}

async function toggleStatus(id: string) {
  const record = userData.value?.result.find((v) => v.id === id);

  if (!record) return;

  const res = await userStore.editById(record.id, {
    status: record.status !== 'INACTIVE' ? 'INACTIVE' : 'ACTIVE',
  });
  if (res) record.status = res.status;
}

async function assignFormData(idEdit: string) {
  if (!userData.value) return;
  const foundUser = userData.value.result.find((user) => user.id === idEdit);
  if (foundUser) {
    currentUser.value = foundUser;
    infoPersonId.value = currentUser.value.id;

    formData.value = {
      provinceId: foundUser.provinceId,
      districtId: foundUser.districtId,
      subDistrictId: foundUser.subDistrictId,
      telephoneNo: foundUser.telephoneNo,
      email: foundUser.email,
      zipCode: foundUser.zipCode,
      gender: foundUser.gender,
      addressEN: foundUser.addressEN,
      address: foundUser.address,
      trainingPlace: foundUser.trainingPlace,
      importNationality: foundUser.importNationality,
      sourceNationality: foundUser.sourceNationality,
      licenseNo: foundUser.licenseNo,
      discountCondition: foundUser.discountCondition,
      registrationNo: foundUser.registrationNo,
      lastNameEN: foundUser.lastNameEN,
      lastName: foundUser.lastName,
      firstNameEN: foundUser.firstNameEN,
      firstName: foundUser.firstName,
      userRole: foundUser.userRole,
      userType: foundUser.userType,
      username: foundUser.username,
      responsibleArea: foundUser.responsibleArea,
      status: foundUser.status,
      licenseExpireDate:
        (foundUser.licenseExpireDate &&
          new Date(foundUser.licenseExpireDate)) ||
        null,
      licenseIssueDate:
        (foundUser.licenseIssueDate && new Date(foundUser.licenseIssueDate)) ||
        null,
      retireDate:
        (foundUser.retireDate && new Date(foundUser.retireDate)) || null,
      startDate: (foundUser.startDate && new Date(foundUser.startDate)) || null,
      birthDate: (foundUser.birthDate && new Date(foundUser.birthDate)) || null,
    };

    formData.value.status === 'ACTIVE' || 'CREATED'
      ? (statusToggle.value = true)
      : (statusToggle.value = false);
    userId.value = foundUser.id;
    if (foundUser.branch[0].isHeadOffice) {
      hqId.value = foundUser.branch[0].id as string;
    } else {
      hqId.value = foundUser.branch[0].headOfficeId as string;
      brId.value = foundUser.branch[0].id;
    }
    code.value = foundUser.code;
    urlProfile.value = foundUser.profileImageUrl;
    isEdit.value = true;
    profileSubmit.value = true;
    await userStore.fetchBrOption(hqId.value);
    if (formData.value.districtId) {
      await adrressStore.fetchSubDistrictByProvinceId(
        formData.value.districtId,
      );
    }
  }
}

onMounted(async () => {
  await userStore.fetchList({
    includeBranch: true,
    userType: selectorLabel.value ?? undefined,
  });
  userStore.userOption.roleOpts.length === 0
    ? await userStore.fetchRoleOption()
    : '';
  typeStats.value = await userStore.typeStats();

  const firstTypeIncludeUser = Object.entries(typeStats.value || {}).find(
    (v) => v[1] > 0,
  );

  firstTypeIncludeUser && (selectorLabel.value = firstTypeIncludeUser[0]);

  const res = await branchStore.userStats(formData.value.userType);
  if (res) {
    userStats.value = res;
  }
});

watch(
  () => selectorLabel.value,
  async (label) => {
    mapUserType(label);
    await userStore.fetchList({
      includeBranch: true,
      userType: selectorLabel.value ?? undefined,
    });
    const res = await branchStore.userStats(label);
    if (res) {
      userStats.value = res;
    }
  },
);
</script>

<template>
  <div class="column q-pb-lg">
    <div class="text-h6 text-weight-bold q-mb-md">
      {{ $t('personnelManagement') }}
    </div>

    <div class="row full-width q-mb-md no-wrap">
      <!-- selector -->
      <SelectorList
        :list="selectorList"
        v-model:selector="selectorLabel"
        class="q-mr-md col-4"
      />

      <!-- stat -->
      <AppBox bordered class="column full-width">
        <div class="row q-pb-sm justify-between items-center">
          <div class="text-weight-bold text-subtitle1">
            {{ $t('personnelStatTitle') }}
            {{ selectorLabel === '' ? '' : $t(selectorLabel) }}
          </div>
          <q-btn
            dense
            unelevated
            label="+ เพิ่มบุคลากร"
            padding="4px 16px"
            @click="openDialog('FORM')"
            style="background-color: var(--cyan-6); color: white"
          />
        </div>
        <div class="row full-width q-py-md" style="overflow-x: auto">
          <StatCardComponent
            v-if="userStats"
            :branch="
              userStats.map((v) => ({
                count: v.count,
                label: $i18n.locale === 'en-US' ? v.nameEN : v.name,
              }))
            "
            :dark="$q.dark.isActive"
            class="no-wrap"
          />
        </div>
      </AppBox>
    </div>

    <!-- main -->
    <AppBox bordered style="width: 100%; height: 70vh; overflow-y: auto">
      <div class="row q-mb-md justify-between">
        <q-btn
          icon="mdi-tune-vertical-variant"
          class="bordered rounded"
          :class="{ 'app-text-info': statusFilter !== 'all' }"
          unelevated
        >
          <q-menu class="bordered">
            <q-list v-close-popup dense>
              <q-item
                clickable
                class="flex items-center"
                :class="{ 'app-text-info': statusFilter === 'all' }"
                @click="statusFilter = 'all'"
              >
                {{ $t('all') }}
              </q-item>
              <q-item
                clickable
                class="flex items-center"
                :class="{
                  'app-text-info': statusFilter === 'statusACTIVE',
                }"
                @click="statusFilter = 'statusACTIVE'"
              >
                {{ $t('statusACTIVE') }}
              </q-item>
              <q-item
                clickable
                class="flex items-center"
                :class="{
                  'app-text-info': statusFilter === 'statusINACTIVE',
                }"
                @click="statusFilter = 'statusINACTIVE'"
              >
                {{ $t('statusINACTIVE') }}
              </q-item>
            </q-list>
          </q-menu>
        </q-btn>
        <q-input
          style="width: 250px"
          outlined
          dense
          label="ค้นหา"
          v-model="inputSearch"
        ></q-input>
      </div>
      <PersonCard
        :list="
          userData?.result
            .filter((v) => {
              if (statusFilter === 'statusACTIVE' && v.status === 'INACTIVE') {
                return false;
              }
              if (
                statusFilter === 'statusINACTIVE' &&
                v.status !== 'INACTIVE'
              ) {
                return false;
              }
              return true;
            })
            .map((v) => ({
              id: v.id,
              img: `${v.profileImageUrl}`,
              name:
                $i18n.locale === 'en-US'
                  ? `${v.firstNameEN} ${v.lastNameEN}`
                  : `${v.firstName} ${v.lastName}`,
              male: v.gender === 'male',
              female: v.gender === 'female',
              detail: [
                { label: 'ประเภท', value: $t(v.userType) },
                { label: 'โทรศัพท์', value: v.telephoneNo },
                {
                  label: 'อายุ',
                  value: userStore.calculateAge(v.birthDate as Date),
                },
              ],
              badge: v.code,
              disabled: v.status === 'INACTIVE',
            })) || []
        "
        @update-card="openDialog"
        @delete-card="onDelete"
        @enter-card="openDialog"
        @toggle-status="toggleStatus"
      />
      <div
        class="column"
        style="height: 100%"
        v-if="userData && userData.total === 0"
      >
        <div class="col-1 self-end">
          <div class="row">
            <TooltipComponent
              title="personnelTooltipTitle"
              caption="personnelTooltipCaption"
              imgSrc="personnel-table-"
            />
          </div>
        </div>
        <div class="col self-center" style="display: flex; align-items: center">
          <AddButton
            :label="'personnelAdd'"
            :cyanOn="true"
            @trigger="openDialog('FORM')"
          />
        </div>
      </div>
    </AppBox>
  </div>

  <DrawerInfo
    v-if="currentUser"
    bg-on
    :isEdit="infoPersonCardEdit"
    :title="
      $i18n.locale === 'en-US'
        ? `${currentUser.firstNameEN} ${currentUser.lastNameEN}`
        : `${currentUser.firstName} ${currentUser.lastName}`
    "
    v-model:drawerOpen="infoDrawer"
    :deleteData="() => onDelete(infoPersonId)"
    :submit="() => onSubmit()"
    :close="() => onClose()"
    :undo="() => undo()"
    :editData="() => (infoPersonCardEdit = true)"
  >
    <template #info>
      <infoForm
        :readonly="!infoPersonCardEdit"
        v-model:address="formData.address"
        v-model:addressEN="formData.addressEN"
        v-model:provinceId="formData.provinceId"
        v-model:districtId="formData.districtId"
        v-model:subDistrictId="formData.subDistrictId"
        v-model:zipCode="formData.zipCode"
      >
        <template #person-card>
          <div class="q-ma-md">
            <AppBox class="surface-1" style="padding: 0">
              <PersonCard
                noHover
                noAction
                noDetail
                no-bg
                :list="infoPersonCard"
                :gridColumns="1"
              />
            </AppBox>
          </div>
        </template>
        <template #information>
          <FormInformation
            dense
            outlined
            separator
            :readonly="!infoPersonCardEdit"
            :usernameReadonly="isEdit"
            v-model:hqId="hqId"
            v-model:brId="brId"
            v-model:userType="formData.userType"
            v-model:userRole="formData.userRole"
            v-model:username="formData.username"
            v-model:userCode="code"
          />
        </template>
        <template #person>
          <FormPerson
            dense
            outlined
            separator
            :readonly="!infoPersonCardEdit"
            v-model:firstName="formData.firstName"
            v-model:lastName="formData.lastName"
            v-model:firstNameEN="formData.firstNameEN"
            v-model:lastNameEN="formData.lastNameEN"
            v-model:telephoneNo="formData.telephoneNo"
            v-model:email="formData.email"
            v-model:gender="formData.gender"
            v-model:birthDate="formData.birthDate"
          />
        </template>
        <template #by-type>
          <FormByType
            dense
            outlined
            separator
            :readonly="!infoPersonCardEdit"
            v-model:userType="formData.userType"
            v-model:registrationNo="formData.registrationNo"
            v-model:startDate="formData.startDate"
            v-model:retireDate="formData.retireDate"
            v-model:responsibleArea="formData.responsibleArea"
            v-model:discountCondition="formData.discountCondition"
            v-model:sourceNationality="formData.sourceNationality"
            v-model:importNationality="formData.importNationality"
            v-model:trainingPlace="formData.trainingPlace"
          />
        </template>
      </infoForm>
    </template>
  </DrawerInfo>

  <!-- form -->
  <FormDialog
    removeDialog
    ref="formDialogRef"
    title="เพิ่มบุคลากร"
    addressTitle="ที่อยู่พนักงาน"
    addressENTitle="ที่อยู่พนักงาน ENG"
    v-model:modal="modal"
    v-model:address="formData.address"
    v-model:addressEN="formData.addressEN"
    v-model:provinceId="formData.provinceId"
    v-model:districtId="formData.districtId"
    v-model:subDistrictId="formData.subDistrictId"
    v-model:zipCode="formData.zipCode"
    :addressSeparator="formData.userType !== ''"
    :submit="() => onSubmit()"
    :close="() => onClose()"
  >
    <template #prepend>
      <div class="text-center">
        <div class="upload-img-preview">
          <q-img
            v-if="urlProfile"
            :src="urlProfile"
            style="object-fit: cover; width: 100%; height: 100%"
          />
          <q-icon
            v-else
            name="mdi-account full-height"
            size="3vw"
            style="color: var(--border-color)"
          />
        </div>
        <div
          v-if="urlProfile && !profileSubmit"
          class="col-12 row q-mt-md q-col-gutter-x-md"
        >
          <div class="col-6">
            <q-btn
              dense
              unelevated
              outlined
              padding="8px"
              class="cancel-img-btn full-width"
              label="ยกเลิก"
              @click="urlProfile = ''"
            />
          </div>
          <div class="col-6">
            <q-btn
              dense
              unelevated
              outlined
              padding="8px"
              class="submit-img-btn full-width"
              label="บันทึก"
              @click="profileSubmit = true"
            />
          </div>
        </div>
        <q-btn
          v-else-if="urlProfile && profileSubmit"
          dense
          unelevated
          outlined
          padding="8px"
          icon="mdi-pencil-outline"
          class="edit-img-btn q-mt-md full-width"
          label="แก้ไขโปรไฟล์"
          @click.prevent="inputFile.click(), (profileSubmit = false)"
        />

        <q-btn
          v-else
          dense
          unelevated
          outlined
          padding="8px"
          class="upload-img-btn q-mt-md full-width"
          label="อัปโหลดรูปภาพ"
          :class="{ dark: $q.dark.isActive }"
          @click="inputFile.click()"
        />
        <q-separator class="col-12 q-my-md" />
        <div class="text-left q-pt-md">
          <q-toggle
            dense
            size="md"
            v-model="statusToggle"
            padding="none"
            class="q-pr-md"
          />
          <span>สถานะผู้ใช้งาน</span>
        </div>
      </div>
    </template>

    <template #information>
      <FormInformation
        dense
        outlined
        separator
        :usernameReadonly="isEdit"
        v-model:hqId="hqId"
        v-model:brId="brId"
        v-model:userType="formData.userType"
        v-model:userRole="formData.userRole"
        v-model:username="formData.username"
        v-model:userCode="code"
      />
    </template>
    <template #person>
      <FormPerson
        dense
        outlined
        separator
        v-model:firstName="formData.firstName"
        v-model:lastName="formData.lastName"
        v-model:firstNameEN="formData.firstNameEN"
        v-model:lastNameEN="formData.lastNameEN"
        v-model:telephoneNo="formData.telephoneNo"
        v-model:email="formData.email"
        v-model:gender="formData.gender"
        v-model:birthDate="formData.birthDate"
      />
    </template>
    <template #by-type>
      <FormByType
        dense
        outlined
        separator
        v-model:userType="formData.userType"
        v-model:registrationNo="formData.registrationNo"
        v-model:startDate="formData.startDate"
        v-model:retireDate="formData.retireDate"
        v-model:responsibleArea="formData.responsibleArea"
        v-model:discountCondition="formData.discountCondition"
        v-model:sourceNationality="formData.sourceNationality"
        v-model:importNationality="formData.importNationality"
        v-model:trainingPlace="formData.trainingPlace"
      />
    </template>
  </FormDialog>
</template>
<style>
.upload-img-preview {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-2);
  height: 12vw;
  background-color: var(--surface-1);
}

.upload-img-btn {
  color: hsl(var(--info-bg));
  border: 1px solid hsl(var(--info-bg));
  background-color: hsla(var(--info-bg) / 0.1);
  border-radius: var(--radius-2);

  &.dark {
    background-color: transparent;
  }
}

.edit-img-btn {
  color: hsl(var(--info-bg));
  border: 1px solid hsl(var(--info-bg));
  background-color: transparent;
  border-radius: var(--radius-2);
}

.cancel-img-btn {
  color: hsl(var(--negative-bg));
  border: 1px solid hsl(var(--negative-bg));
  background-color: transparent;
  border-radius: var(--radius-2);
}

.submit-img-btn {
  color: var(--surface-1);
  border: 1px solid hsl(var(--positive-bg));
  background-color: hsl(var(--positive-bg));
  border-radius: var(--radius-2);
}
</style>
