import Api from '../../services/api';
import type { OrderRequestItem, OrderRequestPayload } from '../../types/api';
import { AnalyticsConsent } from '../../services/analyticsConsent';
import { Identity } from '../../services/identity';

const MAX_ITEMS = 50;
const MAX_URL_LENGTH = 500;
const MAX_STRING_LENGTH = 128;

export interface TrackOrderItemInput {
	id?: string;
	productId?: string;
	product_id?: string;
	quantity?: number;
	price?: number;
}

export interface TrackOrderPayload {
	orderId: string;
	revenue: number;
	currency: string;
	items?: TrackOrderItemInput[];
	products?: TrackOrderItemInput[];
	pageLocation?: string;
	pageReferrer?: string;
}

export interface TrackOrderResult {
	success: boolean;
	error?: string;
}

export const trackOrder = async (input: TrackOrderPayload): Promise<TrackOrderResult> => {
	try {
		if (!AnalyticsConsent.has()) {
			return { success: false, error: 'Analytics consent not granted' };
		}
		const payload = buildRequestPayload(input);
		await Api.trackOrder(payload);
		return { success: true };
	} catch (error) {
		const message = error instanceof Error ? error.message : 'Unknown error';
		console.warn('AdalongTrack: failed to send order', message);
		return { success: false, error: message };
	}
};

const sanitizeString = (value: unknown, maxLength = MAX_STRING_LENGTH): string | undefined => {
	if (typeof value !== 'string') {
		return undefined;
	}
	const trimmed = value.trim();
	return trimmed ? trimmed.slice(0, maxLength) : undefined;
};

const sanitizeNumber = (value: unknown): number | undefined => {
	const numeric = typeof value === 'number' ? value : Number(value);
	return Number.isFinite(numeric) ? numeric : undefined;
};

const sanitizeCurrency = (value: unknown): string | undefined => {
	const sanitized = sanitizeString(value, 10);
	return sanitized ? sanitized.toUpperCase() : undefined;
};

const roundCurrency = (value: number): number => Math.round(value * 100) / 100;

const getDefaultLocation = (): string | undefined => {
	if (typeof window === 'undefined' || !window.location) {
		return undefined;
	}
	return window.location.href.slice(0, MAX_URL_LENGTH);
};

const getDefaultReferrer = (): string | undefined => {
	if (typeof document === 'undefined') {
		return undefined;
	}
	return document.referrer ? document.referrer.slice(0, MAX_URL_LENGTH) : undefined;
};

const normalizeItems = (items?: TrackOrderItemInput[]): OrderRequestItem[] | undefined => {
	if (!Array.isArray(items) || items.length === 0) {
		return undefined;
	}

	const normalized = items
		.slice(0, MAX_ITEMS)
		.map((item) => {
			const productId =
				sanitizeString(item.productId ?? item.product_id ?? item.id, MAX_STRING_LENGTH);

			if (!productId) {
				return undefined;
			}

			const normalizedItem: OrderRequestItem = { productId };

			const quantity = sanitizeNumber(item.quantity);
			if (quantity !== undefined && quantity > 0) {
				normalizedItem.quantity = Math.trunc(quantity);
			}

			const price = sanitizeNumber(item.price);
			if (price !== undefined && price >= 0) {
				normalizedItem.price = roundCurrency(price);
			}

			return normalizedItem;
		})
		.filter((value): value is OrderRequestItem => Boolean(value));

	return normalized.length > 0 ? normalized : undefined;
};

export const buildRequestPayload = (input: TrackOrderPayload): OrderRequestPayload => {
	if (!input || typeof input !== 'object') {
		throw new Error('trackOrder: payload must be an object');
	}

	const orderId = sanitizeString(input.orderId);
	if (!orderId) {
		throw new Error('trackOrder: orderId is required');
	}

	const revenue = sanitizeNumber(input.revenue);
	if (revenue === undefined) {
		throw new Error('trackOrder: revenue must be a number');
	}

	const currency = sanitizeCurrency(input.currency);
	if (!currency) {
		throw new Error('trackOrder: currency is required');
	}

	const identityPayload = (() => {
		if (!AnalyticsConsent.has()) {
			return undefined;
		}
		const identity = Identity.getIdentity();
		if (!identity) {
			return undefined;
		}
		Identity.touchSession();
		return {
			visitor_id: identity.visitorId,
			session_id: identity.sessionId,
		};
	})();

	const rawItems = input.items ?? input.products;
	const normalizedItems = normalizeItems(rawItems);

	const pageLocation = sanitizeString(input.pageLocation, MAX_URL_LENGTH) ?? getDefaultLocation();
	const pageReferrer = sanitizeString(input.pageReferrer, MAX_URL_LENGTH) ?? getDefaultReferrer();

	const payload: OrderRequestPayload = {
		order_id: orderId,
		revenue: roundCurrency(revenue),
		currency,
		...(identityPayload ?? {}),
		...(normalizedItems ? { items: normalizedItems } : {}),
		...(pageLocation ? { page_location: pageLocation } : {}),
		...(pageReferrer ? { page_referrer: pageReferrer } : {}),
	};

	return payload;
};

export type { TrackOrderPayload as OrderPayload, TrackOrderItemInput as OrderItemPayload };
