<script setup lang="ts">
import { reactive, ref } from 'vue';

import OcrDialog from 'src/components/upload-file/OcrDialog.vue';
import { parseResultMRZ, runOcr } from 'src/utils/ocr';
import { useRequestList } from 'src/stores/request-list';

import {
  DocStatus,
  RowDocument,
  Attributes,
} from 'src/stores/request-list/types';
import MainButton from 'src/components/button/MainButton.vue';
import FormGroupHead from './FormGroupHead.vue';
import BadgeComponent from 'src/components/BadgeComponent.vue';
import FormEmployeePassport from 'components/03_customer-management/FormEmployeePassport.vue';
import FormEmployeeVisa from 'components/03_customer-management/FormEmployeeVisa.vue';
import { CancelButton, EditButton } from 'src/components/button';

import { docColumn } from './constants';
import { computed } from 'vue';
import { QTableSlots } from 'quasar';
import {
  EmployeePassportPayload,
  EmployeeVisaPayload,
} from 'stores/employee/types';

type Data = {
  id: string;
  key: string;
  type: 'customer' | 'employee';
  data: RowDocument & { fileName: string };
};

defineEmits<{
  (e: 'changeStatus', v: Partial<Data> & { status: DocStatus }): void;
  (e: 'viewDoc', v: Data): void;
  (
    e: 'upload',
    v: {
      id: string;
      file: File;
      form?: EmployeePassportPayload | EmployeeVisaPayload;
      group: string;
      type: 'customer' | 'employee';
    },
    done: typeof fetchRequestAttachment,
  ): void;
  (e: 'download', v: Data): void;
}>();

const group = ref('passport');

const requestListStore = useRequestList();

const props = withDefaults(
  defineProps<{
    readonly?: boolean;
    listDocument: string[];
    currentId: { customer: string; employee: string };
  }>(),
  {
    listDocument: () => [],
  },
);

const attributes = defineModel<Attributes>('attributes', {
  default: {
    customer: {},
    employee: {},
  },
});

const state = reactive<{
  isEdit: boolean;
  splitPercent: number;
  tab: 'customer' | 'employee';
}>({
  isEdit: false,
  splitPercent: 15,
  tab: 'customer',
});

const docStatus = [
  DocStatus.AwaitReview,
  DocStatus.UploadedAwaitReview,
  DocStatus.ReviewedAwaitUpload,
  DocStatus.Reviewed,
  DocStatus.ApprovedReview,
];

const attachmentList = ref<
  Awaited<ReturnType<typeof requestListStore.getAttachmentRequest>>
>({});

async function ocr(file: File): Promise<Record<string, any> | false> {
  const result = await ocrGroup(file);
  if (result) ocrResultToVariable(result);
  return result;
}

async function ocrGroup(file: File) {
  switch (group.value) {
    case 'passport':
      return ocrPassport(file);
    case 'visa':
      return ocrPassport(file);
    default:
      return false;
  }
}

async function ocrPassport(file: File): Promise<Record<string, any> | false> {
  const mrz = await runOcr(file, parseResultMRZ);
  return mrz?.result || false;
}

function ocrResultToVariable(
  data: Record<string, any>,
): EmployeePassportPayload | EmployeeVisaPayload {
  // TODO: assign ocr result to variable
  let form: EmployeePassportPayload | EmployeeVisaPayload;

  if (group.value === 'passport') {
    form = {
      birthCountry: data.birthCountry,
      previousPassportRef: data.previousPassportRef,
      issuePlace: data.nationality,
      issueCountry: data.country,
      issueDate: new Date(data.issue_date),
      type: data.doc_type,
      expireDate: new Date(data.expire_date),
      birthDate: new Date(data.birthDate),
      workerStatus: data.workerStatus,
      nationality: data.nationality,
      gender: data.sex,
      lastNameEN: data.lastNameEN,
      lastName: data.last_name,
      middleNameEN: data.middleNameEN,
      middleName: data.middleName,
      firstNameEN: data.firstNameEN,
      firstName: data.first_name,
      namePrefix: data.namePrefix,
      number: data.doc_number,
    };
  } else {
    form = {
      arrivalAt: data.arrivalAt,
      arrivalTMNo: data.arrivalTMNo,
      arrivalTM: data.arrivalTM,
      mrz: data.mrz,
      entryCount: data.entryCount,
      issuePlace: data.issue_place,
      issueCountry: data.country,
      issueDate: new Date(data.valid_until),
      type: data.visa_type || '',
      expireDate: new Date(data.expire_date),
      remark: data.remark,
      workerType: data.workerType,
      number: data.doc_number,
    };
  }

  return form;
}

defineExpose({
  fetchRequestAttachment,
});

async function fetchRequestAttachment(type: 'customer' | 'employee') {
  const res = await requestListStore.getAttachmentRequest(
    {
      customer: props.currentId.customer,
      employee: props.currentId.employee,
    }[type] || '',
    type,
  );

  if (res) {
    attachmentList.value = res;
  }
}

const currentListDocument = computed(() => {
  return props.listDocument
    .map((v, i) => {
      const fileIds = attachmentList.value[v]
        ? Object.values(attachmentList.value[v])
        : [];
      const fileNames = fileIds.map((id) => String(id));
      return {
        no: i + 1,
        documentType: v,
        fileName: fileNames,
        amount: fileIds.length,
        documentInSystem: fileIds.length > 0,
        status: attributes.value
          ? (attributes.value[state.tab]?.[v] ?? docStatus[0])
          : docStatus[0],
      };
    })
    .filter((v) => {
      const filterFileCustomer = ['passport', 'visa', 'tm6'];
      const filterFileEmployee = ['citizen'];

      if (state.tab === 'customer') {
        return !filterFileCustomer.includes(v.documentType);
      } else {
        return !filterFileEmployee.includes(v.documentType);
      }
    });
});

function triggerCancel() {
  state.isEdit = false;
}

function triggerEdit() {
  state.isEdit = true;
}

function changeCustomerTab(opts: { tab: 'customer' | 'employee' }) {
  state.tab = opts.tab;
}
</script>
<template>
  <q-expansion-item
    dense
    class="overflow-hidden bordered full-width"
    switch-toggle-side
    style="border-radius: var(--radius-2)"
    expand-icon="mdi-chevron-down-circle"
    header-class="surface-1 q-py-sm text-medium text-body1"
    @click="fetchRequestAttachment(state.tab)"
  >
    <template #header>
      <span>
        {{ $t('menu.order.documentCheck') }}
      </span>
      <nav class="q-ml-auto row" v-if="!readonly">
        <CancelButton
          v-if="state.isEdit"
          id="btn-info-basic-undo"
          icon-only
          type="button"
          @click.stop="triggerCancel"
        />
        <EditButton
          v-if="!state.isEdit"
          id="btn-info-basic-edit"
          icon-only
          @click.stop="triggerEdit"
          type="button"
        />
      </nav>
    </template>

    <FormGroupHead>
      {{ $t('requestList.relatedDoc') }}
    </FormGroupHead>

    <main>
      <q-splitter
        v-model="state.splitPercent"
        :limits="[0, 100]"
        style="width: 100%"
        class="col"
        before-class="overflow-hidden"
        after-class="overflow-hidden"
      >
        <template v-slot:before>
          <section class="q-px-md q-py-sm column" style="gap: var(--size-1)">
            <q-item
              v-for="tab in ['customer', 'employee'] as const"
              v-close-popup
              clickable
              :key="tab"
              dense
              class="no-padding items-center rounded full-width"
              active-class="active"
              :active="state.tab === tab"
              @click="
                changeCustomerTab({ tab });
                fetchRequestAttachment(tab);
              "
              :id="`btn-${tab}`"
            >
              <span class="q-px-md ellipsis">
                {{
                  `${$t('general.document')}${tab === 'customer' ? $t('customer.employer') : $t('customer.employee')}`
                }}
              </span>
            </q-item>
          </section>
        </template>

        <template v-slot:after>
          <section class="q-px-md q-py-sm">
            <q-table
              :columns="docColumn"
              :rows="currentListDocument"
              bordered
              flat
              hide-pagination
              :rows-per-page-options="[0]"
              :no-data-label="$t('general.noDataTable')"
              class="full-width"
            >
              <template v-slot:header="props">
                <q-tr
                  style="background-color: hsla(var(--info-bg) / 0.07)"
                  :props="props"
                >
                  <q-th
                    v-for="col in props.cols"
                    :class="`text-${col.align}`"
                    :key="col.name"
                    :props="props"
                  >
                    {{ col.label && $t(col.label) }}
                  </q-th>
                  <q-th></q-th>
                </q-tr>
              </template>

              <template
                v-slot:body="props: {
                  row: (typeof currentListDocument.value)[number];
                } & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
              >
                <q-tr
                  :class="{
                    dark: $q.dark.isActive,
                  }"
                  class="text-center"
                >
                  <q-td>
                    {{ props.rowIndex + 1 }}
                  </q-td>
                  <q-td class="text-left">
                    {{
                      $t(`customerEmployee.fileType.${props.row.documentType}`)
                    }}
                  </q-td>
                  <q-td
                    class="text-left q-gutter-xs"
                    style="
                      max-width: 400px;
                      white-space: normal;
                      word-break: break-word;
                    "
                  >
                    <span
                      :class="{
                        'app-text-muted': !props.row.fileName,
                      }"
                    >
                      <div class="q-gutter-y-xs">
                        <BadgeComponent
                          hide-icon
                          v-for="v in props.row.fileName"
                          :key="v"
                          :title="v ? v : $t('requestList.noDocumentYet')"
                          hsla-color="--gray-8-hsl"
                        >
                          <template #label>
                            <span
                              :class="{
                                'cursor-pointer': props.row.fileName,
                              }"
                              @click.stop="
                                $emit('viewDoc', {
                                  key: props.row.documentType,
                                  data: { ...props.row, fileName: v },
                                  id:
                                    {
                                      customer: currentId.customer,
                                      employee: currentId.employee,
                                    }[state.tab] || '',
                                  type: state.tab,
                                })
                              "
                            >
                              {{ v ? $t(v) : $t('requestList.noDocumentYet') }}
                            </span>
                          </template>

                          <template #append>
                            <q-icon
                              :class="{
                                'cursor-pointer': props.row.fileName,
                              }"
                              style="color: hsla(207% 96% 32%)"
                              name="mdi-tray-arrow-down"
                              size="xs"
                              class="app-text-muted q-ml-xs"
                              @click.stop="
                                $emit('download', {
                                  key: props.row.documentType,
                                  data: { ...props.row, fileName: v },
                                  id:
                                    {
                                      customer: currentId.customer,
                                      employee: currentId.employee,
                                    }[state.tab] || '',
                                  type: state.tab,
                                })
                              "
                            />
                          </template>
                        </BadgeComponent>
                      </div>
                    </span>
                  </q-td>
                  <q-td>
                    {{ props.row.amount }}
                  </q-td>
                  <q-td>
                    <q-icon
                      :name="`mdi-${props.row.documentInSystem ? 'check' : 'close'}-circle`"
                      size="sm"
                      :class="{
                        'app-text-positive': props.row.documentInSystem,
                        'app-text-negative': !props.row.documentInSystem,
                      }"
                    />
                  </q-td>
                  <q-td class="text-left">
                    <q-btn-dropdown
                      :disabled="readonly"
                      dense
                      unelevated
                      :label="
                        $t(
                          `requestList.status.${props.row.status || 'AwaitReview'}`,
                        )
                      "
                      class="text-capitalize text-weight-regular doc-status"
                      :class="{
                        await: props.row.status === DocStatus.AwaitReview,
                        'in-progress':
                          props.row.status === DocStatus.ReviewedAwaitUpload ||
                          props.row.status === DocStatus.UploadedAwaitReview,
                        completed:
                          props.row.status === DocStatus.Reviewed ||
                          props.row.status === DocStatus.ApprovedReview,
                      }"
                      :menu-offset="[0, 8]"
                      dropdown-icon="mdi-chevron-down"
                      content-class="bordered rounded"
                      @click.stop
                    >
                      <q-list dense>
                        <template v-for="s in docStatus" :key="s">
                          <q-item
                            v-if="s !== props.row.status"
                            clickable
                            v-close-popup
                            @click="
                              $emit('changeStatus', {
                                key: props.row.documentType,
                                status: s,
                                type: state.tab,
                              })
                            "
                          >
                            {{ $t(`requestList.status.${s}`) }}
                          </q-item>
                        </template>
                      </q-list>
                    </q-btn-dropdown>
                  </q-td>
                  <q-td>
                    <span class="row justify-end no-wrap">
                      <OcrDialog
                        @submit="
                          (file, meta) => {
                            $emit(
                              'upload',
                              {
                                id: {
                                  customer: currentId.customer,
                                  employee: currentId.employee,
                                }[state.tab] as string,

                                file,
                                form:
                                  meta !== undefined
                                    ? ocrResultToVariable(meta)
                                    : undefined,
                                group: props.row.documentType,
                                type: state.tab,
                              },
                              fetchRequestAttachment,
                            );
                          }
                        "
                        :ocr
                      >
                        <template #trigger="{ browse }">
                          <MainButton
                            v-if="!!state.isEdit"
                            iconOnly
                            icon="mdi-tray-arrow-up"
                            color="var(--positive-bg)"
                            :title="$t('general.upload')"
                            @click.stop="
                              group = props.row.documentType;
                              browse();
                            "
                          />
                        </template>
                        <template #body="{ metadata, isRunning }">
                          <FormEmployeePassport
                            v-if="group === 'passport' && metadata"
                            :title="$t('customerEmployee.form.group.passport')"
                            dense
                            outlined
                            separator
                            ocr
                            prefix-id="ocr"
                            v-model:birth-country="metadata.birthCountry"
                            v-model:previous-passportRef="
                              metadata.previousPassportRef
                            "
                            v-model:issue-place="metadata.nationality"
                            v-model:issue-country="metadata.country"
                            v-model:issue-date="metadata.issue_date"
                            v-model:type="metadata.doc_type"
                            v-model:expire-date="metadata.expire_date"
                            v-model:birth-date="metadata.birthDate"
                            v-model:worker-status="metadata.workerStatus"
                            v-model:nationality="metadata.nationality"
                            v-model:gender="metadata.sex"
                            v-model:last-name-en="metadata.lastNameEN"
                            v-model:last-name="metadata.last_name"
                            v-model:middle-name-en="metadata.middleNameEN"
                            v-model:middle-name="metadata.middleName"
                            v-model:first-name-en="metadata.firstNameEN"
                            v-model:first-name="metadata.first_name"
                            v-model:name-prefix="metadata.namePrefix"
                            v-model:passport-number="metadata.doc_number"
                          />

                          <FormEmployeeVisa
                            v-if="group === 'visa' && metadata"
                            :title="$t('customerEmployee.form.group.visa')"
                            ocr
                            dense
                            outlined
                            prefix-id="ocr"
                            v-model:arrival-at="metadata.arrivalAt"
                            v-model:arrival-tm-no="metadata.arrivalTMNo"
                            v-model:arrival-tm="metadata.arrivalTM"
                            v-model:mrz="metadata.mrz"
                            v-model:entry-count="metadata.entryCount"
                            v-model:issue-place="metadata.issue_place"
                            v-model:issue-country="metadata.country"
                            v-model:visa-issue-date="metadata.valid_until"
                            v-model:visa-type="metadata.visa_type"
                            v-model:expire-date="metadata.expire_date"
                            v-model:visa-expiry-date="metadata.expireDate"
                            v-model:remark="metadata.remark"
                            v-model:worker-type="metadata.workerType"
                            v-model:visa-number="metadata.doc_number"
                          />
                          <div
                            v-if="isRunning"
                            class="full-height flex flex-center"
                          >
                            <q-circular-progress
                              indeterminate
                              rounded
                              size="50px"
                              color="light-blue"
                              class="q-ma-md"
                            />
                          </div>
                        </template>
                      </OcrDialog>
                    </span>
                  </q-td>
                </q-tr>
              </template>
            </q-table>
          </section>
        </template>
      </q-splitter>
    </main>
  </q-expansion-item>
</template>
<style scoped>
:deep(tr:nth-child(2n)) {
  background: #f9fafc;
  &.dark {
    background: hsl(var(--gray-11-hsl) / 0.2);
  }
}
.active {
  background-color: hsla(var(--info-bg) / 0.1);
  color: hsl(var(--info-bg));
}

.doc-status {
  padding-left: 8px;
  border-radius: 20px;
  &.await {
    color: var(--yellow-6);
    background: hsla(var(--yellow-6-hsl) / 0.15);
  }
  &.in-progress {
    color: var(--orange-5);
    background: hsla(var(--orange-5-hsl) / 0.15);
  }
  &.completed {
    color: var(--green-5);
    background: hsla(var(--green-5-hsl) / 0.15);
  }
}
</style>
