import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { v4 as uuidv4 } from 'uuid';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { generateInvoiceCodeHelper } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/generate-invoice-code.helper';
import * as moment from 'moment';
import { TransactionItemModel } from 'src/modules/transaction/transaction/data/models/transaction-item.model';
import { RescheduleVerificationModel } from '../../../data/models/reschedule-verification.model';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';

@Injectable()
export class RescheduleManager {
  constructor(private serviceData: TransactionDataService) {}

  async reschedule(data: RescheduleVerificationModel) {
    const transaction = await this.serviceData.getTransactionWithReschedule(
      data.booking_id,
    );

    const rescheduleDate = moment(data.reschedule_date, 'DD-MM-YYYY');

    const id = uuidv4();
    const invoiceCode = await generateInvoiceCodeHelper(
      this.serviceData,
      'BOOK',
    );

    const items = this.makeItemZeroPrice(transaction.items);
    const transactionData = this.makeTransactionZeroPrice(transaction);

    Object.assign(transactionData, {
      parent_id: transaction.id,
      id,
      invoice_code: invoiceCode,
      status: STATUS.SETTLED,
      invoice_date: rescheduleDate.format('YYYY-MM-DD'),
      booking_date: rescheduleDate.format('YYYY-MM-DD'),
      created_at: moment().unix() * 1000,
      updated_at: moment().unix() * 1000,
      items,
    });

    await this.serviceData.getRepository().save(transactionData);

    const whatsapp = new WhatsappService();
    whatsapp.rescheduleCreated({
      id: transactionData.id,
      name: transactionData.customer_name,
      phone: transactionData.customer_phone,
      time: moment(transactionData.invoice_date).unix() * 1000,
      code: transactionData.invoice_code,
    });

    return transactionData;
  }

  private makeItemZeroPrice(items: TransactionItemModel[]) {
    return items.map((item) => {
      return {
        ...item,
        id: uuidv4(),
        item_price: 0,
        total_price: 0,
        total_hpp: 0,
        total_profit: 0,
        total_profit_share: 0,
        payment_total_dpp: 0,
        payment_total_tax: 0,
        total_net_price: 0,
      };
    });
  }

  private makeTransactionZeroPrice(transaction: TransactionModel) {
    return {
      ...transaction,
      payment_sub_total: 0,
      payment_discount_total: 0,
      payment_total: 0,
      payment_total_pay: 0,
      payment_total_share: 0,
      payment_total_tax: 0,
      payment_total_profit: 0,
      payment_total_net_profit: 0,
      payment_total_dpp: 0,
      discount_percentage: 0,
    };
  }
}
