export const ROYAL_POP_CART_KEY = "royal-pop-cart";
export const ROYAL_POP_BUILDER_KEY = "royal-pop-builder-selection";
export const ROYAL_POP_CART_LIMIT = Number.POSITIVE_INFINITY;

export interface RoyalPopSelection {
	style: string;
	colorwayId: string;
	finishId: string;
	quantity: number;
}

export interface RoyalPopCartItem {
	id: string;
	style: string;
	colorwayId: string;
	finishId: string;
	quantity: number;
}

const isBrowser = () => typeof window !== "undefined" && typeof window.localStorage !== "undefined";

const readJson = <T,>(key: string, fallback: T): T => {
	if (!isBrowser()) return fallback;

	try {
		const raw = window.localStorage.getItem(key);
		if (!raw) return fallback;
		return JSON.parse(raw) as T;
	} catch {
		return fallback;
	}
};

const writeJson = (key: string, value: unknown) => {
	if (!isBrowser()) return;

	try {
		window.localStorage.setItem(key, JSON.stringify(value));
	} catch {
		// Ignore storage write failures.
	}
};

const createItemId = () => {
	if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
		return crypto.randomUUID();
	}

	return `rp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
};

const normalizeSelection = (selection: Partial<RoyalPopSelection>): RoyalPopSelection => ({
	style: selection.style === "A" ? "A" : "B",
	colorwayId: selection.colorwayId || "sorbet-pop-multi-color",
	finishId: selection.finishId || "silver",
	quantity: Math.max(1, Math.round(Number(selection.quantity) || 1)),
});

export const loadBuilderSelection = (): RoyalPopSelection | null => {
	const selection = readJson<Partial<RoyalPopSelection> | null>(ROYAL_POP_BUILDER_KEY, null);
	if (!selection) return null;
	return normalizeSelection(selection);
};

export const saveBuilderSelection = (selection: Partial<RoyalPopSelection>) => {
	writeJson(ROYAL_POP_BUILDER_KEY, normalizeSelection(selection));
};

export const loadCart = (): RoyalPopCartItem[] => {
	const items = readJson<Partial<RoyalPopCartItem>[]>(ROYAL_POP_CART_KEY, []);

	return items
		.filter((item) => item && item.colorwayId && item.finishId)
		.map((item) => ({
			id: item.id || createItemId(),
			style: item.style === "A" ? "A" : "B",
			colorwayId: String(item.colorwayId),
			finishId: String(item.finishId),
			quantity: Math.max(1, Math.round(Number(item.quantity) || 1)),
		}))
;
};

export const saveCart = (items: RoyalPopCartItem[]) => {
	writeJson(
		ROYAL_POP_CART_KEY,
		items.map((item) => ({
			...item,
			quantity: Math.max(1, Math.round(Number(item.quantity) || 1)),
		})),
	);
};

export const getCartCount = () => loadCart().reduce((sum, item) => sum + Math.max(1, Number(item.quantity) || 1), 0);

export const addSelectionToCart = (selection: Partial<RoyalPopSelection>) => {
	const normalized = normalizeSelection(selection);
	const currentCart = loadCart();
	const matchingIndex = currentCart.findIndex(
		(item) =>
			item.style === normalized.style &&
			item.colorwayId === normalized.colorwayId &&
			item.finishId === normalized.finishId,
	);

	let nextCart: RoyalPopCartItem[];
	if (matchingIndex >= 0) {
		nextCart = currentCart.map((item, index) =>
			index === matchingIndex
				? {
					...item,
					quantity: Math.max(1, Number(item.quantity) || 1) + normalized.quantity,
				}
				: item,
		);
	} else {
		nextCart = [
			...currentCart,
			{
				id: createItemId(),
				style: normalized.style,
				colorwayId: normalized.colorwayId,
				finishId: normalized.finishId,
				quantity: normalized.quantity,
			},
		];
	}

	saveCart(nextCart);

	return {
		cart: nextCart,
		addedCount: normalized.quantity,
		isFull: false,
	};
};

export const getEffectiveCart = (): RoyalPopCartItem[] => {
	const cart = loadCart();
	if (cart.length > 0) return cart;

	const selection = loadBuilderSelection();
	if (!selection) return [];

	return [
		{
			id: createItemId(),
			style: selection.style,
			colorwayId: selection.colorwayId,
			finishId: selection.finishId,
			quantity: selection.quantity,
		},
	];
};

export const groupCartItems = (items: RoyalPopCartItem[]) => {
	const groups = new Map<string, { style: string; colorwayId: string; finishId: string; quantity: number }>();

	items.forEach((item) => {
		const key = `${item.style}::${item.colorwayId}::${item.finishId}`;
		const current = groups.get(key);
		const itemQuantity = Math.max(1, Math.round(Number(item.quantity) || 1));

		if (current) {
			current.quantity += itemQuantity;
			return;
		}

		groups.set(key, {
			style: item.style,
			colorwayId: item.colorwayId,
			finishId: item.finishId,
			quantity: itemQuantity,
		});
	});

	return Array.from(groups.values());
};

export const removeCartItem = (itemId: string) => {
	const nextCart = loadCart().filter((item) => item.id !== itemId);
	saveCart(nextCart);
	return nextCart;
};

export const clearCart = () => {
	if (!isBrowser()) return;
	window.localStorage.removeItem(ROYAL_POP_CART_KEY);
};
