<script lang="ts" setup>
import { Icon } from '@iconify/vue';
import { QSelect } from 'quasar';
import { selectFilterOptionRefMod } from 'src/stores/utils';
import { onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';

import { formatNumberDecimal, commaInput } from 'stores/utils';

import { useConfigStore } from 'stores/config';
import AppBox from 'components/app/AppBox.vue';
import DatePicker from 'src/components/shared/DatePicker.vue';
import SelectInput from 'src/components/shared/SelectInput.vue';

import useOptionStore from 'src/stores/options';
import { storeToRefs } from 'pinia';

defineProps<{
  readonly?: boolean;
  quotationNo?: string;
  data?: {
    total: number;
    discount: number;
    totalVatExcluded: number;
    totalVatIncluded: number;
    totalAfterDiscount: number;
  };
}>();

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

const urgent = defineModel<boolean>('urgent', {
  required: true,
  default: false,
});
const actor = defineModel<string>('actor', { required: true });
const workName = defineModel<string>('workName', { required: true });
const contactor = defineModel<string>('contactor', { required: true });
const telephone = defineModel<string>('telephone', { required: true });
const documentReceivePoint = defineModel<string>('documentReceivePoint', {
  required: true,
});
const dueDate = defineModel<Date | string>('dueDate', { required: true });
const payType = defineModel<'Full' | 'Split' | 'BillFull' | 'BillSplit'>(
  'payType',
  { required: true },
);
const paySplitCount = defineModel<number | null>('paySplitCount', {
  default: 1,
});
const payBank = defineModel<string>('payBank', { required: true });
const paySplit = defineModel<
  { no: number; date: string | Date | null; amount: number }[]
>('paySplit', { required: true });
const summaryPrice = defineModel<{
  totalPrice: number;
  totalDiscount: number;
  vat: number;
  finalPrice: number;
}>('summaryPrice', {
  required: true,
  default: {
    totalPrice: 0,
    totalDiscount: 0,
    vat: 0,
    finalPrice: 0,
  },
});

const optionStore = useOptionStore();

const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
const finalDiscount4Show = ref<string>(finalDiscount.value.toString());

const payTypeOpion = ref([
  {
    value: 'Full',
    label: t('quotation.type.fullAmountCash'),
  },
  {
    value: 'Split',
    label: t('quotation.type.installmentsCash'),
  },
  {
    value: 'BillFull',
    label: t('quotation.type.fullAmountBill'),
  },
  {
    value: 'BillSplit',
    label: t('quotation.type.installmentsBill'),
  },
]);

const bankBookOptions = ref<Record<string, unknown>[]>([]);
let bankBoookFilter: (
  value: string,
  update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;

onMounted(() => {
  if (optionStore.globalOption) {
    bankBoookFilter = selectFilterOptionRefMod(
      ref(optionStore.globalOption.bankBook),
      bankBookOptions,
      'label',
    );
  }
});

watch(
  () => optionStore.globalOption,
  () => {
    bankBoookFilter = selectFilterOptionRefMod(
      ref(optionStore.globalOption.bankBook),
      bankBookOptions,
      'label',
    );
  },
);

watch(
  () => payType.value,
  (v) => {
    if (v === 'Split' || v === 'BillSplit') {
      paySplitCount.value = 1;
    } else {
      paySplitCount.value = 0;
    }
  },
);

watch(
  () => paySplitCount.value,
  (newCount, oldCount) => {
    if (newCount !== null && oldCount !== null) {
      const totalAmount = summaryPrice.value.finalPrice;

      if (newCount > oldCount) {
        const installmentAmount = totalAmount / newCount;

        paySplit.value.forEach((payment, index) => {
          payment.amount = installmentAmount;
        });

        for (let i = oldCount; i < newCount; i++) {
          paySplit.value.push({
            no: i + 1,
            date: null,
            amount: installmentAmount,
          });
        }
      } else if (newCount < oldCount) {
        paySplit.value.splice(newCount, oldCount - newCount);

        const installmentAmount = totalAmount / newCount;
        paySplit.value.forEach((payment) => {
          payment.amount = installmentAmount;
        });
      }
    }
  },
  { deep: true },
);
</script>

<template>
  <AppBox no-padding bordered class="column">
    <div
      class="bordered-b q-px-md q-py-sm row bg-color-orange-light items-center"
    >
      <div class="icon-wrapper bg-color-orange q-mr-sm">
        <q-icon name="mdi-file-outline" />
      </div>
      <span class="text-weight-bold">
        {{ $t('general.information', { msg: $t('general.attachment') }) }}
      </span>

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

    <div class="q-pa-sm">
      <div class="row q-col-gutter-sm">
        <q-input
          for="input-quotation"
          :label="$t('general.itemNo', { msg: $t('quotation.title') })"
          :readonly
          :model-value="!quotationNo ? $t('general.generated') : quotationNo"
          :disable="!readonly"
          class="col-12"
          dense
          outlined
        />
        <q-input
          for="input-actor"
          :label="$t('quotation.actor')"
          :readonly
          v-model="actor"
          :disable="!readonly"
          class="col-12"
          dense
          outlined
        />
        <q-input
          for="input-work-name"
          :label="$t('quotation.workName')"
          :readonly
          v-model="workName"
          class="col-12"
          dense
          outlined
        />
        <q-input
          for="input-contact-name"
          :label="$t('quotation.contactName')"
          :readonly
          v-model="contactor"
          class="col-12"
          dense
          outlined
        />
        <q-input
          for="input-telephone"
          :label="$t('general.telephone')"
          :readonly="readonly"
          v-model="telephone"
          class="col-12"
          dense
          outlined
        />
        <q-input
          for="input-docs-receive-point"
          :label="$t('quotation.documentReceivePoint')"
          :readonly
          v-model="documentReceivePoint"
          class="col-12"
          dense
          outlined
        />
        <DatePicker
          id="select-due-date"
          :label="$t('quotation.dueDate')"
          :readonly
          v-model="dueDate"
          class="col-12"
        />
      </div>
    </div>
    <div
      class="bordered-b q-px-md q-py-sm row bg-color-orange-light items-center"
    >
      <div class="icon-wrapper bg-color-orange q-mr-sm">
        <q-icon name="mdi-bank-outline" />
      </div>
      <span class="text-weight-bold">
        {{ $t('quotation.paymentCondition') }}
      </span>
    </div>
    <div class="q-pa-sm">
      <div class="row q-col-gutter-sm">
        <SelectInput
          class="col-12"
          :label="$t('quotation.payType')"
          :option="payTypeOpion"
          :readonly
          id="pay-type"
          v-model="payType"
        />

        <q-field
          dense
          outlined
          class="col-12"
          v-if="payType === 'Split' || payType === 'BillSplit'"
        >
          <div class="row full-width items-center justify-between q-py-xs">
            <div class="column">
              <span style="color: var(--foreground)">
                {{ $t('quotation.paySplitCount') }}
              </span>
              <span class="app-text-muted text-caption">
                ({{
                  $t('quotation.payTotal', {
                    msg:
                      formatNumberDecimal(
                        Math.max(summaryPrice.finalPrice, 0),
                        2,
                      ) || 0,
                  })
                }})
              </span>
            </div>
            <q-input
              v-model="paySplitCount"
              :readonly
              class="col-3"
              type="number"
              dense
              outlined
              min="1"
              @update:model-value="(i) => (paySplitCount = Number(i))"
            />
          </div>
        </q-field>
        <section
          v-if="payType === 'Split' || payType === 'BillSplit'"
          class="col-12 text-caption"
          style="padding-left: 20px"
        >
          <template v-for="(period, i) in paySplit" :key="period.no">
            <div
              class="row app-text-muted items-center"
              :class="{ 'q-mb-sm': i !== paySplit.length }"
            >
              {{ `${$t('quotation.periodNo')} ${period.no}` }}
              <q-input
                class="col q-mx-sm"
                :label="$t('quotation.amount')"
                :model-value="formatNumberDecimal(period.amount, 2)"
                dense
                readonly
                outlined
                bg-color="input-border"
              >
                <template #prepend>
                  <q-icon name="mdi-cash" color="primary" />
                </template>
              </q-input>
              <DatePicker
                v-model="period.date"
                class="col-5"
                :label="$t('quotation.payDueDate')"
                bg-color="input-border"
              />
            </div>
          </template>
        </section>

        <DatePicker
          v-if="payType === 'BillFull'"
          class="col-12"
          :label="$t('quotation.callDueDate')"
        />

        <q-select
          outlined
          clearable
          use-input
          emit-value
          fill-input
          map-options
          hide-bottom-space
          option-value="value"
          input-debounce="0"
          option-label="label"
          class="col-12"
          autocomplete="off"
          for="select-bankbook"
          dense
          :label="$t('quotation.bank')"
          :options="bankBookOptions"
          :readonly
          :hide-dropdown-icon="readonly"
          v-model="payBank"
          @filter="bankBoookFilter"
        >
          <template v-slot:option="scope">
            <q-item
              v-if="scope.opt"
              v-bind="scope.itemProps"
              class="row items-center"
            >
              <q-item-section avatar>
                <q-img
                  :src="`/img/bank/${scope.opt.value}.png`"
                  class="bordered"
                  style="
                    border-radius: 50%;
                    aspect-ratio: 1;
                    height: 2rem;
                    width: 2rem;
                  "
                />
              </q-item-section>
              <q-item-section>
                {{ scope.opt.label }}
              </q-item-section>
            </q-item>
          </template>

          <template v-slot:selected-item="scope">
            <q-item-section
              v-if="scope.opt && !!payBank"
              avatar
              class="q-py-sm row"
            >
              <q-img
                :src="`/img/bank/${scope.opt.value}.png`"
                class="bordered"
                style="
                  border-radius: 50%;
                  aspect-ratio: 1;
                  height: 2rem;
                  width: 2rem;
                "
              />
            </q-item-section>
          </template>

          <template v-slot:no-option>
            <q-item>
              <q-item-section class="text-grey">
                {{ $t('general.noData') }}
              </q-item-section>
            </q-item>
          </template>
        </q-select>
      </div>
    </div>
    <div
      class="bordered-b q-px-md q-py-sm row bg-color-orange-light items-center"
    >
      <div class="icon-wrapper bg-color-orange q-mr-sm">
        <Icon icon="iconoir:coins" />
      </div>
      <span class="text-weight-bold">
        {{ $t('quotation.summary') }}
      </span>
    </div>
    <div class="q-pa-sm">
      <div class="row">
        {{ $t('general.total') }}
        <span class="q-ml-auto">
          {{
            formatNumberDecimal(
              summaryPrice.finalPrice +
                summaryPrice.totalDiscount +
                Number(finalDiscount),
              2,
            ) || 0
          }}
          ฿
        </span>
      </div>
      <div class="row">
        {{ $t('quotation.discountList') }}
        <span class="q-ml-auto">
          {{ formatNumberDecimal(summaryPrice.totalDiscount, 2) || 0 }} ฿
        </span>
      </div>
      <div class="row">
        {{ $t('general.totalAfterDiscount') }}
        <span class="q-ml-auto">
          {{
            formatNumberDecimal(
              summaryPrice.finalPrice + Number(finalDiscount),
              2,
            )
          }}
          ฿
        </span>
      </div>
      <div class="row">
        {{ $t('general.totalVatExcluded') }}
        <span class="q-ml-auto">
          {{
            formatNumberDecimal(
              summaryPrice.finalPrice +
                Number(finalDiscount) -
                Number(summaryPrice.vat),
              2,
            ) || 0
          }}
          ฿
        </span>
      </div>
      <div class="row">
        {{ $t('general.totalVatIncluded') }}
        <span class="q-ml-auto">
          {{
            formatNumberDecimal(
              summaryPrice.finalPrice + Number(finalDiscount),
              2,
            ) || 0
          }}
          ฿
        </span>
      </div>
      <div class="row">
        {{
          $t('general.vat', {
            msg: `${config && Math.round(config.vat * 100)}%`,
          })
        }}
        <span class="q-ml-auto">
          {{ formatNumberDecimal(summaryPrice.vat || 0, 2) }} ฿
        </span>
      </div>
      <div class="row">
        {{ $t('general.discountAfterVat') }}
        <q-input
          :readonly
          dense
          outlined
          class="q-ml-auto price-tag"
          input-class="text-right"
          debounce="500"
          :model-value="commaInput(finalDiscount.toString() || '0')"
          @update:model-value="
            (v) => {
              if (typeof v === 'string') finalDiscount4Show = commaInput(v);
              const x = parseFloat(
                finalDiscount4Show && typeof finalDiscount4Show === 'string'
                  ? finalDiscount4Show.replace(/,/g, '')
                  : '',
              );
              finalDiscount = x;
            }
          "
        />
        <!-- <span class="q-ml-auto">{{ data?.totalVatIncluded || 0 }} ฿</span> -->
      </div>
    </div>
    <div class="q-pa-sm row surface-2 items-center text-weight-bold">
      {{ $t('general.totalAmount') }}

      <span class="q-ml-auto" style="color: var(--brand-1)">
        {{ formatNumberDecimal(Math.max(summaryPrice.finalPrice, 0), 2) || 0 }}
        ฿
      </span>
    </div>
  </AppBox>
</template>

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

:deep(.price-tag .q-field__control) {
  display: flex;
  align-items: center;
  width: 90px;
  height: 25px;
}

.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);
}
</style>
