import { get } from "svelte/store";
import {
	getDefaultOrderCursor,
	type PaginatedOrderInfoModel,
	type OrderCursorModel,
	getDefaultPaginatedOrderInfoModel,
} from "../data/entities";
import { trpcApiStore } from "$lib/stores/api";
import type { Result } from "@pkg/result";
import { toast } from "svelte-sonner";
import { encodeCursor } from "$lib/core/string.utils";

export class OrderViewModel {
	orderInfo = $state<PaginatedOrderInfoModel>(
		getDefaultPaginatedOrderInfoModel(),
	);
	fetching = $state(false);
	query = $state("");

	private getApi() {
		return get(trpcApiStore);
	}

	private _getPayload() {
		return {
			limit: this.orderInfo.limit,
			asc: this.orderInfo.asc,
			page: this.orderInfo.page,
			totalItemCount: this.orderInfo.totalItemCount,
			totalPages: this.orderInfo.totalPages,
			cursor: this.orderInfo.cursor,
		};
	}

	async fetchNextPage() {
		const api = this.getApi();
		this.fetching = true;
		if (!this.orderInfo || !api) {
			return;
		}
		if (
			this.orderInfo.page >= this.orderInfo.totalPages &&
			this.orderInfo.totalPages > 0
		) {
			console.log("Not fetching next page, at the end");
			return;
		}
		const res = await api.user.getAgentsPaginatedInfo.query({
			info: this._getPayload(),
			fetchNext: true,
		});
		console.log(res);
		this.fetching = false;
		this.setOrderInfoState(res as Result<PaginatedOrderInfoModel>);
	}

	async fetchPrevPage() {
		const api = this.getApi();
		this.fetching = true;
		if (!this.orderInfo || !api) {
			return;
		}
		if (this.orderInfo.page <= 1 || this.orderInfo.totalPages <= 1) {
			console.log("Not fetching prev page, at the start");
			return;
		}
		const res = await api.user.getAgentsPaginatedInfo.query({
			info: this._getPayload(),
			fetchNext: false,
		});
		this.fetching = false;
		this.setOrderInfoState(res as Result<PaginatedOrderInfoModel>);
	}

	private setOrderInfoState(res: Result<PaginatedOrderInfoModel>) {
		if (res.error) {
			return toast.error(res.error.message, {
				description: res.error.userHint,
			});
		}
		if (!res.data) {
			this.resetOrderInfo();
			return;
		}
		this.orderInfo = {
			...res.data,
			data: res.data.data.map((item) => {
				return {
					...item,
					createdAt: new Date(item.createdAt).toISOString(),
					updatedAt: new Date(item.updatedAt).toISOString(),
				};
			}),
		};
	}

	async searchOrders() {
		if (!this.orderInfo) {
			return;
		}
		this.resetOrderInfo();
		await this.fetchNextPage();
	}

	resetOrderInfo() {
		this.orderInfo = {
			data: [],
			cursor: encodeCursor<OrderCursorModel>({
				...getDefaultOrderCursor(),
				query: this.query,
			}),
			limit: this.orderInfo.limit,
			asc: this.orderInfo.asc,
			totalItemCount: 0,
			totalPages: 0,
			page: 0,
		};
	}
}

export const orderVM = new OrderViewModel();
