<i18n>
{
  "en": {
    "PaymentsSearchCard": {
      "paymentDate": "Date",
      "amount": "Total",
      "narrative": "Payment narrative",
      "KBK": "KBK",
      "payerId": "Payer identifier",
      "paymentId": "UIP",
      "supplierBillId": "UIN",
      "meaning": "Payment type",
      "action": "Action",
      "quitannce": "quitannce",
      "binded": "binded",
      "request": "Payments Request"
    }
  },
  "ru": {
    "PaymentsSearchCard": {
      "paymentDate": "Дата оплаты",
      "amount": "Сумма",
      "narrative": "Назначение платежа",
      "KBK": "КБК",
      "payerId": "Идентификатор плательщика",
      "paymentId": "УИП",
      "supplierBillId": "УИН",
      "meaning": "Тип платежа",
      "action": "Действие",
      "quitannce": "Сквитировать",
      "binded": "Привязан",
      "request": "Запросы платежей"
    }
  }
}
</i18n>

<template>
  <div v-if="common.active === 'payments_search'" class="q-pb-md">
    <q-card class="no-shadow q-gutter-y-md q-mx-md no-border-radius">
      <div v-if="!loading" class="q-mx-md q-pt-md q-pa-sm">
        <div
          class="flex items-center justify-end full-width text-subtitle1 q-pb-md"
        >
          <PaymentsRequestDialogvue
            :common="common"
            :statementModel="model"
            :dictionaries="dictionaries"
          />
        </div>
        <q-table
          v-if="payments"
          :columns="tableColumns"
          :data="payments"
          :totalRowsNumber="payments.length"
          title="Платежи"
          row-key="paymentId"
          :binary-state-sort="true"
          :pagination="pagination"
          :visible-columns="visibleColumns"
        >
          <template #body-cell-action="props">
            <q-td :props="props">
              <q-btn
                v-if="!isQuittencedPayment(props.row)"
                outline
                color="primary"
                @click="selectedPayment = [props.row]"
              >
                {{ $t(`PaymentsSearchCard.quitannce`) }}
              </q-btn>
            </q-td>
          </template>
          <template #body-cell-binded="props">
            <q-td :props="props">
              <q-icon
                name="check_circle"
                size="20px"
                color="positive"
                v-if="props.row.binded"
              />
            </q-td>
          </template>
          <template #pagination="scope">
            {{ paginationLabelCustom(scope.pagination) }}
            <q-btn
              icon="chevron_left"
              color="grey-8"
              round
              dense
              flat
              :disable="scope.isFirstPage || !!$props.loading"
              @click="scope.prevPage"
            />
            <q-btn
              icon="chevron_right"
              color="grey-8"
              round
              dense
              flat
              :disable="scope.isLastPage || !!$props.loading"
              @click="scope.nextPage"
            />
          </template>
        </q-table>
        <q-expansion-item v-if="model.paymentsReceivedReq">
          <template #header>
            <q-item-section>
              <p class="text-h6 q-ma-none">
                {{ $t('PaymentsSearchCard.request') }}
              </p>
            </q-item-section>
          </template>
          <InterdepreqExpandedTable
            source="paymentsReceivedReq"
            :common="common"
            :model="model"
          />
        </q-expansion-item>
      </div>
      <div v-if="loading" style="padding: 100px">
        <q-inner-loading :showing="loading">
          <q-spinner-gears color="primary" size="50px" />
        </q-inner-loading>
      </div>

      <PaymentsQuittanceDialog
        :common="common"
        :charges="chargesRegistered"
        :payment="selectedPayment"
        @clear="selectedPayment = []"
      />
    </q-card>
  </div>
</template>

<script lang="ts">
import PaymentsRequestDialogvue from './PaymentsRequestDialogvue.vue';
import PaymentsQuittanceDialog from './PaymentsQuittanceDialog.vue';
import InterdepreqExpandedTable from './components/InterdepreqExpandedTable.vue';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { convertDateFromBackendFormat, DateFormat } from '@utils/format-date';
import { DictionaryApi, Dictionary } from '@openapi/registry-service';
import { TablePagination } from '@models/base/TablePagination';
import { BaseCardCommon } from '@/interfaces';
import { Quitannce } from './Charges.vue';
import QColumn from '@/types/QColumn';
import get from 'lodash/get';

const dictionaryApi = new DictionaryApi();

export type Charge = {
  systemStatus: string;
  billDate: string;
  totalAmount: string;
  KBK: string;
  billFor: string;
  quittance?: Quitannce;
  charge?: Record<string, unknown>;
  id: string;
  EPGUPaymentRequired: boolean | undefined;
};

export type Payment = {
  paymentDate: string;
  id: string;
  index: string;
  sortable: string;
  amount: number;
  narrative: string;
  kbk: string;
  payerId: string;
  paymentId: string;
  supplierBillId: number;
  meaning: string;
  acknowledgmentInfo?: {
    supplierBillID?: string;
  };
};

@Component({
  components: {
    PaymentsRequestDialogvue,
    PaymentsQuittanceDialog,
    InterdepreqExpandedTable,
  },
  props: {
    selected: [],
  },
})
export default class PaymentsSearch extends Vue {
  @Prop({}) private common?: BaseCardCommon;
  @Prop({}) private model?: any;

  private dictionaries: Dictionary[] = [];
  private dictionariesList = ['gis_gmp_payer_type', 'gis_gmp_document_type'];

  loading = false;
  showDialog = false;
  selectedPayment = {};
  chargesRegistered = [];
  pagination = {
    rowsPerPage: 15,
  };

  visibleColumns = [
    'paymentDate',
    'amount',
    'narrative',
    'kbk',
    'payerId',
    'paymentId',
    'supplierBillId',
    'meaning',
    'binded',
  ];

  private meaningOptions = [
    { id: '1', label: 'Новый' },
    { id: '2', label: 'Уточнение' },
    { id: '3', label: 'Уточнение об аннулировании' },
    { id: '4', label: 'Уточнение о деаннулировании (отмена аннулирования)' },
  ];

  get payments(): Payment[] {
    return this.model?.paymentsReceived?.map(
      (payment: { [key: string]: any }, index: number) => ({
        paymentDate: convertDateFromBackendFormat(
          payment.paymentDate,
          DateFormat.invertedDatetime
        ),
        id: payment.id,
        index: index,
        amount: (Number(payment.amount) / 100).toFixed(2),
        narrative: payment.purpose,
        kbk: payment.kbk,
        payerId: payment.payer?.payerIdentifier,
        paymentId: payment?.paymentId,
        supplierBillId: payment.acknowledgmentInfo?.supplierBillID,
        binded: !!payment.acknowledgmentInfo?.supplierBillID?.length,
        meaning: this.meaningOptions.find(
          (el) => el.id === payment.changeStatusInfo.meaning
        )?.label,
      })
    );
  }

  // •	Сумма с учетом возврата

  get tableColumns(): Array<QColumn> {
    return [
      {
        name: 'paymentDate',
        label: this.$t('PaymentsSearchCard.paymentDate'),
        field: 'paymentDate',
        align: 'left',
        sortable: true,
      },
      {
        name: 'amount',
        label: this.$t('PaymentsSearchCard.amount'),
        field: 'amount',
        align: 'left',
      },
      {
        name: 'narrative',
        label: this.$t('PaymentsSearchCard.narrative'),
        field: 'narrative',
        align: 'left',
        style: 'white-space: normal; min-width: 250px;',
      },
      {
        name: 'kbk',
        label: this.$t('PaymentsSearchCard.KBK'),
        field: 'kbk',
        align: 'left',
      },
      {
        name: 'payerId',
        label: this.$t('PaymentsSearchCard.payerId'),
        field: 'payerId',
        align: 'left',
      },
      {
        name: 'paymentId',
        label: this.$t('PaymentsSearchCard.paymentId'),
        field: 'paymentId',
        align: 'left',
      },
      {
        name: 'supplierBillId',
        label: this.$t('PaymentsSearchCard.supplierBillId'),
        field: 'supplierBillId',
        align: 'left',
      },
      {
        name: 'meaning',
        label: this.$t('PaymentsSearchCard.meaning'),
        field: 'meaning',
        align: 'center',
      },
      {
        name: 'binded',
        label: this.$t('PaymentsSearchCard.binded'),
        field: 'binded',
        align: 'center',
      },
      {
        name: 'action',
        label: this.$t('PaymentsSearchCard.action'),
        field: 'action',
        align: 'center',
      },
    ];
  }

  isQuittencedPayment(payment: Payment): boolean {
    return !!get(payment, 'supplierBillId');
  }

  @Watch('model.payments', { deep: true, immediate: true })
  hasRegisteredCharge(): void {
    this.chargesRegistered = get(this.model, 'payments')?.reduce(
      (charges: Charge[], charge: Charge) => {
        if (charge.EPGUPaymentRequired !== false) {
          return charges;
        }
        if (
          (Number(charge.systemStatus) >= 3 &&
            !charge.quittance &&
            charge.EPGUPaymentRequired === false) ||
          (Number(charge.systemStatus) >= 3 &&
            charge.quittance?.paymentIdData?.length)
        ) {
          return [
            ...charges,
            {
              ...charge?.charge,
              id: charge?.id,
            },
          ];
        }
        return charges;
      }, []);

    if (this.chargesRegistered?.length) {
      this.visibleColumns.push('action');
    }
  }

  created(): void {
    this.getPayerDictionaries();
  }

  async getPayerDictionaries(): Promise<void> {
    const requests = this.dictionariesList.map(
      async (name) =>
        await dictionaryApi
          .searchDictionary(`name==${name}`)
          .then(({ data }) => data[0])
    );
    this.dictionaries = await Promise.all(requests);
  }

  private paginationLabelCustom(pagination: TablePagination): string {
    const page = pagination.page;
    const rowsPerPage = pagination.rowsPerPage;
    const rowsNumber = pagination.rowsNumber || Number(this.payments?.length);
    const firstNumber = (page - 1) * rowsPerPage + rowsPerPage;

    return `${(page - 1) * rowsPerPage + 1} - ${
      firstNumber < rowsNumber ? firstNumber : rowsNumber
    } ${this.$t('base.of').toString().toLowerCase()} ${rowsNumber}`;
  }
}
</script>
