import { billingDetailsVM } from "$lib/domains/checkout/payment-info-section/billing.details.vm.svelte";
import { calculateFinalPrices } from "$lib/domains/checkout/utils";
import { ckFlowVM } from "$lib/domains/ckflow/view/ckflow.vm.svelte";
import { currencyStore } from "$lib/domains/currency/view/currency.vm.svelte";
import { customerInfoVM } from "$lib/domains/customerinfo/view/customerinfo.vm.svelte";
import {
	createOrderPayloadModel,
	OrderCreationStep,
} from "$lib/domains/order/data/entities";
import { productStore } from "$lib/domains/product/store";
import { trpcApiStore } from "$lib/stores/api";
import { toast } from "svelte-sonner";
import { get } from "svelte/store";

/**
 * CreateOrderViewModel manages the order creation flow for product checkout.
 * Handles step progression, validation, and order submission.
 */
export class CreateOrderViewModel {
	// Current step in the order creation flow
	orderStep = $state(OrderCreationStep.CUSTOMER_INFO);

	// Loading state
	loading = $state(false);

	/**
	 * Sets the current order creation step
	 * @param step - The step to navigate to
	 */
	setStep(step: OrderCreationStep) {
		this.orderStep = step;
	}

	/**
	 * Advances to the next step in the order creation flow
	 */
	setNextStep() {
		if (this.orderStep === OrderCreationStep.CUSTOMER_INFO) {
			// Validate customer info before proceeding
			if (!this.isCustomerInfoValid()) {
				toast.error("Please complete customer information");
				return;
			}
			this.orderStep = OrderCreationStep.PAYMENT;
		} else if (this.orderStep === OrderCreationStep.PAYMENT) {
			this.orderStep = OrderCreationStep.SUMMARY;
		}
	}

	/**
	 * Goes back to the previous step
	 */
	setPrevStep() {
		if (this.orderStep === OrderCreationStep.SUMMARY) {
			this.orderStep = OrderCreationStep.PAYMENT;
		} else if (this.orderStep === OrderCreationStep.PAYMENT) {
			this.orderStep = OrderCreationStep.CUSTOMER_INFO;
		}
	}

	/**
	 * Validates if customer information is complete
	 * @returns true if customer info is valid, false otherwise
	 */
	isCustomerInfoValid(): boolean {
		if (!customerInfoVM.customerInfo) {
			return false;
		}
		return customerInfoVM.isValid();
	}

	/**
	 * Validates if product is selected
	 * @returns true if product exists, false otherwise
	 */
	isProductValid(): boolean {
		const product = get(productStore);
		return product !== null && product.id !== undefined;
	}

	/**
	 * Checks if order can be submitted (all validations pass)
	 * @returns true if order is ready to submit, false otherwise
	 */
	canSubmitOrder(): boolean {
		return this.isProductValid() && this.isCustomerInfoValid();
	}

	/**
	 * Creates and submits the order
	 * @returns true if successful, false otherwise
	 */
	async createOrder(): Promise<boolean> {
		const api = get(trpcApiStore);
		if (!api) {
			toast.error("API client not initialized");
			return false;
		}

		const product = get(productStore);
		if (!product || !customerInfoVM.customerInfo) {
			toast.error("Missing required information", {
				description: "Product or customer information is incomplete",
			});
			return false;
		}

		// Calculate price details from product
		const priceDetails = calculateFinalPrices(
			product,
			customerInfoVM.customerInfo,
		);

		// Build the order payload
		const parsed = createOrderPayloadModel.safeParse({
			product: product,
			productId: product.id,
			customerInfo: customerInfoVM.customerInfo,
			paymentInfo: billingDetailsVM.billingDetails,
			orderModel: {
				...priceDetails,
				productId: product.id,
				currency: get(currencyStore).code,
			},
			flowId: ckFlowVM.flowId,
		});

		if (parsed.error) {
			console.error("Order payload validation error:", parsed.error.errors);
			const err = parsed.error.errors[0];
			toast.error("Invalid order data", {
				description: `${err.path.join(".")}: ${err.message}`,
			});
			return false;
		}

		this.loading = true;

		try {
			const out = await api.order.createOrder.mutate(parsed.data);

			if (out.error) {
				toast.error(out.error.message, {
					description: out.error.userHint,
				});
				return false;
			}

			if (!out.data) {
				toast.error("Order creation failed", {
					description:
						"Please try again, or contact support if the issue persists",
				});
				return false;
			}

			toast.success("Order created successfully", {
				description: "Please wait, redirecting...",
			});

			// Redirect to success page after a short delay
			setTimeout(() => {
				window.location.href = `/order/success?uid=${out.data}`;
			}, 1000);

			return true;
		} catch (e) {
			console.error("Order creation error:", e);
			toast.error("An unexpected error occurred", {
				description: "Please try again later",
			});
			return false;
		} finally {
			this.loading = false;
		}
	}

	/**
	 * Resets the view model state
	 */
	reset() {
		this.orderStep = OrderCreationStep.CUSTOMER_INFO;
		this.loading = false;
	}
}

export const createOrderVM = new CreateOrderViewModel();
