<script setup lang="ts">
// NOTE: Library
import { onMounted, reactive, ref, watch, computed, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';

// NOTE:  Components
import DataDisplay from 'src/components/08_request-list/DataDisplay.vue';
import DocumentExpansion from './DocumentExpansion.vue';
import FormExpansion from './FormExpansion.vue';
import PropertiesExpansion from './PropertiesExpansion.vue';
import FormGroupHead from './FormGroupHead.vue';

// NOTE: Store
import { dateFormatJS } from 'src/utils/datetime';
import { useRequestList } from 'src/stores/request-list';
import {
  RequestData,
  RequestWork,
  Attributes,
  DocStatus,
  Step,
  RequestWorkStatus,
} from 'src/stores/request-list/types';
import useOptionStore from 'src/stores/options';
import ProductExpansion from './ProductExpansion.vue';
import { useRoute } from 'vue-router';
import { useWorkflowTemplate } from 'src/stores/workflow-template';
import { WorkflowTemplate } from 'src/stores/workflow-template/types';
import { initLang, initTheme, Lang } from 'src/utils/ui';
import {
  EmployeePassportPayload,
  EmployeeVisaPayload,
} from 'stores/employee/types';
import {
  PropDate,
  PropNumber,
  PropOptions,
  PropString,
} from 'src/stores/product-service/types';
import { Invoice } from 'src/stores/payment/types';

const { locale } = useI18n();

// NOTE: Variable
const route = useRoute();
const optionStore = useOptionStore();
const requestListStore = useRequestList();
const flowTemplateStore = useWorkflowTemplate();

const workList = ref<RequestWork[]>();
const statusFile = ref<Attributes>({
  customer: {},
  employee: {},
});

const refDocumentExpansion = ref<InstanceType<typeof DocumentExpansion>[]>([]);
const data = ref<RequestData>();
const flow = ref<WorkflowTemplate>();
const pageState = reactive({
  hideMetaData: false,
  currentStep: 1,
});

// NOTE: Function

async function fetchRequestWorkList(opts: { requestDataId: string }) {
  const res = await requestListStore.getRequestWorkList({
    requestDataId: opts.requestDataId,
    pageSize: 9999,
  });

  if (res) {
    workList.value = res.result;
  }
}

function getCustomerName(
  record: RequestData,
  opts?: {
    locale?: string;
    noCode?: boolean;
  },
) {
  const customer = record.quotation.customerBranch;

  return (
    {
      ['CORP']: {
        [Lang.English]: customer.registerNameEN,
        [Lang.Thai]: customer.registerName,
      }[opts?.locale || 'eng'],
      ['PERS']:
        {
          [Lang.English]: `${optionStore.mapOption(customer.namePrefix)} ${customer.firstNameEN} ${customer.lastNameEN}`,
          [Lang.Thai]: `${optionStore.mapOption(customer.namePrefix)} ${customer.firstName} ${customer.lastName}`,
        }[opts?.locale || Lang.English] || '-',
    }[customer.customer.customerType] +
    (opts?.noCode ? '' : ' ' + `(${customer.code})`)
  );
}

function getEmployeeName(
  record: RequestData,
  opts?: {
    locale?: string;
  },
) {
  const employee = record.employee;

  return (
    {
      [Lang.English]: `${optionStore.mapOption(employee.namePrefix)} ${employee.firstNameEN} ${employee.lastNameEN}`,
      [Lang.Thai]: `${optionStore.mapOption(employee.namePrefix)} ${employee.firstName} ${employee.lastName}`,
    }[opts?.locale || Lang.English] || '-'
  );
}

async function getData() {
  const current = route.params['requestListId'];

  if (typeof current === 'string') {
    const res = await requestListStore.getRequestData(current);

    if (res) {
      data.value = res;
      await fetchRequestWorkList({ requestDataId: current });
      await getFlow();
    }
  }
}

async function getFlow() {
  if (!workList.value) return;

  const attr = workList.value.find((v) => !!v.productService.work?.attributes)
    ?.productService.work?.attributes;

  if (attr && Object.hasOwn(attr, 'workflowId')) {
    const workflowId = attr['workflowId'];

    const res = await flowTemplateStore.getWorkflowTemplate(workflowId);

    if (res) flow.value = res;
  }
}

onMounted(async () => {
  initTheme();
  initLang();

  // get data
  await getData();
});

watch(() => route.params['requestListId'], getData);

async function triggerChangeStatusWork(step: Step) {
  const res = await requestListStore.editStatusRequestWork(step);
  if (res) {
    const indexWork = workList.value?.findIndex(
      (v) => v.id === step.requestWorkId,
    );
    if (indexWork === -1 || indexWork === undefined) return;
    if (workList.value === undefined) return;

    const indexStep = workList.value[indexWork].stepStatus.findIndex(
      (v) => v.step === step.step,
    );

    if (indexStep === -1) {
      workList.value[indexWork].stepStatus.push(res);
    }
    if (indexStep !== -1) {
      workList.value[indexWork].stepStatus[indexStep].workStatus =
        res.workStatus;
    }
  }
  await nextTick();

  if (successAll.value) {
    await requestListStore.editStatusRequestWork(step, !!successAll.value);
  }
}

async function triggerChangeStatusFile(opt: {
  index: number;
  id: string;
  documentType: string;
  status: DocStatus;
  type: 'customer' | 'employee';
}) {
  if (!workList.value) return;

  const workItem = workList.value[opt.index];
  if (!workItem || !workItem.attributes) {
    if (workItem) {
      workItem.attributes = { customer: {}, employee: {} };
    } else {
      return;
    }
  }

  const attributes = workItem.attributes;

  statusFile.value = attributes;
  if (!statusFile.value[opt.type]) {
    statusFile.value[opt.type] = {};
  }

  statusFile.value[opt.type]![opt.documentType] = opt.status;

  const res = await requestListStore.editRequestWork({
    id: opt.id,
    attributes: statusFile.value,
  });

  if (res) {
    workList.value[opt.index].attributes = res.attributes;
  }
}

async function triggerUpload(opt: {
  id: string;
  type: 'customer' | 'employee';
  group: string;
  file: File;
  form?: EmployeePassportPayload | EmployeeVisaPayload;
}) {
  const newName = `${opt.group}-${Date.now()}-${opt.file.name}`;

  const res = await requestListStore.uploadAttachmentRequest({
    ...opt,
    name: newName,
  });

  return !!res;
}

async function triggerViewFile(opt: {
  id: string;
  fileName: string;
  type: 'customer' | 'employee';
  group: string;
  download?: boolean;
}) {
  let url;
  url = await requestListStore.viewAttachmentRequest({
    id: opt.id,
    name: opt.fileName,
    type: opt.type,
    group: opt.group,
    download: opt.download,
  });

  if (!opt.download) window.open(url, '_blank');
}

const successAll = computed(() => {
  return !!flow.value?.step.every((_, i) => {
    return workList.value
      ?.filter((v) => {
        return v.productService.work?.attributes.workflowStep?.[
          i
        ]?.productsId.includes(v.productService.productId);
      })
      .every((v) => {
        const status = v.stepStatus.find(
          ({ step }) => step === i + 1,
        )?.workStatus;

        return (
          status === RequestWorkStatus.Completed ||
          status === RequestWorkStatus.Ended
        );
      });
  });
});

function getInstallmentInfo() {
  if (
    data.value?.quotation.payCondition === 'Full' ||
    data.value?.quotation.payCondition === 'BillFull'
  ) {
    return undefined;
  }

  const total = data.value?.quotation.paySplitCount || 0;
  const paid = data.value?.quotation.invoice?.reduce((a, c) => {
    if (c.payment?.paymentStatus === 'PaymentSuccess') {
      a += c.installments.length || 0;
    }
    return a;
  }, 0);

  return { total, paid };
}

function isInstallmentPaySuccess(installmentNo: number) {
  if (
    data.value?.quotation.payCondition === 'Full' ||
    data.value?.quotation.payCondition === 'BillFull'
  ) {
    return true;
  }

  const invoice = data.value?.quotation.invoice?.find((lhs) => {
    return lhs.installments?.some((rhs) => rhs.no === installmentNo);
  });

  return !!(invoice?.payment?.paymentStatus === 'PaymentSuccess');
}
</script>
<template>
  <div class="column surface-0 fullscreen" v-if="data">
    <!-- SEC: Header -->
    <header class="row q-px-md q-py-sm items-center full justify-between">
      <div style="flex: 1" class="row items-center">
        <RouterLink to="/request-list">
          <q-img src="/icons/favicon-512x512.png" width="3rem" />
        </RouterLink>
        <span class="column text-h6 text-bold q-ml-md">
          {{ $t('requestList.title') }}
          {{ data.code || '' }}
          <span class="text-caption text-regular app-text-muted">
            {{
              $t('quotation.processOn', {
                msg: dateFormatJS({ date: data.createdAt }),
              })
            }}
          </span>
        </span>
      </div>
    </header>

    <!-- SEC: Body -->
    <main 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" :key="pageState.currentStep">
          <!-- step -->
          <nav
            v-if="flow"
            class="surface-1 q-pa-sm row no-wrap full-width scroll rounded"
            style="gap: 10px"
          >
            <span
              v-if="
                workList?.every((v) =>
                  v.productService.work?.attributes?.workflowStep?.every(
                    (s) => {
                      s.attributes?.properties.length === 0;
                    },
                  ),
                )
              "
              class="app-text-muted q-py-sm"
            >
              {{ $t('requestList.noWorkflowTemplate') }}
            </span>
            <template v-for="(value, i) in flow.step" :key="value.id">
              <button
                v-if="
                  workList?.some(
                    (v) =>
                      v.productService.work?.attributes?.workflowStep?.[i]
                        ?.attributes.properties.length > 0,
                  )
                "
                class="status-color q-pa-sm bordered row items-center cursor-pointer no-wrap"
                style="text-wrap: nowrap"
                :class="{
                  ['status-color-done']: workList
                    ?.filter((v) => {
                      return v.productService.work?.attributes.workflowStep?.[
                        i
                      ]?.productsId.includes(v.productService.productId);
                    })
                    .every((v) => {
                      const status = v.stepStatus.find(
                        ({ step }) => step === i + 1,
                      )?.workStatus;

                      return (
                        status === RequestWorkStatus.Completed ||
                        status === RequestWorkStatus.Ended
                      );
                    }),
                  ['status-color-doing']: true,
                  ['step-status-active']: pageState.currentStep === value.order,
                }"
                @click="() => (pageState.currentStep = value.order)"
              >
                <!-- 'quotation-status-active': value.active?.(), -->
                <!-- @click="'waiting' !== 'waiting' && value.handler()" -->
                <div class="q-px-sm">
                  <q-icon
                    class="icon-color quotation-status"
                    style="border-radius: 50%"
                    :name="`${pageState.currentStep === value.order ? 'mdi-circle-slice-8' : 'mdi-checkbox-blank-circle-outline'}`"
                  />
                </div>
                <div class="text-left">{{ value.name }}</div>
              </button>
            </template>
          </nav>

          <!-- meta data -->
          <article class="surface-1 rounded">
            <div
              class="text-weight-bold row items-center no-wrap q-pa-sm"
              style="gap: 16px"
            >
              <q-img src="/images/quotation-avatar.png" width="42px" />
              <span class="ellipsis" style="font-size: 18px">
                {{ data.quotation.workName || '-' }}
              </span>
              <q-btn
                class="q-ml-sm"
                icon="mdi-pin-outline"
                color="primary"
                size="sm"
                flat
                dense
                rounded
                @click="pageState.hideMetaData = !pageState.hideMetaData"
                :style="pageState.hideMetaData ? 'rotate: 90deg' : ''"
                style="transition: 0.1s ease-in-out"
              />
            </div>
            <transition name="slide">
              <section
                v-if="!pageState.hideMetaData"
                class=""
                :class="{ row: $q.screen.gt.sm, column: $q.screen.lt.md }"
              >
                <FormGroupHead class="col-12">
                  {{ $t('requestList.ref') }}
                </FormGroupHead>
                <div
                  class="col-12 q-pa-sm"
                  :class="{
                    row: $q.screen.gt.sm,
                    'column q-gutter-y-sm': $q.screen.lt.md,
                  }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    :label="$t('requestList.quotationCode')"
                    :value="data.quotation.code || '-'"
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.invoiceCode')"
                    :value="
                      data.quotation?.invoice
                        ?.map((i: Invoice) => i.code)
                        .join(', ') || '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.receiptCode')"
                    :value="
                      data.quotation?.invoice
                        ?.flatMap((i: Invoice) => i.payment?.code || [])
                        .join(', ') || '-'
                    "
                  />
                  <div v-if="$q.screen.gt.sm" class="col"></div>
                </div>
                <FormGroupHead class="col-12">
                  {{ $t('quotation.employee') }}
                </FormGroupHead>
                <div
                  class="col-12 q-pa-sm"
                  :class="{
                    row: $q.screen.gt.sm,
                    'column q-gutter-y-sm': $q.screen.lt.md,
                  }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('customer.employer')"
                    :value="
                      getCustomerName(data, { locale: locale, noCode: true }) ||
                      '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('customer.employee')"
                    :value="
                      getEmployeeName(data, { locale: $i18n.locale }) || '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-passport"
                    :label="$t('customerEmployee.form.passportNo')"
                    :value="data.employee.employeePassport?.[0]?.number || '-'"
                  />
                  <div v-if="$q.screen.gt.sm" class="col"></div>
                </div>
                <!-- <div
                  class="col q-gutter-y-md"
                  :class="{ column: $q.screen.gt.sm, row: $q.screen.lt.md }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    :label="$t('requestList.requestListCode')"
                    :value="data.code || '-'"
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('customer.employer')"
                    :value="
                      getCustomerName(data, { locale: locale, noCode: true }) ||
                      '-'
                    "
                  />
                </div>
                <div
                  class="col q-gutter-y-md"
                  :class="{ column: $q.screen.gt.sm, row: $q.screen.lt.md }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    :label="$t('requestList.quotationCode')"
                    :value="data.quotation.code || '-'"
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('customer.employee')"
                    :value="
                      getEmployeeName(data, { locale: $i18n.locale }) || '-'
                    "
                  />
                </div>
                <div
                  class="col q-gutter-y-md"
                  :class="{ column: $q.screen.gt.sm, row: $q.screen.lt.md }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.invoiceCode')"
                    :value="
                      data.quotation?.invoice
                        ?.map((i: Invoice) => i.code)
                        .join(', ') || '-'
                    "
                  />
                  <span class="col"></span>
                </div>
                <div
                  class="col q-gutter-y-md"
                  :class="{ column: $q.screen.gt.sm, row: $q.screen.lt.md }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.receiptCode')"
                    :value="
                      data.quotation?.invoice
                        ?.flatMap((i: Invoice) => i.payment?.code || [])
                        .join(', ') || '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-passport"
                    :label="$t('customerEmployee.form.passportNo')"
                    :value="data.employee.employeePassport?.[0]?.number || '-'"
                  />
                </div>
                <div
                  class="col q-gutter-y-md"
                  :class="{ column: $q.screen.gt.sm, row: $q.screen.lt.md }"
                >
                  <DataDisplay
                    class="col"
                    icon="mdi-card-account-details-outline"
                    :label="$t('requestList.alienIdCard')"
                    :value="data.employee.nrcNo"
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('flow.responsiblePerson')"
                    :value="'-'"
                  />
                </div> -->
              </section>
            </transition>
          </article>
          <!-- product -->
          <template
            v-for="(value, index) in workList?.filter((v) =>
              v.productService.work?.attributes.workflowStep?.[
                pageState.currentStep - 1
              ]?.productsId.includes(v.productService.productId),
            )"
            :key="value"
          >
            <ProductExpansion
              :installment-info="getInstallmentInfo()"
              :pay-success="
                isInstallmentPaySuccess(value.productService.installmentNo)
              "
              :status="
                value.stepStatus?.find((v) => v.step === pageState.currentStep)
              "
              :img-url="`/product/${value.productService.productId}/image/${value.productService.product.selectedImage}`"
              :name="value.productService.product.name"
              :code="value.productService.product.code"
              :product="value.productService.product"
              @change-status="
                (v) => {
                  triggerChangeStatusWork({
                    workStatus: v.requestWorkStatus,
                    step:
                      v.step === undefined
                        ? pageState.currentStep
                        : v.step.step,
                    requestWorkId: value.id || '',
                  });
                }
              "
            >
              <template v-slot="{ product }">
                <section
                  class="column surface-1 q-px-sm bordered-t q-pb-sm q-gutter-y-sm"
                >
                  <DocumentExpansion
                    v-if="
                      value.productService.work?.attributes?.workflowStep[
                        pageState.currentStep - 1
                      ].attributes?.properties.some(
                        (v: PropString | PropNumber | PropDate | PropOptions) =>
                          v.fieldName === 'documentCheck',
                      )
                    "
                    ref="refDocumentExpansion"
                    :attributes="value.attributes"
                    @change-status="
                      (opt) => {
                        triggerChangeStatusFile({
                          index,
                          id: value.id || '',
                          documentType: opt.key || '',
                          status: opt.status,
                          type: opt.type || 'customer',
                        });
                      }
                    "
                    @view-doc="
                      (opt) => {
                        triggerViewFile({
                          id: opt.id,
                          fileName: opt.data.fileName,
                          type: opt.type,
                          group: opt.data.documentType,
                        });
                      }
                    "
                    @upload="
                      async (opt, done) => {
                        await triggerUpload({ ...opt });
                        await done(opt.type || 'customer');
                      }
                    "
                    @download="
                      (opt) => {
                        console.log(opt);

                        triggerViewFile({
                          id: opt.id,
                          fileName: opt.data.fileName,
                          type: opt.type,
                          group: opt.data.documentType,
                          download: true,
                        });
                      }
                    "
                    :current-id="{
                      customer: value.request.quotation.customerBranchId,
                      employee: value.request.employeeId,
                    }"
                    :listDocument="product?.document"
                  />
                  <FormExpansion
                    v-if="
                      value.productService.work?.attributes?.workflowStep[
                        pageState.currentStep - 1
                      ].attributes?.properties.some(
                        (v: PropString | PropNumber | PropDate | PropOptions) =>
                          v.fieldName === 'designForm',
                      )
                    "
                    :step="{
                      step: pageState.currentStep,
                      requestWorkId: value.id || '',
                    }"
                    :id="value.id"
                    :attributes-form="
                      value.stepStatus?.[pageState.currentStep - 1]?.attributes
                        ?.form
                    "
                    :responsible-area-district-id="
                      data.quotation.customerBranch.districtId
                    "
                  />
                  <PropertiesExpansion
                    :id="value.id"
                    :properties-to-show="
                      value.productService.work?.attributes.workflowStep[
                        pageState.currentStep - 1
                      ].attributes.properties
                    "
                    :attributes="value.attributes"
                  />
                </section>
              </template>
            </ProductExpansion>
          </template>
        </div>
      </section>
    </main>
  </div>
</template>
<style scoped>
.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-waiting {
    --_color: var(--gray-4-hsl);
    color: var(--foreground);
  }
  &.status-color-doing {
    --_color: var(--blue-5-hsl);
    color: var(--foreground);
  }
  &.status-color-done {
    --_color: var(--green-5-hsl);
    color: var(--foreground);
  }
}

.step-status-active {
  opacity: 1;
  font-weight: 600;
  transition: 1s box-shadow ease-in-out;
  animation: status 1s infinite;
}

@keyframes status {
  0% {
    box-shadow: 0x 0px 0px hsla(var(--_color) / 0.5);
  }
  50% {
    box-shadow: 0px 0px 1px 4px hsla(var(--_color) / 0.2);
  }
  100% {
    box-shadow: 0px 0px 4px 7px hsla(var(--_color) / 0);
  }
}
</style>
