<script setup lang="ts">
import { baseUrl } from 'stores/utils';
import { storeToRefs } from 'pinia';
import { useConfigStore } from 'stores/config';
import { formatNumberDecimal } from 'stores/utils';
import { reactive, ref } from 'vue';
import { useQuotationPayment } from 'src/stores/quotations';
import {
  PaymentPayload,
  Quotation,
  QuotationFull,
  QuotationPaymentData,
} from 'src/stores/quotations/types';
import { dateFormat } from 'src/utils/datetime';
import { QFile, QMenu } from 'quasar';
import UploadFileCard from 'src/components/upload-file/UploadFileCard.vue';
import { onMounted } from 'vue';

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

const prop = defineProps<{ data?: Quotation | QuotationFull }>();

const refQFile = ref<InstanceType<typeof QFile>[]>([]);
const refQMenu = ref<InstanceType<typeof QMenu>[]>([]);
const paymentData = ref<QuotationPaymentData[]>([]);
const submitPaymentData = ref<QuotationPaymentData[]>([]);
const payAll = ref<boolean>(false);
const paymentStatusOpts = [
  {
    status: 'PaymentInProcess',
    icon: 'mdi-credit-card-clock-outline',
    color: 'danger',
    name: 'quotation.receiptDialog.PaymentInProcess',
  },
  {
    status: 'PaymentRetry',
    icon: 'mdi-information-outline',
    color: 'negative',
    name: 'quotation.receiptDialog.PaymentRetry',
  },
  {
    status: 'PaymentSuccess',
    icon: 'mdi-check-decagram-outline',
    color: 'positive',
    name: 'quotation.receiptDialog.PaymentSuccess',
  },
];
const slipFile = ref<
  {
    paymentId: string;
    data: { name: string; progress: number; loaded: number; total: number }[];
    file?: File;
  }[]
>([]);

const state = reactive({
  waitExpansion: true,
  payExpansion: [] as boolean[],
});

function monthDisplay(date: Date | string) {
  const arr = dateFormat(date, true).split(' ');
  arr.shift();
  return arr.join(' ');
}

function pickFile(index: number) {
  refQFile.value[index].pickFiles();
}

async function getSlipList(payment: QuotationPaymentData, index: number) {
  const slipList = await quotationPayment.listAttachment({
    parentId: payment.id,
  });

  if (slipList && slipList.length > 0) {
    slipFile.value[index].data = slipFile.value[index].data.filter((item) =>
      slipList.includes(item.name),
    );

    slipList.forEach((slip) => {
      const exists = slipFile.value[index].data.some(
        (item) => item.name === slip,
      );

      if (!exists) {
        slipFile.value[index].data.push({
          name: slip,
          progress: 1,
          loaded: 0,
          total: 0,
        });
      }
    });
  } else slipFile.value[index].data = [];
}

async function triggerUpload(
  payment: QuotationPaymentData,
  index: number,
  file?: File,
) {
  if (!file) return;
  slipFile.value[index].data.push({
    name: file.name,
    progress: 0,
    loaded: 0,
    total: 0,
  });
  const ret = await quotationPayment.putAttachment({
    parentId: payment.id,
    name: file.name,
    file: file,
    onUploadProgress: (e) => {
      slipFile.value[index].data[slipFile.value[index].data.length - 1] = {
        name: file.name,
        progress: e.progress || 0,
        loaded: e.loaded,
        total: e.total || 0,
      };
    },
  });
  if (ret) await getSlipList(payment, index);
  slipFile.value[index].file = undefined;
}

async function triggerDelete(
  payment: QuotationPaymentData,
  name: string,
  index: number,
) {
  await quotationPayment.delAttachment({ parentId: payment.id, name });
  await getSlipList(payment, index);
}

function triggerViewSlip(payment: QuotationPaymentData, name: string) {
  const url = `${baseUrl}/payment/${payment.id}/attachment/${name}`;
  window.open(url, '_blank');
}

function selectStatus(
  payment: QuotationPaymentData,
  status: string,
  index: number,
) {
  const existingPayment = submitPaymentData.value.findIndex(
    (p: QuotationPaymentData) => p.id === payment.id,
  );

  if (existingPayment !== -1) {
    submitPaymentData.value[existingPayment].paymentStatus = status;
  } else {
    payment.paymentStatus = status;
    submitPaymentData.value.push(payment);
  }

  refQMenu.value[index].hide();
}

async function triggerSubmit() {
  submitPaymentData.value.forEach(async (p) => {
    const payload: PaymentPayload = {
      paymentStatus: p.paymentStatus,
      date: new Date(p.date),
      amount: p.amount,
    };
    await quotationPayment.updateQuotationPayment(p.id, payload);
  });
}

onMounted(async () => {
  if (!prop.data) return;
  const ret = await quotationPayment.getQuotationPayment(prop.data.id);
  if (ret) {
    paymentData.value = ret.result;
    slipFile.value = paymentData.value.map((v) => ({
      paymentId: v.id,
      data: [],
    }));
  }
});
</script>
<template>
  <q-form
    greedy
    @submit.prevent
    @validation-success="triggerSubmit"
    class="column full-height"
    v-if="data"
  >
    <div class="col column no-wrap">
      <!-- PRICE DETAIL -->
      <section class="bordered rounded surface-1" style="overflow: hidden">
        <q-expansion-item
          hide-expand-icon
          v-model="state.waitExpansion"
          header-style="padding:0px"
        >
          <template v-slot:header>
            <div class="column full-width bordered-b">
              <header class="bg-color-orange text-bold text-body1 q-pa-sm">
                <q-avatar class="surface-1 q-mr-sm" size="10px" />
                {{ $t('quotation.receiptDialog.paymentWait') }}
              </header>
              <span class="q-pa-md row items-center">
                <q-img
                  src="/images/quotation-avatar.png"
                  width="3rem"
                  class="q-mr-lg"
                />
                <div class="column col">
                  <span class="text-bold text-body1">
                    {{ data.workName }}
                  </span>
                  <span
                    class="row items-center"
                    :class="data.urgent ? 'urgent' : 'app-text-muted'"
                  >
                    {{ data.code }}
                    <q-icon
                      v-if="data.urgent"
                      class="q-pl-sm"
                      name="mdi-fire"
                      size="xs"
                    />
                    <span class="q-ml-auto" style="color: var(--foreground)">
                      ฿ {{ formatNumberDecimal(data.finalPrice, 2) || '0.00' }}
                    </span>
                  </span>
                </div>
              </span>
            </div>
          </template>

          <span class="app-text-muted-2 q-px-md q-py-sm column">
            <span class="row">
              {{ $t('general.total') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿
                {{ formatNumberDecimal(data.totalPrice, 2) || '0.00' }}
              </span>
            </span>
            <span class="row">
              {{ $t('quotation.discountList') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿
                {{ formatNumberDecimal(data.totalDiscount, 2) || '0.00' }}
              </span>
            </span>
            <span class="row">
              {{ $t('general.totalAfterDiscount') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿
                {{
                  formatNumberDecimal(
                    data.totalPrice - data.totalDiscount,
                    2,
                  ) || '0.00'
                }}
              </span>
            </span>
            <span class="row">
              {{ $t('general.totalVatExcluded') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿ {{ formatNumberDecimal(data.vatExcluded, 2) || '0.00' }}
              </span>
            </span>
            <span class="row">
              {{
                $t('general.vat', {
                  msg: `${config && Math.round(config.vat * 100)}%`,
                })
              }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿ {{ formatNumberDecimal(data.vat, 2) || '0.00' }}
              </span>
            </span>
            <span class="row">
              {{ $t('general.totalVatIncluded') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿
                {{
                  formatNumberDecimal(
                    data.totalPrice - data.totalDiscount + data.vat,
                    2,
                  ) || '0.00'
                }}
              </span>
            </span>
            <span class="row">
              {{ $t('general.discountAfterVat') }}
              <span class="q-ml-auto" style="color: var(--foreground)">
                ฿ {{ formatNumberDecimal(data.discount, 2) || '0.00' }}
              </span>
            </span>
          </span>
        </q-expansion-item>
        <q-separator inset v-if="state.waitExpansion" />
        <div
          class="q-py-sm q-px-md row items-center justify-end app-text-muted-2"
        >
          {{ $t('quotation.totalPriceBaht') }}:
          <span class="q-px-sm" style="color: var(--foreground)">
            {{ formatNumberDecimal(data.finalPrice, 2) || '0.00' }}
          </span>
          <q-btn
            dense
            flat
            rounded
            padding="0"
            :icon="`mdi-chevron-${state.waitExpansion ? 'down' : 'up'}`"
            @click.stop="state.waitExpansion = !state.waitExpansion"
          />
        </div>
      </section>

      <!-- PAYMENT DETAIL -->
      <section
        class="surface-1 rounded bordered column q-mt-md q-pa-md col scroll no-wrap"
      >
        <span class="text-weight-bold text-body1">
          {{ $t('general.payment') }}
        </span>
        <div class="row items-center q-pb-md">
          <span class="app-text-muted-2">{{ $t('quotation.payType') }}</span>
          <div
            class="badge-card q-ml-auto rounded"
            :class="`badge-card__${data.payCondition}`"
          >
            {{ $t(`quotation.type.${data.payCondition}`) }}
          </div>
        </div>

        <!-- split summary -->
        <div
          v-if="
            data.payCondition === 'BillSplit' || data.payCondition === 'Split'
          "
          class="row items-center q-pb-sm"
        >
          <span class="app-text-muted-2">
            {{ $t('quotation.paySplitCount') }}
          </span>
          <span class="q-ml-auto">
            {{ $t('quotation.receiptDialog.total') }}
          </span>
          <span class="bordered rounded surface-2 number-box q-mx-sm">
            {{ data.paySplitCount }}
          </span>
          {{ $t('quotation.receiptDialog.installments') }}
          {{ $i18n.locale === 'eng' ? ',' : '' }}
          {{ $t('quotation.receiptDialog.paid') }}
          <span class="bordered rounded surface-2 number-box q-mx-sm">
            {{
              paymentData.reduce(
                (c, i) => (i.paymentStatus === 'PaymentSuccess' ? c + 1 : c),
                0,
              )
            }}
          </span>
          {{
            $i18n.locale === 'tha'
              ? $t('quotation.receiptDialog.installments')
              : ','
          }}
          {{ $t('quotation.receiptDialog.remain') }}
          <span class="bordered rounded surface-2 number-box q-mx-sm">
            {{
              paymentData.reduce(
                (c, i) => (i.paymentStatus !== 'PaymentSuccess' ? c + 1 : c),
                0,
              )
            }}
          </span>
          {{
            $i18n.locale === 'tha'
              ? $t('quotation.receiptDialog.installments')
              : ''
          }}
        </div>

        <!-- summary total, paid, remain -->
        <div class="row items-center">
          <span
            class="row col rounded q-px-sm q-py-md"
            style="border: 1px solid hsl(var(--info-bg))"
          >
            {{ $t('quotation.receiptDialog.totalAmount') }}
            <span class="q-ml-auto">
              {{ formatNumberDecimal(data.finalPrice, 2) }}
            </span>
          </span>
          <span
            class="row col rounded q-px-sm q-py-md q-mx-md"
            style="border: 1px solid hsl(var(--positive-bg))"
          >
            {{ $t('quotation.receiptDialog.paid') }}
            <span class="q-ml-auto">
              {{
                formatNumberDecimal(
                  paymentData.reduce(
                    (c, i) =>
                      i.paymentStatus === 'PaymentSuccess' ? c + i.amount : c,
                    0,
                  ),
                  2,
                )
              }}
            </span>
          </span>
          <span
            class="row col rounded q-px-sm q-py-md"
            style="border: 1px solid hsl(var(--warning-bg))"
          >
            {{ $t('quotation.receiptDialog.remain') }}
            <span class="q-ml-auto">
              {{
                formatNumberDecimal(
                  paymentData.reduce(
                    (c, i) =>
                      i.paymentStatus !== 'PaymentSuccess' ? c + i.amount : c,
                    0,
                  ),
                  2,
                )
              }}
            </span>
          </span>
        </div>

        <!-- bill -->
        <span class="app-text-muted-2 q-pt-md">
          {{ $t('quotation.receiptDialog.billOfPayment') }}
        </span>
        <q-checkbox
          v-if="
            data.payCondition === 'BillSplit' || data.payCondition === 'Split'
          "
          size="xs"
          v-model="payAll"
          :label="$t('quotation.receiptDialog.payAll')"
        />

        <!-- payment item -->
        <section class="row">
          <div
            v-for="(p, i) in paymentData"
            :key="i"
            class="bordered rounded surface-1 q-mb-md col-12"
            style="overflow: hidden"
          >
            <q-expansion-item
              hide-expand-icon
              v-model="state.payExpansion[i]"
              header-style="padding:0px"
              @before-show="getSlipList(p, i)"
            >
              <template v-slot:header>
                <div class="column full-width">
                  <section
                    class="row full-width items-center surface-2 bordered-b q-px-md q-py-sm"
                  >
                    <span class="text-weight-medium column">
                      {{ $t('quotation.receiptDialog.allInstallments') }}
                      {{ monthDisplay(p.date) }}
                      <span
                        class="text-caption app-text-muted-2"
                        v-if="data.payCondition !== 'Full'"
                      >
                        {{ $t('quotation.receiptDialog.paymentDueDate') }}
                        {{
                          data.payCondition !== 'BillFull'
                            ? dateFormat(p.date, true)
                            : dateFormat(data.payBillDate)
                        }}
                      </span>
                    </span>

                    <q-btn
                      @click.stop
                      unelevated
                      padding="4px 8px"
                      class="q-ml-auto rounded text-capitalize text-weight-regular payment-wait row items-center"
                      :class="{
                        'payment-pending': p.paymentStatus === 'PaymentWait',
                        'payment-process':
                          p.paymentStatus === 'PaymentInProcess',
                        'payment-retry': p.paymentStatus === 'PaymentRetry',
                        'payment-success': p.paymentStatus === 'PaymentSuccess',
                      }"
                    >
                      <q-icon
                        size="xs"
                        :name="
                          paymentStatusOpts.find(
                            (s) => s.status === p.paymentStatus,
                          )?.icon || 'mdi-hand-coin-outline'
                        "
                        class="q-pr-sm"
                      />
                      <span>
                        {{ $t(`quotation.receiptDialog.${p.paymentStatus}`) }}
                      </span>
                      <q-icon name="mdi-chevron-down" class="q-pl-xs" />
                      <q-menu
                        ref="refQMenu"
                        fit
                        :offset="[0, 8]"
                        class="rounded"
                      >
                        <q-list dense>
                          <template
                            v-for="opts in paymentStatusOpts"
                            :key="opts.status"
                          >
                            <q-item
                              v-if="
                                (p.paymentStatus === 'PaymentWait' &&
                                  opts.status !== 'PaymentRetry') ||
                                (p.paymentStatus === 'PaymentInProcess' &&
                                  opts.status !== 'PaymentInProcess') ||
                                (p.paymentStatus === 'PaymentRetry' &&
                                  opts.status !== 'PaymentRetry')
                              "
                              clickable
                              class="row items-center"
                              @click="selectStatus(p, opts.status, i)"
                            >
                              <q-icon
                                :name="opts.icon"
                                :color="opts.color"
                                class="q-pr-sm"
                                size="xs"
                              />
                              {{ $t(opts.name) }}
                            </q-item>
                          </template>
                        </q-list>
                      </q-menu>
                    </q-btn>
                  </section>
                  <section class="row items-center q-px-md q-py-sm">
                    {{ $t('quotation.receiptDialog.amountToBePaid') }}
                    <span
                      class="q-px-sm q-ml-auto"
                      style="color: var(--foreground)"
                    >
                      {{ formatNumberDecimal(p.amount, 2) }}
                    </span>
                    <q-btn
                      dense
                      flat
                      rounded
                      padding="0"
                      :icon="`mdi-chevron-${state.payExpansion[i] ? 'down' : 'up'}`"
                      @click.stop="
                        state.payExpansion[i] = !state.payExpansion[i]
                      "
                    />
                  </section>
                </div>
              </template>

              <div
                class="q-px-md q-py-xs text-weight-medium row items-center"
                style="background-color: hsla(var(--info-bg) / 0.1)"
              >
                {{
                  $t('general.upload', {
                    msg: $t('quotation.receiptDialog.slip'),
                  })
                }}
              </div>
              <div class="surface-2 q-pa-md">
                <div
                  class="upload-section column rounded q-py-md full-height items-center justify-center no-wrap"
                >
                  <q-img src="/images/upload.png" width="150px" />
                  {{ $t('general.upload', { msg: ' E-slip' }) }}
                  {{
                    $t('general.or', {
                      msg: $t('general.upload', {
                        msg: $t('quotation.receiptDialog.paymentDocs'),
                      }),
                    })
                  }}
                  <q-btn
                    unelevated
                    :label="$t('general.upload')"
                    rounded
                    class="app-bg-info q-mt-sm"
                    @click.stop="() => pickFile(i)"
                  />
                  <q-file
                    ref="refQFile"
                    v-show="false"
                    v-model="slipFile[i].file"
                    @update:model-value="triggerUpload(p, i, slipFile[i].file)"
                  />
                </div>
              </div>

              <section class="surface-2 row q-px-md">
                <!-- upload card -->
                <div
                  v-for="(d, j) in slipFile[i].data"
                  :key="j"
                  class="col-12"
                  :class="{
                    'q-pb-md': j === slipFile[i].data.length - 1,
                    'q-pb-sm': j < slipFile[i].data.length,
                  }"
                >
                  <UploadFileCard
                    :name="d.name"
                    :progress="d.progress"
                    :uploading="{ loaded: d.loaded, total: d.total }"
                    :url="`/quotation/${data.id}/payment/${p.id}/attachment/${d.name}`"
                    icon="mdi-file-image-outline"
                    color="hsl(var(--text-mute))"
                    clickable
                    @click="triggerViewSlip(p, d.name)"
                    @close="triggerDelete(p, d.name, i)"
                  />
                </div>
              </section>
            </q-expansion-item>
          </div>
        </section>
      </section>
    </div>
  </q-form>
</template>
<style scoped>
.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);
}

.payment-pending {
  color: hsl(var(--warning-bg));
  background: hsla(var(--warning-bg) / 0.15);
}

.payment-process {
  color: hsl(var(--danger-bg));
  background: hsla(var(--danger-bg) / 0.15);
}

.payment-retry {
  color: hsl(var(--negative-bg));
  background: hsla(var(--negative-bg) / 0.15);
}

.payment-success {
  color: hsl(var(--positive-bg));
  background: hsla(var(--positive-bg) / 0.1);
}

.urgent {
  color: hsl(var(--red-6-hsl));
}

.number-box {
  text-align: center;
  width: 25px;
  height: 25px;
}

.badge-card {
  padding: 4px 8px;
  color: hsla(var(--gray-0-hsl) / 1);
  background: hsla(var(--_color) / 1);
}

.badge-card__Full {
  --_color: var(--red-6-hsl);
}

.badge-card__Split {
  --_color: var(--blue-6-hsl);
}

.badge-card__BillFull {
  --_color: var(--jungle-8-hsl);
}

.badge-card__BillSplit {
  --_color: var(--purple-7-hsl);
}

.dark .badge-card__Split {
  --_color: var(--blue-10-hsl);
}

.upload-section {
  border: 3px solid var(--border-color);
  border-style: dashed;
}

:deep(
    .q-expansion-item
      .q-item.q-item-type.row.no-wrap.q-item--clickable.q-link.cursor-pointer.q-focusable.q-hoverable
      .q-focus-helper
  ) {
  visibility: hidden;
}
</style>
