import mipsApi from '@apis/mips.api'
import { Injectable } from '@nestjs/common'
import { PaymentLink } from '@/entities/payment-link.entity'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
import * as moment from "moment"
import { CustomerService } from '@/services/customer.service'
import { InvoiceService } from '@/services/invoice.service'

@Injectable()
export class PaymentService {
	constructor(
		@InjectRepository(PaymentLink)
		private paymentLinkRepository: Repository<PaymentLink>,
		private readonly customerService: CustomerService,
		private readonly invoiceService: InvoiceService,
	) {}

    async addPaymentLink(invoiceId: string) {
        try {
			const invoice = await this.invoiceService.getInvoice(invoiceId)
			const customer = await this.customerService.getCustomer(invoice?.CustomerRef?.value)

			let paymentLink = await this.getPaymentLink(invoiceId)
			if (!paymentLink) {
				paymentLink = await this.create({
					customer,
					invoice: invoice,
				})
			}

            await this.invoiceService.addPaymentLinkToInvoice(invoice, paymentLink)

            return paymentLink
        } catch (error) {
            throw new Error(`Failed to add payment link to invoice ${invoiceId}: ${error.message}`)
        }
    }

	async create({ customer, invoice }: { customer: any; invoice: any }) {
		try {
			const authentify = {
				id_merchant: process.env.MIPS_MERCHANT_ID,
				id_entity: process.env.MIPS_ENTITY_ID,
				id_operator: process.env.MIPS_OPERATOR_ID,
				operator_password: process.env.MIPS_OPERATOR_PASSWORD,
			}

            let exp_date = moment(invoice.TxnDate).add(12, 'months')

			const request = {
				request_mode: 'simple',
				sending_mode: 'link',
				request_title: `Invoice ${invoice?.DocNumber}`,
				exp_date: exp_date.format('YYYY-MM-DD'),
				client_details: {
					first_name: customer?.GivenName,
					last_name: customer?.FamilyName,
					client_email: invoice?.BillEmail?.Address,
				},
			}

			const body = {
				authentify,
				request,
				initial_payment: {
					id_order: `INV#${invoice?.DocNumber}`,
					currency: 'MUR',
					amount: invoice?.TotalAmt,
				},
			}

			const response: any = await mipsApi.post('create_payment_request', body)

			if (response.data?.operation_status !== 'success') {
				throw new Error(`Failed to create payment: ${response.data?.operation_status_details}`)
			}

            const paymentLink = this.savePaymentLink('mips', response.data?.payment_link?.url, invoice?.Id, invoice?.TotalAmt, exp_date.toDate())

			return paymentLink
		} catch (error) {
			throw new Error(`Failed to create payment: ${error.message}`)
		}
	}

	async getPaymentLink(invoiceId: string): Promise<PaymentLink | null> {
		return this.paymentLinkRepository.findOne({ where: { invoiceId } })
	}

	async savePaymentLink(provider: string, url: string, invoiceId: string, amount: number, expiresAt: Date): Promise<PaymentLink> {
		const paymentLink = new PaymentLink()
		paymentLink.provider = provider
		paymentLink.url = url
		paymentLink.invoiceId = invoiceId
		paymentLink.amount = amount
        paymentLink.expiresAt = expiresAt
		return this.paymentLinkRepository.save(paymentLink)
	}
}
