/home/bdqbpbxa/dev-subdomains/admin.pixory.goodface.com.ua/src/stripe/stripe.service.ts
import Stripe from 'stripe';
import { env } from 'src/config/env';
import { round } from 'src/api/utils/math';
import { Configuration } from 'src/api/configuration/common/types/pricing';
import { CreateCustomerDto } from './types/createCustomer.dto';
import { UpdateCustomerDto } from './types/updateCustomer.dto';
import { CreateIntentDto, UpdateIntentDto } from './types/checkout.dto';


export class StripeService {
	private readonly stripe = new Stripe(env.stripe.apiKey, {
		apiVersion: '2025-08-27.preview',
	});

	/**
	 * Function to get exchange rates from Stripe API
	 */
	async getRates(): Promise<{[key: string]: Stripe.FxQuote.Rates}> {
		const pricing = await strapi.db.query('api::configuration.configuration').findOne() as Configuration;
		const response = await this.stripe.fxQuotes.create({
			to_currency: pricing.defaultCurrency,
			from_currencies: pricing.availableCurrencies,
			lock_duration: 'day',
		});

		return response.rates;
	}

	/**
	 * Function to create Stripe customer
	 * @param {CreateCustomerDto} dto Data of user in app
	 * @returns {Promise<string>} Stripe customer Id
	 */
	async createCustomer(dto: CreateCustomerDto): Promise<string> {
		const customer = await this.stripe.customers.create({
			email: dto.email,
			name: `${dto.firstName + dto.lastName}`,
			metadata: {
				id: dto.id
			}
		})

		return customer.id
	}

	/**
	 * Function to update Stripe customer
	 * @param {UpdateCustomerDto} dto Data of user to update
	 * @returns {string} Stripe customer Id
	 */
	async updateCustomer(id: string, dto: UpdateCustomerDto): Promise<string> {
		const customer = await this.stripe.customers.update(id, {
			email: dto.email,
			name: `${dto.firstName + dto.lastName}`,
		})

		return customer.id
	}

	/**
	 * Function to delete Stripe customer
	 * @returns {number} Status Code
	 */
	async deleteCustomer(id: string): Promise<string> {
		const customer = await this.stripe.customers.del(id)

		return customer.id
	}


	async getPaymentIntent(id: string) {
		const paymentIntent = await this.stripe.paymentIntents.retrieve(id)

		return {
			id: paymentIntent.id,
			client_secret: paymentIntent.client_secret,
			chargeId: paymentIntent.latest_charge
		}
	}

	async createPaymentIntent(dto: CreateIntentDto) {
		const paymentIntent = await this.stripe.paymentIntents.create({
			customer: dto.customerId,
			amount: round(dto.amount * 100),
			currency: "GBP",
			payment_method_types: ['card']
		})

		return {
			id: paymentIntent.id,
			client_secret: paymentIntent.client_secret
		}
	}

	async updatePaymentIntent(id: string, dto: UpdateIntentDto) {
		const paymentIntent = await this.stripe.paymentIntents.update(id, {
			amount: dto.amount ? dto.amount * 100 : undefined,
			description: dto.orderId ? `Order #${dto.orderId}` : undefined,
			metadata: dto.orderId ? {
				orderId: dto.orderId
			} : undefined
		})

		return {
			id: paymentIntent.id,
			client_secret: paymentIntent.client_secret
		}
	}

	async refundCheckout(dto) {
		let refund = await this.stripe.refunds.create({
			charge: dto.chargeId,
			amount: dto.amount * 100,
			reason: "requested_by_customer",
		})

		return refund.id
	}

	async validateWebhook(body: any, sig: string | string[]) {
		let res;
		try {
			res = await this.stripe.webhooks.constructEvent(body, sig, env.stripe.webhookSecret)
		} catch (error) {
			throw new Error(error)
		}

		return res
	}

}