<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 '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';
import AvatarGroup from 'src/components/shared/AvatarGroup.vue';
import { StateButton } from 'components/button';
import { CancelButton, MainButton, SaveButton } from 'components/button';
import DutyExpansion from './DutyExpansion.vue';
import MessengerExpansion from './MessengerExpansion.vue';
import RequestAction from './RequestAction.vue';
import DialogFormContainer from 'src/components/dialog/DialogFormContainer.vue';
import DialogHeader from 'src/components/dialog/DialogHeader.vue';
import FormCancel from './FormCancel.vue';

// NOTE: Store
import {
  baseUrl,
  dialog,
  getEmployeeName,
  getCustomerName,
  dialogWarningClose,
} from 'src/stores/utils';
import { dateFormatJS } from 'src/utils/datetime';
import { useRequestList } from 'src/stores/request-list';
import {
  RequestData,
  RequestWork,
  Attributes,
  DocStatus,
  Step,
  RequestWorkStatus,
  RequestDataStatus,
} 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 } from 'src/utils/ui';
import {
  EmployeePassportPayload,
  EmployeeVisaPayload,
} from 'stores/employee/types';
import { PropVariant } from 'src/stores/product-service/types';
import { Invoice } from 'src/stores/payment/types';

import { CreatedBy } from 'src/stores/types';
import { getUserId } from 'src/services/keycloak';
import { QuotationFull } from 'src/stores/quotations/types';

const { locale, t } = 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 productsList = computed(() =>
  workList.value
    ?.filter((v) =>
      v.productService.work?.attributes.workflowStep?.[
        pageState.currentStep - 1
      ]?.productsId.includes(v.productService.productId),
    )
    .map((v) => {
      const _props =
        v.productService.work?.attributes?.workflowStep[
          pageState.currentStep - 1
        ]?.attributes?.properties;
      return Object.assign(v, {
        _documentExpansion: _props.some(
          (v: PropVariant) => v.fieldName === 'documentCheck',
        ),
        _formExpansion: _props.some(
          (v: PropVariant) => v.fieldName === 'designForm',
        ),
        _dutyExpansion: _props.some((v: PropVariant) => v.fieldName === 'duty'),
        _messengerExpansion: _props.some(
          (v: PropVariant) => v.fieldName === 'messenger',
        ),
      });
    })
    .sort(
      (lhs, rhs) =>
        lhs.productService.installmentNo - rhs.productService.installmentNo,
    ),
);

const pageState = reactive({
  hideMetaData: false,
  currentStep: 1,
  requestActionDialog: false,
  rejectCancelDialog: false,
  rejectCancelReason: '',
  requestWorkId: '',
});

// NOTE: Function

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

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

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, responsibleUserId?: string) {
  if (step.workStatus === 'Ready' && !responsibleUserId) {
    dialog({
      color: 'warning',
      icon: 'mdi-alert',
      title: t('form.warning.title'),
      actionText: t('dialog.action.ok'),
      message: t('dialog.message.warningSelectDeliveryStaff'),
      action: async () => {
        await nextTick();
        return;
      },
    });
    return;
  }

  if (step.workStatus === 'RejectCancel') {
    pageState.rejectCancelDialog = true;
    pageState.rejectCancelReason = '';
    pageState.requestWorkId = step.requestWorkId;
    return;
  }

  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();
}

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 responsiblePersonList = computed(() => {
  const temp = workList.value?.reduce<Record<string, CreatedBy[]>>(
    (acc, curr: RequestWork) => {
      curr.productService.service?.workflow?.step.forEach((v) => {
        const key = v.order.toString();

        if (!acc[key]) acc[key] = v.responsiblePerson.map((v) => v.user);

        const current = acc[key];

        v.responsiblePerson.forEach((lhs) => {
          if (current.find((rhs) => rhs.id === lhs.userId)) return;
          current.push(lhs.user);
        });
      });

      return acc;
    },
    {},
  );

  return temp || {};
});

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');
}

function goToQuotation(
  quotation: QuotationFull,
  opt?: { tab?: string; id?: string; amount?: number },
) {
  const { tab, id, amount } = opt || {};
  const url = new URL('/quotation/view', window.location.origin);
  if (tab) {
    url.searchParams.append('tab', tab);
  }
  if (id) {
    url.searchParams.append('id', id);
  }
  if (amount) {
    url.searchParams.append('amount', amount.toString());
  }

  localStorage.setItem(
    'new-quotation',
    JSON.stringify({
      customerBranchId: quotation.customerBranchId,
      agentPrice: quotation.agentPrice,
      statusDialog: 'info',
      quotationId: opt && opt.id ? opt.id : quotation.id,
    }),
  );

  window.open(url.toString(), '_blank');
}

function goToDebitNote(opt?: { tab?: string; id?: string }) {
  const { tab, id } = opt || {};
  const url = new URL(
    `/debit-note/${id}?mode=info&tab=${tab}`,
    window.location.origin,
  );

  window.open(url.toString(), '_blank');
}

function closeTab() {
  dialogWarningClose(t, {
    message: t('dialog.message.close'),
    action: () => {
      window.close();
    },
    cancel: () => {},
  });
}

function openRequestAction() {
  pageState.requestActionDialog = true;
}

async function submitRequestAction(data: {
  form: { responsibleUserLocal: boolean; responsibleUserId: string };
  selected: { _work: RequestWork }[];
}) {
  const requestWorksId = data.selected.map((s) => s._work.id);

  const res = await requestListStore.actionRequestWork(
    route.params['requestListId'] as string,
    pageState.currentStep,
    requestWorksId.map((v) => ({
      responsibleUserId: data.form.responsibleUserId,
      responsibleUserLocal: data.form.responsibleUserLocal,
      requestWorkId: v!,
    })),
  );
  if (res) {
    await getData();
    pageState.requestActionDialog = false;
  }
}

async function submitRejectCancel() {
  const current = route.params['requestListId'];
  if (typeof current !== 'string') return;

  const res = await requestListStore.rejectRequestWork(
    current,
    pageState.requestWorkId,
    {
      reason: pageState.rejectCancelReason,
    },
  );

  if (res) {
    const indexWork = workList.value?.findIndex(
      (v) => v.id === pageState.requestWorkId,
    );

    workList.value[indexWork].rejectRequestCancel = true;
    workList.value[indexWork].rejectRequestCancelReason =
      pageState.rejectCancelReason;
    pageState.rejectCancelDialog = false;
  }
}
</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>
      <div class="row q-gutter-x-xl q-mr-xl">
        <div class="column">
          <span class="app-text-muted">
            {{ $t('requestList.salesRepresentative') }}
          </span>
          <span>
            {{ optionStore.mapOption(data.quotation.createdBy.namePrefix) }}

            {{
              $i18n.locale === 'eng'
                ? `${data.quotation.createdBy.firstNameEN} ${data.quotation.createdBy.lastNameEN}`
                : `${data.quotation.createdBy.firstName} ${data.quotation.createdBy.lastName}`
            }}
          </span>
        </div>
        <div class="column">
          <span class="app-text-muted">{{ $t('flow.responsiblePerson') }}</span>
          <span>
            <template
              v-if="responsiblePersonList[pageState.currentStep]?.length"
            >
              <AvatarGroup
                :data="
                  (responsiblePersonList[pageState.currentStep] || []).map(
                    (v) => ({
                      name:
                        $i18n.locale === 'eng'
                          ? `${v.firstNameEN} ${v.lastNameEN}`
                          : `${v.firstName} ${v.lastName}`,
                      imgUrl: !v.selectedImage
                        ? v.gender === 'male'
                          ? `/no-img-man.png`
                          : `/no-img-female.png`
                        : `${baseUrl}/user/${v.id}/profile-image/${v.selectedImage}`,
                    }),
                  )
                "
              />
            </template>
            <template v-else>-</template>
          </span>
        </div>
      </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: any) => {
                      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">
              <StateButton
                @click="() => (pageState.currentStep = value.order)"
                :status-waiting="
                  !workList
                    ?.filter((v) => {
                      return v.productService.work?.attributes.workflowStep?.[
                        i - 1
                      ]?.productsId.includes(v.productService.productId);
                    })
                    .every((v) => {
                      const status = v.stepStatus.find(
                        ({ step }) => step === i,
                      )?.workStatus;
                      return (
                        status === RequestWorkStatus.Completed ||
                        status === RequestWorkStatus.Ended ||
                        status === RequestWorkStatus.Canceled
                      );
                    })
                "
                :status-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 === RequestWorkStatus.Canceled ||
                        (data?.requestDataStatus === 'Canceled' && !status)
                      );
                    })
                "
                :status-active="pageState.currentStep === value.order"
                :label="value.name"
              />
              <!-- 'quotation-status-active': value.active?.(), -->
              <!-- @click="'waiting' !== 'waiting' && value.handler()" -->
            </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
                    clickable
                    class="col"
                    icon="mdi-file-document-outline"
                    :label="$t('requestList.quotationCode')"
                    :value="data.quotation.code || '-'"
                    @label-click="
                      data.quotation.isDebitNote
                        ? goToDebitNote({ id: data.quotation.id, tab: 'title' })
                        : goToQuotation(data.quotation)
                    "
                  />
                  <DataDisplay
                    clickable
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.invoiceCode')"
                    :value="
                      data.quotation?.invoice?.map((i: Invoice) => i.code)
                    "
                    @label-click="
                      (value: string, index: number | null) => {
                        if (!data || index === null) return;

                        data.quotation.isDebitNote
                          ? goToDebitNote({
                              id: data.quotation.id,
                              tab: 'payment',
                            })
                          : goToQuotation(data.quotation, {
                              tab: 'invoice',
                              id: data.quotation.id,
                              amount: data.quotation.invoice?.[index]?.amount,
                            });
                      }
                    "
                  />
                  <DataDisplay
                    clickable
                    class="col"
                    icon="mdi-file-document-outline"
                    tooltip
                    :label="$t('requestList.receiptCode')"
                    :value="
                      data.quotation?.invoice?.flatMap(
                        (i: Invoice) => i.payment?.code || [],
                      )
                    "
                    @click="
                      data.quotation.isDebitNote
                        ? goToDebitNote({
                            id: data.quotation.id,
                            tab: 'receipt',
                          })
                        : goToQuotation(data.quotation, { tab: 'receipt' })
                    "
                  />

                  <DataDisplay
                    v-if="data.quotation.isDebitNote"
                    clickable
                    class="col"
                    icon="mdi-file-document-outline"
                    :label="$t('requestList.referenceNo')"
                    :value="data.quotation.debitNoteQuotation.code || '-'"
                    @label-click="
                      goToQuotation(data.quotation, {
                        id: data.quotation.debitNoteQuotationId,
                      })
                    "
                  />

                  <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.quotation.customerBranch, {
                        locale: locale,
                        noCode: true,
                      }) || '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('customer.employee')"
                    :value="
                      getEmployeeName(data.employee, {
                        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>
                <FormGroupHead class="col-12">
                  {{ $t('general.contactName') }}
                </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('quotation.actor')"
                    :value="
                      getEmployeeName(data.quotation?.createdBy, {
                        locale: $i18n.locale,
                      }) || '-'
                    "
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-account-settings-outline"
                    :label="$t('quotation.contactName')"
                    :value="data.quotation?.contactName || '-'"
                  />
                  <DataDisplay
                    class="col"
                    icon="mdi-telephone-outline"
                    :label="$t('general.telephone')"
                    :value="data.quotation.contactTel || '-'"
                  />
                  <div v-if="$q.screen.gt.sm" class="col"></div>
                </div>
              </section>
            </transition>
          </article>
          <!-- product -->
          <template v-for="(value, index) in productsList" :key="value">
            <ProductExpansion
              :request-cancel="value.customerRequestCancel"
              :request-cancel-reason="value.customerRequestCancelReason"
              :reject-request-cancel="value.rejectRequestCancel"
              :reject-request-cancel-reason="value.rejectRequestCancelReason"
              :cancel="data.requestDataStatus === RequestDataStatus.Canceled"
              :readonly="
                data.requestDataStatus === RequestDataStatus.Canceled ||
                (responsiblePersonList &&
                  !!responsiblePersonList[pageState.currentStep]?.length &&
                  !responsiblePersonList[pageState.currentStep]?.find(
                    (v) => v.id === getUserId(),
                  ))
              "
              :order-able="value._messengerExpansion"
              :installment-info="getInstallmentInfo()"
              :pay-success="
                isInstallmentPaySuccess(value.productService.installmentNo)
              "
              :status="
                value.stepStatus?.find((v) => v.step === pageState.currentStep)
              "
              :installment-no="value.productService.installmentNo"
              :pay-condition="data?.quotation.payCondition"
              :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 || '',
                    },
                    value.stepStatus?.[pageState.currentStep - 1]
                      ?.responsibleUserId,
                  );
                }
              "
            >
              <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._documentExpansion"
                    :readonly="
                      data.requestDataStatus === RequestDataStatus.Canceled
                    "
                    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) => {
                        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"
                  />
                  <MessengerExpansion
                    v-if="value._messengerExpansion"
                    :readonly="
                      data.requestDataStatus === RequestDataStatus.Canceled
                    "
                    :step="{
                      step: pageState.currentStep,
                      requestWorkId: value.id || '',
                    }"
                    :id="value.id"
                    :attributes-form="
                      value.stepStatus[pageState.currentStep - 1]
                    "
                    :responsible-area-district-id="
                      data.quotation.customerBranch.districtId
                    "
                    @update-attributes="
                      (opt) => {
                        value.stepStatus[pageState.currentStep - 1] = opt;
                      }
                    "
                  />
                  <DutyExpansion
                    v-if="value._dutyExpansion"
                    :readonly="
                      data.requestDataStatus === RequestDataStatus.Canceled
                    "
                    :step="{
                      step: pageState.currentStep,
                      requestWorkId: value.id || '',
                    }"
                    :id="value.id"
                    :attributes-form="
                      value.stepStatus?.[pageState.currentStep - 1]
                    "
                  />
                  <FormExpansion
                    v-if="value._formExpansion"
                    :readonly="
                      data.requestDataStatus === RequestDataStatus.Canceled
                    "
                    :step="{
                      step: pageState.currentStep,
                      requestWorkId: value.id || '',
                    }"
                    :id="value.id"
                    :attributes-form="
                      value.stepStatus?.[pageState.currentStep - 1]
                    "
                  />
                  <PropertiesExpansion
                    :request-list-data="data"
                    :id="value.id"
                    :readonly="
                      data.requestDataStatus === RequestDataStatus.Canceled
                    "
                    :properties-to-show="
                      value.productService.work?.attributes.workflowStep[
                        pageState.currentStep - 1
                      ].attributes.properties
                    "
                    :attributes="value.attributes"
                  />
                </section>
              </template>
            </ProductExpansion>
          </template>
        </div>
      </section>
    </main>

    <!-- SEC: Footer -->
    <footer
      class="surface-1 q-pa-md full-width row justify-end"
      style="gap: var(--size-2)"
    >
      <CancelButton
        outlined
        @click="closeTab()"
        :label="$t('dialog.action.close')"
      />
      <MainButton
        v-if="productsList.some((v) => v._messengerExpansion)"
        solid
        icon="mdi-account-outline"
        color="207 96% 32%"
        @click="openRequestAction"
      >
        {{
          $t('general.manage', { text: $t('requestList.employeeMessenger') })
        }}
      </MainButton>
    </footer>
  </div>

  <RequestAction
    v-model="pageState.requestActionDialog"
    :work="workList"
    :responsible-district-id="data?.quotation.customerBranch.districtId || ''"
    @submit="submitRequestAction"
  />

  <DialogFormContainer
    width="60vw"
    height="40vh"
    v-model="pageState.rejectCancelDialog"
    @submit="() => submitRejectCancel()"
  >
    <template #header>
      <DialogHeader :title="$t('requestList.status.work.RejectCancel')" />
    </template>

    <section class="col q-pa-md scroll">
      <FormCancel v-model:reason="pageState.rejectCancelReason" />
    </section>

    <template #footer>
      <CancelButton
        class="q-ml-auto"
        outlined
        @click="() => (pageState.rejectCancelDialog = false)"
      />
      <SaveButton
        label="ยืนยัน"
        class="q-ml-sm"
        icon="mdi-check"
        solid
        type="submit"
      />
    </template>
  </DialogFormContainer>
</template>
<style scoped></style>
