<script lang="ts" setup>
import { Icon } from '@iconify/vue';
import { ref, watch, computed } from 'vue';
import { useI18n } from 'vue-i18n';

import { View } from './types.ts';

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 { storeToRefs } from 'pinia';
import { precisionRound } from 'src/utils/arithmetic';
import { PayCondition } from 'src/stores/quotations/types.ts';

defineEmits<{
  (e: 'changePayType', type: PayCondition): void;
}>();

defineProps<{
  readonly?: boolean;
  quotationNo?: string;
  installmentNo?: number[];
  installmentAmount?: number;

  view?: View;
  data?: {
    total: number;
    discount: number;
    totalVatExcluded: number;
    totalVatIncluded: number;
    totalAfterDiscount: number;
  };
  taskOrder?: boolean;
  taskOrderComplete?: boolean;
}>();

const { t } = useI18n();
const configStore = useConfigStore();
const { data: config } = storeToRefs(configStore);
const payBillDate = defineModel<Date | null | undefined>('payBillDate', {
  required: false,
});
const payType = defineModel<PayCondition>('payType', { required: true });
const paySplitCount = defineModel<number | null>('paySplitCount', {
  default: 1,
});
const paySplit = defineModel<{ no: number; name?: string; amount: number }[]>(
  'paySplit',
  { required: true },
);
const summaryPrice = defineModel<{
  totalPrice: number;
  totalDiscount: number;
  vat: number;
  vatExcluded: number;
  finalPrice: number;
}>('summaryPrice', {
  required: true,
  default: {
    totalPrice: 0,
    totalDiscount: 0,
    vat: 0,
    vatExcluded: 0,
    finalPrice: 0,
  },
});

// const finalDiscount = defineModel<number>('finalDiscount', { default: 0 });
// const finalDiscount4Show = ref<string>(finalDiscount.value.toString());
const payTypeOption = computed(() => [
  {
    value: 'Full',
    label: t('quotation.type.fullAmountCash'),
  },
  {
    value: 'Split',
    label: t('quotation.type.installmentsCash'),
  },
  {
    value: 'SplitCustom',
    label: t('quotation.type.installmentsCustomCash'),
  },
]);
const amount4Show = ref<string[]>([]);

function handleSplitCount(count: number) {
  if (count > paySplit.value.length) {
    paySplit.value.push({ no: Number(count), amount: 0 });
  } else {
    paySplit.value[paySplit.value.length - 2].amount =
      paySplit.value[paySplit.value.length - 1].amount +
      paySplit.value[paySplit.value.length - 2].amount;
    paySplit.value.pop();
  }
}

function calculateInstallments(param: {
  customIndex?: number;
  customAmount?: number;
  newCount: number;
  oldCount: number;
}) {
  if (payType.value !== 'SplitCustom' && payType.value !== 'BillSplitCustom') {
    return;
  }

  if (param.newCount !== null && param.oldCount !== null) {
    const totalAmount = summaryPrice.value.finalPrice;

    // if (param.newCount > param.oldCount) {
    //   const installmentAmount = +(totalAmount / param.newCount).toFixed(2);

    //   // Update existing
    //   paySplit.value.forEach((payment, i) => {
    //     if (i !== param.customIndex) {
    //       payment.amount = installmentAmount;
    //       amount4Show.value[i] = installmentAmount.toString();
    //     }
    //   });

    //   // Add
    //   for (let i = param.oldCount; i < param.newCount; i++) {
    //     paySplit.value.push({
    //       no: i + 1,
    //       amount: installmentAmount,
    //     });
    //     amount4Show.value.push(installmentAmount.toString());
    //   }
    // } else if (param.newCount < param.oldCount) {
    //   // Remove extra
    //   paySplit.value.splice(param.newCount, param.oldCount - param.newCount);
    //   amount4Show.value.splice(param.newCount, param.oldCount - param.newCount);

    //   // Recalculate
    //   const installmentAmount = +(totalAmount / param.newCount).toFixed(2);
    //   paySplit.value.forEach((payment, i) => {
    //     if (i !== param.customIndex) {
    //       payment.amount = installmentAmount;
    //       amount4Show.value[i] = installmentAmount.toString();
    //     }
    //   });
    if (param.newCount === param.oldCount) {
      if (param.customIndex !== undefined && param.customAmount !== undefined) {
        paySplit.value[param.customIndex].amount = param.customAmount;
        // amount4Show.value[param.customIndex] = param.customAmount.toString();
      }
    }

    // Calculate last
    if (paySplit.value.length > 0) {
      const totalPreviousPayments = paySplit.value
        .slice(0, -1)
        .reduce((sum, payment) => sum + payment.amount, 0);

      const remainingAmount = totalAmount - totalPreviousPayments;
      paySplit.value[paySplit.value.length - 1].amount =
        +remainingAmount.toFixed(2);
      amount4Show.value[amount4Show.value.length - 1] = commaInput(
        paySplit.value[paySplit.value.length - 1].amount.toString(),
      );
      // amount4Show.value[amount4Show.value.length - 1] =
      //   (+remainingAmount.toFixed(2)).toString();
    }
  }
}

// watch(
//   () => [paySplitCount.value, summaryPrice.value.finalPrice],
//   ([newCount, _newF], [oldCount, _oldF]) => {
//     if (
//       paySplitCount.value === 0 ||
//       !paySplitCount.value ||
//       !summaryPrice.value.finalPrice ||
//       props.readonly
//     ) {
//       return;
//     }
//     calculateInstallments({ newCount: newCount || 0, oldCount: oldCount || 0 });
//   },
//   { deep: true },
// );

watch(
  () => paySplit.value,
  () => {
    amount4Show.value = paySplit.value.map((payment) =>
      commaInput(payment.amount.toString()),
    );
  },
);
</script>

<template>
  <AppBox
    no-padding
    bordered
    class="main-color"
    :class="{
      row: $q.screen.gt.sm,
      column: $q.screen.lt.md,
      'invoice-color': view === View.Invoice,
      'receipt-color': view === View.Receipt,
      'task-order-color': taskOrder && !taskOrderComplete,
    }"
  >
    <div class="col bordered-r" v-if="!taskOrder">
      <div class="bordered-b q-px-md q-py-sm row bg-color-light items-center">
        <div class="icon-wrapper bg-color 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">
          <section class="row q-col-gutter-sm col-12 items-center">
            <SelectInput
              class="col-md-6 col-12"
              :label="$t('quotation.payType')"
              :option="
                taskOrder
                  ? payTypeOption.filter((v) => v.value === 'Full')
                  : payTypeOption
              "
              :readonly
              id="pay-type"
              :model-value="payType"
              @update:model-value="
                (v) => {
                  payType = v as PayCondition;
                  $emit('changePayType', v as PayCondition);
                }
              "
            />

            <div
              class="col-md-6 col-12"
              :class="{ 'q-pl-md': $q.screen.lt.md }"
              v-if="payType === 'Split' || payType === 'SplitCustom'"
            >
              <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="readonly || payType === 'Split'"
                  class="col-3"
                  type="number"
                  dense
                  outlined
                  min="1"
                  @update:model-value="
                    (i) => {
                      paySplitCount = Number(i);
                      handleSplitCount(Number(i));
                    }
                  "
                />
              </div>
            </div>
          </section>

          <section
            v-if="payType === 'Split' || payType === 'SplitCustom'"
            class="col-12 text-caption"
            style="padding-left: 20px"
          >
            <template
              v-for="(period, i) in installmentNo?.length > 0
                ? paySplit.filter((value) => installmentNo?.includes(value.no))
                : paySplit"
              :key="period.no"
            >
              <div
                class="row app-text-muted items-center"
                :class="{ 'q-mb-sm': i !== paySplit.length }"
              >
                {{ `${$t('quotation.periodNo')} ${i + 1}` }}
                <q-input
                  :readonly="readonly"
                  :label="$t('general.name')"
                  v-if="payType === 'SplitCustom'"
                  v-model="period.name"
                  class="col q-mx-sm"
                  dense
                  outlined
                />
                <q-input
                  :readonly="readonly || payType === 'Split'"
                  class="col q-mx-sm"
                  :label="$t('quotation.amount')"
                  :model-value="
                    amount4Show[i] || commaInput(period.amount.toString())
                  "
                  dense
                  outlined
                  @blur="
                    () => {
                      period.amount = Number(amount4Show[i]?.replace(/,/g, ''));
                      if (period.amount % 1 === 0) {
                        const [, dec] = amount4Show[i].split('.');
                        if (!dec) {
                          amount4Show[i] += '.00';
                        }
                      }
                    }
                  "
                  @update:model-value="
                    (v) => {
                      if (readonly) return;

                      amount4Show[i] = commaInput(
                        v?.toString() || '0',
                        'string',
                      );

                      calculateInstallments({
                        customIndex: i,
                        customAmount: parseFloat(
                          amount4Show[i].replace(/,/g, ''),
                        ),
                        newCount: paySplit.length,
                        oldCount: paySplit.length,
                      });

                      const lastAmount = paySplit.at(-1);
                      if ((lastAmount?.amount || 0) < 0) {
                        period.amount = precisionRound(
                          paySplit[i].amount + (paySplit.at(-1)?.amount || 0),
                        );
                        amount4Show[i] = period.amount.toString();
                        if (lastAmount) lastAmount.amount = 0;
                        amount4Show[amount4Show.length - 1] = '0';
                      }
                    }
                  "
                >
                  <template #prepend>
                    <q-icon name="mdi-cash" color="primary" />
                  </template>
                </q-input>
              </div>
            </template>
          </section>

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

    <div class="col">
      <div class="bordered-b q-px-md q-py-sm row bg-color-light items-center">
        <div class="icon-wrapper bg-color q-mr-sm">
          <Icon icon="iconoir:coins" />
        </div>
        <span class="text-weight-bold">
          {{ $t('quotation.summary') }}
        </span>
      </div>
      <div
        class="q-pa-sm price-container"
        v-if="payType !== 'SplitCustom' || view !== View.Invoice"
      >
        <div class="row">
          {{ $t('general.total') }}
          <span class="q-ml-auto">
            {{ formatNumberDecimal(summaryPrice.totalPrice, 2) }}
            ฿
          </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.totalPrice - summaryPrice.totalDiscount,
                2,
              )
            }}
            ฿
          </span>
        </div>
        <div class="row">
          {{ $t('general.totalVatExcluded') }}
          <span class="q-ml-auto">
            {{ formatNumberDecimal(summaryPrice.vatExcluded, 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, 2) }} ฿
          </span>
        </div>
        <div class="row">
          {{ $t('general.totalVatIncluded') }}
          <span class="q-ml-auto">
            {{
              formatNumberDecimal(
                summaryPrice.totalPrice -
                  summaryPrice.totalDiscount +
                  summaryPrice.vat,
                2,
              )
            }}
            ฿
          </span>
        </div>
        <!-- <div class="row">
          {{ $t('general.discountAfterVat') }}
          <q-input
            :readonly
            dense
            outlined
            class="q-ml-auto price-tag"
            style="padding-inline: none !important"
            input-class="text-right"
            debounce="500"
            :model-value="commaInput(finalDiscount.toString() || '0')"
            @focus="(e) => (e.target as HTMLInputElement).select()"
            @update:model-value="
              (v) => {
                if (typeof v === 'string') finalDiscount4Show = commaInput(v);
                const x = parseFloat(
                  finalDiscount4Show && typeof finalDiscount4Show === 'string'
                    ? finalDiscount4Show.replace(/,/g, '')
                    : '',
                );
                finalDiscount = x;
              }
            "
          />
        </div> -->
      </div>
      <div class="q-pa-sm row surface-2 items-center text-weight-bold">
        {{ $t('quotation.totalPriceBaht') }}

        <span class="q-ml-auto" style="color: var(--brand-1)">
          {{
            payType === 'SplitCustom' && view === View.Invoice
              ? formatNumberDecimal(Math.max(installmentAmount || 0, 0), 2) || 0
              : formatNumberDecimal(Math.max(summaryPrice.finalPrice, 0), 2) ||
                0
          }}
          ฿
        </span>
      </div>
    </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;
}

.main-color {
  --_color: var(--yellow-7-hsl);
}

.invoice-color {
  --_color: var(--purple-9-hsl);
}

.receipt-color {
  --_color: var(--green-6-hsl);
}

.task-order-color {
  --_color: var(--pink-7-hsl);
}

.bg-color {
  color: white;
  background: hsla(var(--_color));
}

.dark .bg-color {
  --_color: var(--orange-6-hsl);
}

.bg-color-light {
  background: hsla(var(--_color) / 0.1);
}

.dark .bg-color-light {
  --_color: var(--orange-6-hsl / 0.2);
}

.price-container > * {
  padding: var(--size-1);
}
</style>
