<script lang="ts" setup>
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { useQuasar } from 'quasar';
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { dialogCheckData, dialogWarningClose } from 'stores/utils';
import { ProductTree, quotationProductTree } from './utils';

// NOTE: Import stores
import { setLocale, dateFormat, calculateAge } from 'src/utils/datetime';
import { useEmployeeForm } from 'src/pages/03_customer-management/form';
import useProductServiceStore from 'stores/product-service';
import { baseUrl, waitAll, calculateDaysUntilExpire } from 'src/stores/utils';
import useCustomerStore from 'stores/customer';
import useOptionStore from 'stores/options';
import { useQuotationForm } from './form';
import useOcrStore from 'stores/ocr';
import { deleteItem } from 'stores/utils';
import { runOcr, parseResultMRZ } from 'src/utils/ocr';

// NOTE  Import Types
import { QuotationPayload } from 'src/stores/quotations/types';
import { EmployeeWorker } from 'src/stores/quotations/types';
import { Employee } from 'src/stores/employee/types';
import {
  ProductGroup,
  Product,
  Service,
} from 'src/stores/product-service/types';

// NOTE: Import Components
import FormEmployeePassport from 'components/03_customer-management/FormEmployeePassport.vue';
import FormEmployeeVisa from 'components/03_customer-management/FormEmployeeVisa.vue';
import FormReferDocument from 'src/components/05_quotation/FormReferDocument.vue';
import { UploadFileGroup, noticeJobEmployment } from 'components/upload-file';
import FormPerson from 'components/02_personnel-management/FormPerson.vue';
import ProductItem from 'components/05_quotation/ProductItem.vue';
import WorkerItem from 'components/05_quotation/WorkerItem.vue';
import ToggleButton from 'components/button/ToggleButton.vue';
import FormAbout from 'components/05_quotation/FormAbout.vue';
import SelectZone from 'components/shared/SelectZone.vue';
import PersonCard from 'components/shared/PersonCard.vue';
import {
  AddButton,
  SaveButton,
  EditButton,
  UndoButton,
  DeleteButton,
  CloseButton,
  MainButton,
} from 'components/button';
import ProductServiceForm from './ProductServiceForm.vue';
import QuotationFormInfo from './QuotationFormInfo.vue';
import ProfileBanner from 'components/ProfileBanner.vue';
import DialogForm from 'components/DialogForm.vue';
import {
  uploadFileListEmployee,
  columnsAttachment,
} from 'src/pages/03_customer-management/constant';
import { precisionRound } from 'src/utils/arithmetic';
import { useConfigStore } from 'src/stores/config';
import QuotationFormMetadata from './QuotationFormMetadata.vue';
import BadgeCompoent from 'src/components/BadgeCompoent.vue';

// defineProps<{
//   readonly?: boolean;
// }>();

type Node = {
  [key: string]: any;
  opened?: boolean;
  checked?: boolean;
  bg?: string;
  fg?: string;
  icon?: string;
  children?: Node[];
};

type ProductGroupId = string;

const configStore = useConfigStore();
const productServiceStore = useProductServiceStore();
const employeeFormStore = useEmployeeForm();
const customerStore = useCustomerStore();
const quotationForm = useQuotationForm();
const optionStore = useOptionStore();
const { t, locale } = useI18n();
const ocrStore = useOcrStore();
const $q = useQuasar();

const {
  currentFormData: quotationFormData,
  currentFormState: quotationFormState,
  newWorkerList,
  fileItemNewWorker,
  quotationFull,
} = storeToRefs(quotationForm);

const { data: config } = storeToRefs(configStore);

const refSelectZoneEmployee = ref<InstanceType<typeof SelectZone>>();
const mrz = ref<Awaited<ReturnType<typeof parseResultMRZ>>>();
const toggleWorker = ref(true);
const currentQuotationId = ref<string | undefined>(undefined);
const date = ref();
const preSelectedWorker = ref<Employee[]>([]);
const readonly = computed(() => {
  return !(
    quotationFormState.value.mode === 'create' ||
    quotationFormState.value.mode === 'edit'
  );
});

const selectedWorker = ref<
  (Employee & {
    attachment?: {
      name?: string;
      group?: string;
      url?: string;
      file?: File;
      _meta?: Record<string, any>;
    }[];
  })[]
>([]);
const workerList = ref<Employee[]>([]);

const selectedProductGroup = ref('');
const agentPrice = ref(false);
const summaryPrice = computed(() =>
  productServiceList.value.reduce(
    (a, c) => {
      const price = precisionRound(c.pricePerUnit * c.amount);
      const vat = precisionRound(
        (c.pricePerUnit * c.amount - c.discount) * (config.value?.vat || 0.07),
      );

      a.totalPrice = precisionRound(a.totalPrice + price);
      a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
      a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat;
      a.vatExcluded = c.product.calcVat
        ? a.vatExcluded
        : precisionRound(a.vat + vat);
      a.finalPrice = precisionRound(
        a.totalPrice -
          a.totalDiscount +
          a.vat -
          Number(quotationFormData.value.discount || 0),
      );

      return a;
    },
    {
      totalPrice: 0,
      totalDiscount: 0,
      vat: 0,
      vatExcluded: 0,
      finalPrice: 0,
    },
  ),
);

const payBank = ref('');

const pageState = reactive({
  hideStat: false,
  inputSearch: '',
  statusFilter: 'all',
  fieldSelected: [],
  gridView: false,
  isLoaded: false,

  currentTab: 'all',
  addModal: false,
  quotationModal: false,
  employeeModal: false,
  productServiceModal: false,
});

const productList = ref<Partial<Record<ProductGroupId, Product[]>>>({});
const serviceList = ref<Partial<Record<ProductGroupId, Service[]>>>({});
const productGroup = ref<ProductGroup[]>([]);

const { state: employeeFormState, currentFromDataEmployee } =
  storeToRefs(employeeFormStore);

const selectedGroupSub = ref<'product' | 'service' | null>(null);
const formDataEmployee = ref<
  EmployeeWorker & {
    attachment?: {
      name?: string;
      group?: string;
      url?: string;
      file?: File;
      _meta?: Record<string, any>;
    }[];
  }
>({
  passportNo: '',
  documentExpireDate: new Date(),
  lastNameEN: '',
  lastName: '',
  middleNameEN: '',
  middleName: '',
  firstNameEN: '',
  firstName: '',
  namePrefix: '',
  nationality: '',
  gender: '',
  dateOfBirth: new Date(),
  attachment: [],
});

const productServiceList = ref<
  Required<QuotationPayload['productServiceList'][number]>[]
>([]);

async function closeTab() {
  if (quotationFormState.value.mode === 'edit') {
    quotationForm.resetForm();
    await assignToProductServiceList();
  } else {
    dialogWarningClose(t, {
      message: t('dialog.message.close'),
      action: () => {
        window.close();
      },
      cancel: () => {},
    });
  }
}

function closeAble() {
  return window.opener !== null;
}

async function assignToProductServiceList() {
  const ret = await productServiceStore.fetchProductGroup({
    page: 1,
    pageSize: 9999,
  });

  if (ret) {
    productGroup.value = ret.result;

    productServiceList.value = quotationFormData.value.productServiceList.map(
      (v) => ({
        workerIndex: v.workerIndex || [0],
        vat: v.vat || 0,
        pricePerUnit: v.pricePerUnit || 0,
        discount: v.discount || 0,
        amount: v.amount || 0,
        product: v.product,
        work: v.work || null,
        service: v.service || null,
      }),
    );
    selectedProductGroup.value =
      quotationFormData.value.productServiceList[0]?.product.productGroup?.id ||
      '';
  }
}

async function convertDataToFormSubmit() {
  quotationFormData.value.productServiceList = JSON.parse(
    JSON.stringify(
      productServiceList.value.map((v) => ({
        workerIndex: v.workerIndex,
        discount: v.discount,
        amount: v.amount,
        product: v.product,
        work: v.work,
        service: v.service,
      })),
    ),
  );

  selectedWorker.value.forEach((v, i) => {
    if (v.attachment !== undefined) {
      v.attachment.forEach((value) => {
        fileItemNewWorker.value.push({
          employeeIndex: i,
          name: value.name,
          group: value.group as 'passport' | 'visa' | 'in-country-notice',
          url: value.url,
          file: value.file,
          _meta: value._meta,
        });
      });
    }
  });

  quotationFormData.value.worker = JSON.parse(
    JSON.stringify(
      selectedWorker.value.map((v) => {
        if (v.id === undefined) {
          const { attachment, ...payload } = v;
          return payload;
        } else {
          return v.id;
        }
      }),
    ),
  );

  quotationFormData.value.paySplit = JSON.parse(
    JSON.stringify(
      quotationFormData.value.paySplit.map((p) => ({ ...p, no: undefined })),
    ),
  );

  quotationFormData.value = {
    id: quotationFormData.value.id,
    productServiceList: quotationFormData.value.productServiceList,
    urgent: quotationFormData.value.urgent,
    customerBranchId: quotationFormData.value.customerBranchId,
    registeredBranchId: quotationFormData.value.registeredBranchId,
    worker: quotationFormData.value.worker,
    payBillDate: quotationFormData.value.payBillDate,
    paySplit: quotationFormData.value.paySplit,
    paySplitCount: quotationFormData.value.paySplitCount,
    payCondition: quotationFormData.value.payCondition,
    dueDate: quotationFormData.value.dueDate,
    documentReceivePoint: quotationFormData.value.documentReceivePoint,
    contactTel: quotationFormData.value.contactTel,
    contactName: quotationFormData.value.contactName,
    workName: quotationFormData.value.workName,
    _count: quotationFormData.value._count,
    status: quotationFormData.value.status,
    discount: quotationFormData.value.discount,
    remark: quotationFormData.value.remark || '',
  };

  const res = await quotationForm.submitQuotation();

  if (res === true) {
    quotationFormState.value.mode = 'info';
  }
}

async function getAllProduct(
  groupId: string,
  opts?: { force?: boolean; page?: number; pageSize?: number; query?: string },
) {
  selectedGroupSub.value = 'product';
  if (!opts?.force && productList.value[groupId] !== undefined) return;
  const ret = await productServiceStore.fetchListProduct({
    page: opts?.page ?? 1,
    pageSize: opts?.pageSize ?? 9999,
    query: opts?.query,
    productGroupId: groupId,
  });
  if (ret) productList.value[groupId] = ret.result;
}

function setDefaultFormEmployee() {
  formDataEmployee.value = {
    passportNo: '',
    documentExpireDate: new Date(),
    lastNameEN: '',
    lastName: '',
    middleNameEN: '',
    middleName: '',
    firstNameEN: '',
    firstName: '',
    namePrefix: '',
    nationality: '',
    gender: '',
    dateOfBirth: new Date(),
    attachment: [],
  };

  employeeFormState.value.dialogModal = false;
}

async function getAllService(
  groupId: string,
  opts?: { force?: boolean; page?: number; pageSize?: number; query?: string },
) {
  selectedGroupSub.value = 'service';

  if (!opts?.force && serviceList.value[groupId] !== undefined) return;

  const ret = await productServiceStore.fetchListService({
    page: opts?.page ?? 1,
    pageSize: opts?.pageSize ?? 9999,
    productGroupId: groupId,
    query: opts?.query,

    fullDetail: true,
  });
  if (ret) serviceList.value[groupId] = ret.result;
}

function triggerCreateEmployee() {
  employeeFormStore.resetFormDataEmployee(true);
  setDefaultFormEmployee();
  employeeFormState.value.dialogType = 'create';
  employeeFormState.value.dialogModal = true;
  employeeFormState.value.isEmployeeEdit = true;
}

async function triggerSelectEmployeeDialog() {
  pageState.employeeModal = true;
  await nextTick();
  refSelectZoneEmployee.value?.assignSelect(
    preSelectedWorker.value,
    selectedWorker.value,
  );
}

function triggerProductServiceDialog() {
  pageState.productServiceModal = true;
}

function toggleDeleteProduct(index: number) {
  productServiceList.value.splice(index, 1);
}
async function assignWorkerToSelectedWorker() {
  if (quotationFormData.value.customerBranchId) {
    const retEmp = await customerStore.fetchBranchEmployee(
      quotationFormData.value.customerBranchId,
      { passport: true },
    );
    if (retEmp) {
      workerList.value = retEmp.data.result;
      quotationFormData.value.worker.forEach((value) => {
        const tempValue: Employee | undefined = retEmp.data.result.find(
          (v) => v.id === value.id,
        );
        if (tempValue !== undefined) selectedWorker.value.push(tempValue);
      });
    }
  }
}

function convertToTable(nodes: Node[]) {
  const _recursive = (v: Node): Node | Node[] => {
    if (v.checked && v.children) return v.children.flatMap(_recursive);
    if (v.checked) return v;
    return [];
  };
  const list = nodes.flatMap(_recursive).map((v) => v.value);

  list.forEach((v) => {
    v.amount = Math.max(selectedWorker.value.length, 1);
    if (!v.workerIndex) v.workerIndex = [];
    for (let i = 0; i < selectedWorker.value.length; i++) {
      v.workerIndex.push(i);
    }
  });

  productServiceList.value = list;
  pageState.productServiceModal = false;
}

function convertEmployeeToTable() {
  productServiceList.value.forEach((v) => {
    if (selectedWorker.value.length === 0 && v.amount === 1) v.amount -= 1;

    v.amount = Math.max(
      v.amount + preSelectedWorker.value.length - selectedWorker.value.length,
      1,
    );

    const oldWorkerId: string[] = [];
    const newWorkerIndex: number[] = [];

    selectedWorker.value.forEach((item, i) => {
      if (v.workerIndex.includes(i)) oldWorkerId.push(item.id);
    });
    preSelectedWorker.value.forEach((item, i) => {
      if (selectedWorker.value.find((n) => item.id === n.id)) return;
      newWorkerIndex.push(i);
    });

    v.workerIndex = oldWorkerId
      .map((id) => preSelectedWorker.value.findIndex((item) => item.id === id))
      .filter((idx) => idx !== -1)
      .concat(newWorkerIndex);
  });

  refSelectZoneEmployee.value?.assignSelect(
    selectedWorker.value,
    preSelectedWorker.value,
  );
  pageState.employeeModal = false;
}

function changeMode(mode: string) {
  if (mode === 'light') {
    localStorage.setItem('currentTheme', 'light');
    $q.dark.set(false);
    return;
  }

  if (mode === 'dark') {
    localStorage.setItem('currentTheme', 'dark');
    $q.dark.set(true);
    return;
  }

  if (mode === 'baseOnDevice') {
    localStorage.setItem('currentTheme', 'baseOnDevice');
    if (
      window.matchMedia &&
      window.matchMedia('(prefers-color-scheme: dark)').matches
    ) {
      $q.dark.set(true);
    } else {
      $q.dark.set(false);
    }
    return;
  }
}

const sessionData = ref<Record<string, any>>();

onMounted(async () => {
  await configStore.getConfig();
  // get language
  const getCurLang = localStorage.getItem('currentLanguage');
  if (getCurLang === 'English') {
    locale.value = 'eng';
    setLocale('en-gb');
  }
  if (getCurLang === 'ไทย') {
    locale.value = 'tha';
    setLocale('th');
  }

  // get theme
  const getCurTheme = localStorage.getItem('currentTheme');
  if (
    getCurTheme === 'light' ||
    getCurTheme === 'dark' ||
    getCurTheme === 'baseOnDevice'
  ) {
    changeMode(getCurTheme);
  } else {
    changeMode('light');
  }

  sessionStorage.setItem(
    'new-quotation',
    localStorage.getItem('new-quotation') ||
      sessionStorage.getItem('new-quotation') ||
      '',
  );

  localStorage.removeItem('new-quotation');
  const payload = sessionStorage.getItem('new-quotation');

  if (!!payload) {
    const parsed = JSON.parse(payload);
    date.value = Date.now();
    quotationFormState.value.mode = parsed.statusDialog;
    quotationFormData.value.registeredBranchId = parsed.branchId;
    quotationFormData.value.customerBranchId = parsed.customerBranchId;
    currentQuotationId.value = parsed.quotationId;
    agentPrice.value = parsed.agentPrice;
    if (
      currentQuotationId.value !== undefined &&
      quotationFormState.value.mode &&
      quotationFormState.value.mode !== 'create'
    ) {
      await quotationForm.assignFormData(
        currentQuotationId.value,
        quotationFormState.value.mode,
      );
      await assignWorkerToSelectedWorker();
    }
    sessionData.value = parsed;
  }

  // fetch option
  const resultOption = await fetch('/option/option.json');
  const rawOption = await resultOption.json();
  if (locale.value === 'eng') optionStore.globalOption = rawOption.eng;
  if (locale.value === 'tha') optionStore.globalOption = rawOption.tha;

  await assignToProductServiceList();

  pageState.isLoaded = true;
});

watch(
  () => quotationFormData.value.customerBranchId,
  async (v) => {
    if (!v) return;

    const retEmp = await customerStore.fetchBranchEmployee(v, {
      passport: true,
    });

    if (retEmp) workerList.value = retEmp.data.result;
  },
);

watch(
  () => quotationFormData.value.registeredBranchId,
  async (v) => {
    if (!pageState.isLoaded) return;
    const url = new URL(window.location.href);
    url.searchParams.set('branchId', v);
    history.pushState({}, '', url.toString());
  },
);

const productServiceNodes = ref<ProductTree>([]);

watch(
  () => productServiceList.value,
  () => {
    productServiceNodes.value = quotationProductTree(productServiceList.value);
  },
);

async function searchEmployee(text: string) {
  let query: string | undefined = text;
  let pageSize = 50;

  if (!text) {
    query = undefined;
    pageSize = 9999;
  }

  const retEmp = await customerStore.fetchBranchEmployee(
    quotationFormData.value.customerBranchId,
    {
      query: query,
      pageSize: pageSize,
    },
  );
  if (retEmp) workerList.value = retEmp.data.result;
}

function storeDataLocal() {
  quotationFormData.value.productServiceList = productServiceList.value;

  localStorage.setItem(
    'quotation-preview',
    JSON.stringify({
      data: quotationFormData.value,
      meta: {
        source: {
          ...quotationFormState.value.source,
          code:
            quotationFormState.value.mode === 'create'
              ? '-'
              : quotationFormState.value?.source?.code,
          createAt:
            quotationFormState.value.mode === 'create'
              ? Date.now()
              : quotationFormState.value?.source?.createdAt,
          createBy: quotationFormState.value?.source?.createdBy,
          payCondition: quotationFormData.value.payCondition,
          contactName: quotationFormData.value.contactName,
          contactTel: quotationFormData.value.contactTel,
          workName: quotationFormData.value.workName,
          dueDate: quotationFormData.value.dueDate,
        },
        createdBy: quotationFormState.value.createdBy('tha'),
      },
    }),
  );

  window.open('/quotation/document-view', '_blank');
}

const statusQuotationForm = ref<
  { title: string; status: 'done' | 'doing' | 'waiting' }[]
>([
  {
    title: 'ใบเสนอราคา',
    status: 'doing',
  },
  {
    title: 'ลูกค้าตอบรับ',
    status: 'waiting',
  },
  {
    title: 'ใบแจ้งหนี้',
    status: 'waiting',
  },
  {
    title: 'ชำระเงิน',
    status: 'waiting',
  },
  {
    title: 'ใบเสร็จรับเงิน',
    status: 'waiting',
  },
  {
    title: 'เสร็จสิ้น',
    status: 'waiting',
  },
]);
</script>

<template>
  <div class="column surface-0 fullscreen">
    <div class="color-bar">
      <div class="orange-segment"></div>
      <div class="yellow-segment"></div>
      <div class="gray-segment"></div>
    </div>

    <header class="row q-px-md q-py-sm items-center full">
      <div style="flex: 1" class="row items-center">
        <q-img src="/icons/favicon-512x512.png" width="3rem" />
        <span class="column text-h6 text-bold q-ml-md">
          {{ $t('quotation.title') }}
          <span class="text-caption text-regular app-text-muted">
            {{
              $t('quotation.processOn', {
                msg:
                  quotationFormState.mode === 'create'
                    ? `${dateFormat(date, true)} ${dateFormat(date, true, true)}`
                    : `${dateFormat(quotationFull?.createdAt, true)} ${dateFormat(quotationFull?.createdAt, true, true)}`,
              })
            }}
          </span>
        </span>
      </div>

      <div
        v-if="quotationFormState.mode !== 'create'"
        class="column col-2"
        style="gap: 10px"
      >
        <div class="row justify-end">
          <BadgeCompoent :title-i18n="$t('general.laborIdentified')" />
        </div>
        <div
          class="row items-center justify-between surface-1 rounded q-pa-xs"
          style="height: 40px; border-radius: 40px"
        >
          <div class="full-height full-width row">
            <div
              class="col-6 flex flex-center"
              style="
                color: white;
                background: linear-gradient(to right, #035aa1 0%, #14ab35 100%);
                border-radius: 20px;
                gap: 10px;
              "
            >
              <q-icon name="mdi-calendar-range" />
              {{ $t('quotation.receiptDialog.remain') }}
            </div>
            <div class="col-6 flex flex-center">
              <span
                v-if="calculateDaysUntilExpire(quotationFormData.dueDate) <= 0"
              >
                {{
                  $t(
                    `general.${
                      calculateDaysUntilExpire(quotationFormData.dueDate) > 0
                        ? 'beDue'
                        : calculateDaysUntilExpire(
                              quotationFormData.dueDate,
                            ) === 0
                          ? 'due'
                          : 'overDue'
                    }`,
                  )
                }}
              </span>

              <span v-else>
                {{ calculateDaysUntilExpire(quotationFormData.dueDate) }}
                {{ $t('general.day') }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </header>

    <article
      class="col full-width q-pa-md"
      style="flex-grow: 1; overflow-y: auto"
    >
      <section class="col-sm col-12">
        <div class="col q-gutter-y-md">
          <div
            class="surface-1 q-pa-sm row"
            style="border-radius: var(--radius-2); gap: 10px"
          >
            <div
              v-for="value in statusQuotationForm"
              :key="value.title"
              class="q-pa-sm bordered status-color"
              :class="`status-color-${value.status}`"
              style="min-width: 120px"
            >
              <q-icon
                class="icon-color"
                :name="`${value.status === 'done' ? 'mdi-check-circle' : 'mdi-checkbox-blank-circle-outline'}`"
              />
              {{ value.title }}
            </div>
          </div>

          <q-expansion-item
            for="item-up"
            id="item-up"
            dense
            class="overflow-hidden"
            switch-toggle-side
            default-opened
            style="border-radius: var(--radius-2)"
            expand-icon="mdi-chevron-down-circle"
            header-class="surface-1"
          >
            <template v-slot:header>
              <section class="row items-center full-width">
                <div class="row items-center q-pr-md q-py-sm">
                  <span
                    class="text-weight-medium q-mr-md"
                    style="font-size: 18px"
                  >
                    {{ $t('general.document') }}
                  </span>
                </div>

                <q-checkbox
                  v-model="quotationFormData.urgent"
                  class="q-ml-auto"
                  size="xs"
                  :label="$t('general.urgent')"
                  :disable="readonly"
                />
              </section>
            </template>

            <div class="surface-1 q-pa-md full-width">
              <QuotationFormMetadata
                class="q-mb-md"
                :readonly
                :actor="quotationFormState.createdBy?.($i18n.locale) || ''"
                :quotation-no="(quotationFull && quotationFull.code) || ''"
                v-model:urgent="quotationFormData.urgent"
                v-model:work-name="quotationFormData.workName"
                v-model:contactor="quotationFormData.contactName"
                v-model:telephone="quotationFormData.contactTel"
                v-model:document-receive-point="
                  quotationFormData.documentReceivePoint
                "
                v-model:due-date="quotationFormData.dueDate"
              >
                <template #issue-info>
                  <FormAbout
                    class="col-12 col-md-8"
                    input-only
                    v-model:branch-id="quotationFormData.registeredBranchId"
                    v-model:customer-branch-id="
                      quotationFormData.customerBranchId
                    "
                    :readonly="readonly"
                    @add-customer=""
                  />
                </template>
              </QuotationFormMetadata>
            </div>
          </q-expansion-item>
          <q-expansion-item
            for="item-up"
            id="item-up"
            dense
            class="overflow-hidden"
            switch-toggle-side
            default-opened
            style="border-radius: var(--radius-2)"
            expand-icon="mdi-chevron-down-circle"
            header-class="surface-1"
          >
            <template v-slot:header>
              <section class="row items-center full-width">
                <div class="row items-center q-pr-md q-py-sm">
                  <span
                    class="text-weight-medium q-mr-md"
                    style="font-size: 18px"
                  >
                    {{ $t('quotation.employeeList') }}
                  </span>
                  <template v-if="!readonly">
                    <ToggleButton class="q-mr-sm" v-model="toggleWorker" />
                    {{
                      toggleWorker
                        ? $t('general.specify')
                        : $t('general.noSpecify')
                    }}
                  </template>
                </div>
                <nav class="q-ml-auto">
                  <AddButton
                    v-if="!readonly"
                    icon-only
                    @click.stop="triggerSelectEmployeeDialog"
                  />
                </nav>
              </section>
            </template>

            <div class="surface-1 q-pa-md full-width">
              <WorkerItem
                :employee-amount="selectedWorker.length"
                :readonly="readonly"
                fallback-img="/images/employee-avatar.png"
                :rows="
                  selectedWorker.map((e: Employee) => ({
                    foreignRefNo: e.employeePassport
                      ? e.employeePassport[0]?.number || '-'
                      : '-',
                    employeeName:
                      $i18n.locale === 'eng'
                        ? `${e.firstNameEN} ${e.lastNameEN}`
                        : `${e.firstName} ${e.lastName}`,
                    birthDate: dateFormat(e.dateOfBirth),
                    gender: e.gender,
                    age: calculateAge(e.dateOfBirth),
                    nationality: optionStore.mapOption(e.nationality),
                    documentExpireDate: e.employeePassport
                      ? dateFormat(e.employeePassport[0]?.expireDate) || '-'
                      : '-',
                    imgUrl: `${baseUrl}/customer/${e.id}/image/${e.selectedImage}`,
                    status: e.status,
                  }))
                "
                @delete="(i) => deleteItem(selectedWorker, i)"
              />
            </div>
          </q-expansion-item>

          <q-expansion-item
            for="item-up"
            id="item-up"
            dense
            class="overflow-hidden"
            switch-toggle-side
            default-opened
            style="border-radius: var(--radius-2)"
            expand-icon="mdi-chevron-down-circle"
            header-class="surface-1"
          >
            <template v-slot:header>
              <section class="row items-center full-width">
                <div class="row items-center q-pr-md q-py-sm">
                  <span class="text-weight-medium" style="font-size: 18px">
                    {{ $t('quotation.productList') }}
                  </span>
                </div>
                <nav class="q-ml-auto">
                  <AddButton
                    v-if="!readonly"
                    icon-only
                    class="q-ml-auto"
                    @click.stop="triggerProductServiceDialog"
                  />
                </nav>
              </section>
            </template>
            <div class="surface-1 q-pa-md full-width">
              <ProductItem
                :readonly="readonly"
                :agent-price="agentPrice"
                :employee-rows="
                  selectedWorker.map((e: Employee) => ({
                    foreignRefNo: '123456789',
                    employeeName:
                      $i18n.locale === 'eng'
                        ? `${e.firstNameEN} ${e.lastNameEN}`
                        : `${e.firstName} ${e.lastName}`,
                    birthDate: dateFormat(e.dateOfBirth),
                    gender: e.gender,
                    age: calculateAge(e.dateOfBirth),
                    nationality: optionStore.mapOption(e.nationality),
                    documentExpireDate: '1234',
                    imgUrl: `${baseUrl}/customer/${e.id}/image/${e.selectedImage}`,
                    status: e.status,
                  }))
                "
                @delete="toggleDeleteProduct"
                v-model:rows="productServiceList"
              />
            </div>
          </q-expansion-item>
          <q-expansion-item
            for="item-up"
            id="item-up"
            dense
            class="overflow-hidden"
            switch-toggle-side
            default-opened
            style="border-radius: var(--radius-2)"
            expand-icon="mdi-chevron-down-circle"
            header-class="surface-1"
          >
            <template v-slot:header>
              <section class="row items-center full-width">
                <div class="row items-center q-pr-md q-py-sm">
                  <span
                    class="text-weight-medium q-mr-md"
                    style="font-size: 18px"
                  >
                    {{ $t('general.payment') }}
                  </span>
                </div>
              </section>
            </template>

            <div class="surface-1 q-pa-md full-width">
              <QuotationFormInfo
                v-model:pay-type="quotationFormData.payCondition"
                v-model:pay-bank="payBank"
                v-model:pay-split-count="quotationFormData.paySplitCount"
                v-model:pay-split="quotationFormData.paySplit"
                :readonly
                v-model:final-discount="quotationFormData.discount"
                v-model:pay-bill-date="quotationFormData.payBillDate"
                v-model:summary-price="summaryPrice"
                class="q-mb-md"
              />

              <span class="text-weight-medium q-mr-md" style="font-size: 18px">
                {{ $t('general.remark') }}
              </span>
              <hr
                style="border: 1px solid var(--border-color)"
                class="q-mb-md"
              />
              <q-editor
                dense
                :readonly
                :model-value="quotationFormData.remark || ''"
                min-height="5rem"
                class="full-width"
                toolbar-bg="input-border"
                style="cursor: auto; color: var(--foreground)"
                :flat="!readonly"
                :style="`width: ${$q.screen.gt.xs ? '100%' : '63vw'}`"
                :toolbar="[['left', 'center', 'justify'], ['clip']]"
                :toolbar-toggle-color="readonly ? 'disabled' : 'primary'"
                :toolbar-color="
                  readonly ? 'disabled' : $q.dark.isActive ? 'white' : ''
                "
                :definitions="{
                  clip: {
                    icon: 'mdi-paperclip',
                    tip: 'Upload',
                    handler: () => console.log('upload'),
                  },
                }"
                @update:model-value="
                  (v) => {
                    quotationFormData.remark = v;
                  }
                "
              />
            </div>
          </q-expansion-item>
        </div>
      </section>
    </article>

    <footer class="surface-1 q-pa-md full-width">
      <div class="row full-width justify-between">
        <MainButton
          outlined
          icon="mdi-play-box-outline"
          color="207 96% 32%"
          @click="storeDataLocal"
        >
          {{ $t('general.view', { msg: $t('general.example') }) }}
        </MainButton>
        <div class="row" style="gap: var(--size-2)">
          <UndoButton
            outlined
            @click="closeTab()"
            v-if="quotationFormState.mode === 'edit'"
          />
          <CloseButton
            outlined
            @click="closeTab()"
            v-if="quotationFormState.mode === 'info' && closeAble()"
          />
          <SaveButton
            v-if="
              quotationFormState.mode === 'create' ||
              quotationFormState.mode === 'edit'
            "
            @click="
              () => {
                convertDataToFormSubmit();
              }
            "
            solid
          />
          <EditButton
            v-else
            class="no-print"
            @click="quotationFormState.mode = 'edit'"
            solid
          />
        </div>
      </div>
    </footer>

    <!-- SEC: Dialog -->
    <!-- add employee quotation -->
    <DialogForm
      :title="$t('general.select', { msg: $t('quotation.employeeList') })"
      v-model:modal="pageState.employeeModal"
      :submit-label="$t('general.select', { msg: $t('quotation.employee') })"
      submit-icon="mdi-check"
      height="75vh"
      :submit="() => convertEmployeeToTable()"
      :close="
        () => {
          (preSelectedWorker = []), (pageState.employeeModal = false);
        }
      "
    >
      <section class="col row scroll">
        <SelectZone
          ref="refSelectZoneEmployee"
          v-model:selected-item="preSelectedWorker"
          @search="
            (v) => {
              searchEmployee(v);
            }
          "
          :items="workerList"
          :new-items="newWorkerList"
        >
          <template #top>
            <AddButton
              icon-only
              @click="
                () => {
                  triggerCreateEmployee();
                }
              "
            />
          </template>
          <template #data="{ item }">
            <PersonCard
              noAction
              prefixId="asda"
              class="full-width"
              :data="{
                name:
                  $i18n.locale === 'eng'
                    ? `${item.firstNameEN} ${item.lastNameEN}`
                    : `${item.firstName} ${item.lastName}`,
                code: item.code,
                female: item.gender === 'female',
                male: item.gender === 'male',
                img: `${baseUrl}/customer/${item.id}/image/${item.selectedImage}`,
                fallbackImg: '/images/employee-avatar.png',
                detail: [
                  {
                    icon: 'mdi-passport',
                    value: optionStore.mapOption(item.nationality),
                  },
                  {
                    icon: 'mdi-clock-outline',
                    value: calculateAge(item.dateOfBirth),
                  },
                ],
              }"
            ></PersonCard>
          </template>

          <template #newData="{ item }">
            <PersonCard
              noAction
              prefixId="asda"
              class="full-width"
              :data="{
                name:
                  $i18n.locale === 'eng'
                    ? `${item.firstNameEN} ${item.lastNameEN}`
                    : `${item.firstName} ${item.lastName}`,
                code: item.code,
                female: item.gender === 'female',
                male: item.gender === 'male',
                img: `${baseUrl}/customer/${item.id}/image/${item.selectedImage}`,
                fallbackImg: '/images/employee-avatar.png',
                detail: [
                  {
                    icon: 'mdi-passport',
                    value: optionStore.mapOption(item.nationality),
                  },
                  {
                    icon: 'mdi-clock-outline',
                    value: calculateAge(item.dateOfBirth),
                  },
                ],
              }"
            ></PersonCard>
          </template>
        </SelectZone>
      </section>
    </DialogForm>

    <!-- add product service -->

    <ProductServiceForm
      v-model="pageState.productServiceModal"
      v-model:nodes="productServiceNodes"
      v-model:product-group="productGroup"
      v-model:product-list="productList"
      v-model:service-list="serviceList"
      v-model:selected-product-group="selectedProductGroup"
      :agent-price="agentPrice"
      @submit="convertToTable"
      @select-group="
        async (id) => {
          await getAllService(id);
          await getAllProduct(id);
        }
      "
      @search="
        (id, text, mode) => {
          if (mode === 'service') {
            getAllService(id, { force: true, query: text, pageSize: 50 });
          }
          if (mode === 'product') {
            getAllProduct(id, { force: true, query: text, pageSize: 50 });
          }
        }
      "
    ></ProductServiceForm>
  </div>

  <!-- NOTE: START - Employee Add Form -->

  <DialogForm
    hide-footer
    ref="formDialogRef"
    v-model:modal="employeeFormState.dialogModal"
    :title="$t('form.title.create', { name: $t('customer.employee') })"
    :submit="
      () => {
        quotationForm.injectNewEmployee({ data: formDataEmployee }, () =>
          setDefaultFormEmployee(),
        );
      }
    "
    :close="
      () => {
        employeeFormState.dialogModal = false;
      }
    "
  >
    <div
      :class="{
        'q-mx-lg q-my-md': $q.screen.gt.sm,
        'q-mx-md q-my-sm': !$q.screen.gt.sm,
      }"
    >
      <ProfileBanner
        active
        useToggle
        color="white"
        icon="mdi-account-plus-outline"
        :bg-color="
          employeeFormState.profileUrl
            ? 'white'
            : 'linear-gradient(135deg, rgba(43,137,223,1) 0%, rgba(230,51,81,1) 100%)'
        "
        v-model:current-tab="employeeFormState.currentTab"
        v-model:toggle-status="currentFromDataEmployee.status"
        fallbackCover="/images/employee-banner.png"
        :img="employeeFormState.profileUrl || `/images/employee-avatar.png`"
        :toggleTitle="$t('status.title')"
        hideFade
        @view="
          () => {
            employeeFormState.imageDialog = true;
            employeeFormState.isImageEdit = false;
          }
        "
        @edit="
          employeeFormState.imageDialog = employeeFormState.isImageEdit = true
        "
        @update:toggle-status="
          () => {
            currentFromDataEmployee.status =
              currentFromDataEmployee.status === 'CREATED'
                ? 'INACTIVE'
                : 'CREATED';
          }
        "
      />
    </div>
    <div
      class="col"
      :class="{
        'q-px-lg q-pb-lg': $q.screen.gt.sm,
        'q-px-md q-pb-sm': !$q.screen.gt.sm,
      }"
    >
      <div
        style="overflow-y: auto"
        class="row full-width full-height surface-1 rounded bordered relative-position"
      >
        <div
          :class="{
            'q-py-md q-px-lg': $q.screen.gt.sm,
            'q-py-sm q-px-lg': !$q.screen.gt.sm,
          }"
          style="position: absolute; z-index: 99999; top: 0; right: 0"
        >
          <div
            v-if="currentFromDataEmployee.status !== 'INACTIVE'"
            class="surface-1 row rounded"
          >
            <UndoButton
              v-if="
                employeeFormState.isEmployeeEdit &&
                employeeFormState.dialogType !== 'create'
              "
              id="btn-info-basic-undo"
              icon-only
              @click="
                () => {
                  employeeFormStore.resetFormDataEmployee();
                  employeeFormState.isEmployeeEdit = false;
                  employeeFormState.dialogType = 'info';
                }
              "
              type="button"
            />
            <SaveButton
              v-if="employeeFormState.isEmployeeEdit"
              id="btn-info-basic-save"
              icon-only
              type="submit"
            />
            <EditButton
              v-if="!employeeFormState.isEmployeeEdit"
              id="btn-info-basic-edit"
              icon-only
              @click="
                () => {
                  employeeFormState.isEmployeeEdit = true;
                  employeeFormState.dialogType = 'edit';
                }
              "
              type="button"
            />
            <DeleteButton
              v-if="!employeeFormState.isEmployeeEdit"
              id="btn-info-basic-delete"
              icon-only
            />
          </div>
        </div>

        <div
          class="col-12 full-height q-col-gutter-sm q-py-md q-pl-md q-pr-sm"
          :class="{
            'q-py-md q-pr-md ': $q.screen.gt.sm,
            'q-py-md q-px-lg': !$q.screen.gt.sm,
          }"
          id="branch-form"
          style="overflow-y: auto"
        >
          <FormReferDocument
            title="form.field.basicInformation"
            prefixId="dialog"
            dense
            v-model:passport-no="formDataEmployee.passportNo"
            v-model:document-expire-date="formDataEmployee.documentExpireDate"
            class="q-mb-md"
          />

          <FormPerson
            id="form-personal"
            prefix-id="form-employee"
            dense
            outlined
            employee
            separator
            hideNameEn
            title="personnel.form.personalInformation"
            class="q-mb-md"
            v-model:prefix-name="formDataEmployee.namePrefix"
            v-model:first-name="formDataEmployee.firstName"
            v-model:mid-name="formDataEmployee.middleName"
            v-model:last-name="formDataEmployee.lastName"
            v-model:birth-date="formDataEmployee.dateOfBirth"
            v-model:gender="formDataEmployee.gender"
            v-model:nationality="formDataEmployee.nationality"
          />

          <UploadFileGroup
            show-title
            v-model="formDataEmployee.attachment"
            hide-action
            @submit="
              async (group, allMeta) => {
                if (allMeta === undefined) return;

                if (group === 'passport') {
                  const fullName = allMeta['full_name'].split(' ');
                  let tempValue: {
                    oldData: { nameField: string; value: string }[];
                    newData: { nameField: string; value: string }[];
                  } = { oldData: [], newData: [] };

                  if (
                    formDataEmployee.gender !== '' &&
                    formDataEmployee.gender !== allMeta['sex']
                  ) {
                    tempValue.oldData.push({
                      nameField: $t('form.gender'),
                      value: $t(`general.${formDataEmployee.gender}`),
                    });
                    tempValue.newData.push({
                      nameField: $t('form.gender'),
                      value: $t(`general.${allMeta['sex']}`),
                    });
                  }

                  if (formDataEmployee.firstName !== '') {
                    tempValue.oldData.push({
                      nameField: $t('personnel.form.firstName'),
                      value: formDataEmployee.firstName,
                    });
                    tempValue.newData.push({
                      nameField: $t('personnel.form.firstName'),
                      value: fullName[0],
                    });
                  }

                  if (formDataEmployee.lastName !== '') {
                    tempValue.oldData.push({
                      nameField: $t('personnel.form.lastName'),
                      value: formDataEmployee.lastName,
                    });
                    tempValue.newData.push({
                      nameField: $t('personnel.form.lastName'),
                      value: fullName[1],
                    });
                  }

                  if (formDataEmployee.passportNo !== '') {
                    tempValue.oldData.push({
                      nameField: $t('customerEmployee.form.passportNo'),
                      value: formDataEmployee.passportNo || '',
                    });
                    tempValue.newData.push({
                      nameField: $t('customerEmployee.form.passportNo'),
                      value: allMeta['doc_number'],
                    });
                  }

                  if (formDataEmployee.nationality !== '') {
                    tempValue.oldData.push({
                      nameField: $t('general.nationality'),
                      value: formDataEmployee.nationality || '',
                    });
                    tempValue.newData.push({
                      nameField: $t('general.nationality'),
                      value: allMeta['nationality'],
                    });
                  }

                  dialogCheckData({
                    action: async () => {
                      formDataEmployee.gender = allMeta['sex'];
                      formDataEmployee.firstName = fullName[0];
                      formDataEmployee.lastName = fullName[1];
                      formDataEmployee.passportNo = allMeta['doc_number'];
                      formDataEmployee.nationality = allMeta['nationality'];
                    },
                    checkData: () => {
                      return tempValue;
                    },
                    cancel: () => {
                      if (!formDataEmployee.firstName) {
                        formDataEmployee.gender = allMeta['gender'];
                      }
                      if (!formDataEmployee.firstName) {
                        formDataEmployee.firstName = fullName[0];
                      }
                      if (!formDataEmployee.firstName) {
                        formDataEmployee.firstName = fullName[0];
                      }
                      if (!formDataEmployee.lastName) {
                        formDataEmployee.lastName = fullName[1];
                      }
                      if (!formDataEmployee.passportNo) {
                        formDataEmployee.passportNo = allMeta['doc_number'];
                      }
                      if (!formDataEmployee.nationality) {
                        formDataEmployee.nationality = allMeta['nationality'];
                      }
                    },
                  });
                }
              }
            "
            :menu="uploadFileListEmployee"
            :columns="columnsAttachment"
            :ocr="
              async (group, file) => {
                if (group === 'passport') {
                  mrz = await runOcr(file, parseResultMRZ);

                  if (mrz !== null) {
                    const mapMrz = Object.entries(mrz.result || {}).map(
                      ([key, value]) => ({
                        name: key,
                        value: value,
                      }),
                    );
                    const tempValue = {
                      status: true,
                      group,
                      meta: mapMrz,
                    };

                    return tempValue;
                  }
                } else {
                  const res = await ocrStore.sendOcr({
                    file: file,
                    category: group,
                  });

                  if (res) {
                    const tempValue = {
                      status: true,
                      group,
                      meta: res.fields,
                    };

                    return tempValue;
                  }
                }

                return { status: true, group, meta: [] };
              }
            "
            :delete-item="
              async () => {
                return true;
              }
            "
            :get-file-list="
              async (group: 'passport' | 'visa') => {
                if (formDataEmployee.attachment !== undefined) {
                  const resMeta = formDataEmployee.attachment.filter(
                    (v) => v.group === group,
                  );

                  const tempValue = resMeta.map(async (i: any) => {
                    return {
                      _meta: { ...i._meta },
                      name: i.id || '',
                      group: group,
                      url: i.url,
                      file: undefined,
                    };
                  });

                  return await waitAll(tempValue);
                }
                return [];
              }
            "
          >
            <template #form="{ mode, meta, isEdit }">
              <FormEmployeePassport
                v-if="mode === 'passport' && meta"
                prefix-id="drawer-info-employee"
                id="form-passport"
                dense
                outlined
                separator
                ocr
                :title="$t('customerEmployee.form.group.passport')"
                :readonly="!isEdit"
                v-model:passport-type="meta.type"
                v-model:passport-number="meta.number"
                v-model:gender="meta.gender"
                v-model:first-name="meta.firstName"
                v-model:last-name="meta.lastName"
                v-model:passport-issue-date="meta.issueDate"
                v-model:passport-expiry-date="meta.expireDate"
                v-model:passport-issuing-place="meta.issuePlace"
                v-model:passport-issuing-country="meta.issueCountry"
              />
              <FormEmployeeVisa
                v-if="mode === 'visa' && meta"
                prefix-id="drawer-info-employee"
                id="form-visa"
                ocr
                dense
                outlined
                title="customerEmployee.form.group.visa"
                :readonly="!isEdit"
                v-model:visa-type="meta.type"
                v-model:visa-number="meta.number"
                v-model:visa-issue-date="meta.issueDate"
                v-model:visa-expiry-date="meta.expireDate"
                v-model:visa-issuing-place="meta.issuePlace"
              />

              <noticeJobEmployment v-if="mode === 'noticeJobEmployment'" />
            </template>
          </UploadFileGroup>
        </div>
      </div>
    </div>
  </DialogForm>

  <!-- NOTE: END - Employee Add Form -->
</template>

<style scoped>
.worker-list > :deep(*:not(:last-child)) {
  margin-bottom: var(--size-2);
}

.icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1/1;
  font-size: 1.5rem;
  padding: var(--size-1);
  border-radius: var(--radius-2);
}

.bg-color-orange {
  --_color: var(--yellow-7-hsl);
  color: white;
  background: hsla(var(--_color));
}

.dark .bg-color-orange {
  --_color: var(--orange-6-hsl);
}

.bg-color-orange-light {
  --_color: var(--yellow-7-hsl);
  background: hsla(var(--_color) / 0.2);
}
.dark .bg-color-orange {
  --_color: var(--orange-6-hsl / 0.2);
}

.color-bar {
  width: 100%;
  height: 1vh;
  background: linear-gradient(
    90deg,
    rgba(245, 159, 0, 1) 0%,
    rgba(255, 255, 255, 1) 77%,
    rgba(204, 204, 204, 1) 100%
  );
  display: flex;
  overflow: hidden;
}

.orange-segment {
  background-color: var(--yellow-7);
  flex-grow: 4;
}

.yellow-segment {
  background-color: hsla(var(--yellow-7-hsl) / 0.2);
  flex-grow: 0.5;
}

.gray-segment {
  background-color: #ccc;
  flex-grow: 1;
}

.orange-segment,
.yellow-segment,
.gray-segment {
  transform: skewX(-60deg);
}

:deep(i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon) {
  color: hsl(var(--text-mute));
}

:deep(
    i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
  ) {
  color: var(--brand-1);
}

:deep(.q-editor__toolbar-group):nth-child(2) {
  margin-left: auto !important;
}

:deep(.q-editor__toolbar.row.no-wrap.scroll-x) {
  background-color: var(--surface-2) !important;
}

:deep(.q-editor__toolbar) {
  border-color: var(--surface-3) !important;
}

:deep(
    .q-item.q-item-type.row.no-wrap.q-item--dense.q-item--clickable.q-link.cursor-pointer.q-focusable.q-hoverable.surface-1
      .q-focus-helper
  ) {
  visibility: hidden;
}

.status-color {
  --_color: var(--gray-0);
  border-color: hsla(var(--_color));
  background: hsla(var(--_color) / 0.05);
  border-radius: 4px;

  .icon-color {
    color: hsla(var(--_color));
  }

  &.status-color-done {
    --_color: var(--green-5-hsl);
  }
  &.status-color-doing {
    --_color: var(--blue-5-hsl);
  }
  &.status-color-waiting {
    --_color: var(--gray-4-hsl);
    color: hsla(var(--_color));
  }
}
</style>
