import type { CustomerInfoModel } from "$lib/domains/customerinfo/data";
import type { PaymentInfoPayload } from "$lib/domains/paymentinfo/data/entities";
import { db } from "@pkg/db";
import { isTimestampMoreThan1MinAgo } from "@pkg/logic/core/date.utils";
import type {
	CreateCheckoutFlowPayload,
	FlowInfo,
	PaymentFlowStepPayload,
	PrePaymentFlowStepPayload,
} from "../data/entities";
import { CheckoutFlowRepository } from "../data/repository";

export class CheckoutFlowUseCases {
	constructor(private repo: CheckoutFlowRepository) {}

	async createFlow(payload: CreateCheckoutFlowPayload) {
		return this.repo.createFlow(payload);
	}

	async getFlowInfo(flowId: string) {
		const out = await this.repo.getFlowInfo(flowId);
		if (out.error || !out.data) {
			return out;
		}
		if (isTimestampMoreThan1MinAgo(out.data.lastPinged)) {
			await this.updateFlowState(flowId, {
				...out.data,
				lastPinged: new Date().toISOString(),
			});
		}
		return out;
	}

	async updateFlowState(id: string, state: FlowInfo) {
		return this.repo.updateFlowState(id, state);
	}

	async cleanupFlow(id: string, other: any) {
		return this.repo.cleanupFlow(id, other);
	}

	async goBackToInitialStep(flowId: string) {
		return this.repo.goBackToInitialStep(flowId);
	}

	async executePrePaymentStep(
		flowId: string,
		payload: PrePaymentFlowStepPayload,
	) {
		return this.repo.executePrePaymentStep(flowId, payload);
	}

	async executePaymentStep(flowId: string, payload: PaymentFlowStepPayload) {
		return this.repo.executePaymentStep(flowId, payload);
	}

	async syncPersonalInfo(flowId: string, personalInfo: CustomerInfoModel) {
		return this.repo.syncPersonalInfo(flowId, personalInfo);
	}

	async syncPaymentInfo(flowId: string, paymentInfo: PaymentInfoPayload) {
		return this.repo.syncPaymentInfo(flowId, paymentInfo);
	}

	async ping(flowId: string) {
		return this.repo.ping(flowId);
	}

	async areCheckoutAlreadyLiveForOrder(refOids: number[]) {
		return this.repo.areCheckoutAlreadyLiveForOrder(refOids);
	}
}

export function getCKUseCases() {
	const repo = new CheckoutFlowRepository(db);
	return new CheckoutFlowUseCases(repo);
}
