import format from 'template-format';

function getWatchUrl(scene) {
	try {
		if (scene.url) {
			return new URL(scene.url).href;
		}

		if (scene.channel && (scene.channel.isIndependent || scene.channel.type === 'network' || !scene.network)) {
			return new URL(scene.channel.url).href;
		}

		if (scene.network) {
			return new URL(scene.network.url).href;
		}
	}
	catch (_error) {
		// invalid URL
	}

	return null;
}

export function getAffiliateSceneUrl(scene) {
	const watchUrl = getWatchUrl(scene);

	if (!watchUrl) {
		return null;
	}

	if (!scene.affiliate || scene.affiliate.parameters.scene === false) {
		return watchUrl;
	}

	if (scene.affiliate.parameters.channelScenes === false && scene.channel && scene.affiliate.entityId !== scene.channel.id) {
		return watchUrl;
	}

	if (scene.affiliate.parameters.dynamicScene) {
		const scenePath = new URL(watchUrl).pathname;

		return format(scene.affiliate.parameters.dynamicScene, {
			scenePath: scene.affiliate.parameters.prefixSlash === false
				? scenePath.replace(/^\//, '')
				: scenePath,
			entryId: scene.entryId,
		});
	}

	if (scene.affiliate.parameters.query) { // used by e.g. Bang
		const newParams = new URLSearchParams({
			...Object.fromEntries(new URL(watchUrl).searchParams),
			...Object.fromEntries(new URLSearchParams(scene.affiliate.parameters.query)),
		});

		return `${watchUrl}?${newParams.toString()}`;
	}

	const affiliateUrl = scene.affiliate.parameters.replaceScene?.hostname === new URL(watchUrl).hostname
		? scene.affiliate.parameters.replaceScene.url
		: scene.affiliate.url;

	if (!affiliateUrl) {
		return watchUrl;
	}

	// NATS deep URL
	if (affiliateUrl.includes('/track')
		&& scene.affiliate.parameters.scene !== false
		&& (!scene.channel.isIndependent || scene.channel.id === scene.affiliate.entityId)) {
		const { pathname, search } = new URL(watchUrl);

		return `${affiliateUrl}${pathname.replace(/^\/(trial|tour)/, '')}${search}`; // replace needed for Jules Jordan and HussiePass, verify behavior on other sites
	}

	const affiliateUrlComponents = new URL(affiliateUrl);

	// NetFame / GammaE deep URL
	if (affiliateUrlComponents.searchParams.has('pa') && affiliateUrlComponents.searchParams.has('ar')) {
		affiliateUrlComponents.searchParams.set('pa', 'clip');
		affiliateUrlComponents.searchParams.set('ar', scene.entryId);

		return affiliateUrlComponents.href;
	}

	return watchUrl;
}

function getEntityUrl(entity) {
	try {
		return new URL(entity.url || entity.parent?.url).href;
	}
	catch (_error) {
		return null;
	}
}

export function getAffiliateEntityUrl(entity, affiliate) {
	const entityUrl = getEntityUrl(entity);
	const entityAffiliate = affiliate || entity.affiliate;

	if (!entityUrl) {
		return null;
	}

	if (!entityAffiliate) {
		return entityUrl;
	}

	const affiliateUrl = entityAffiliate.parameters?.replaceEntity?.hostname === new URL(entityUrl).hostname
		? entityAffiliate.parameters.replaceEntity.url
		: entityAffiliate.url;

	if (affiliateUrl && (entity.id === entityAffiliate.entityId || entityUrl === entity.parent?.url)) {
		return affiliateUrl;
	}

	if (entityAffiliate.parameters?.query) {
		const newParams = new URLSearchParams({
			...Object.fromEntries(new URL(entityUrl).searchParams),
			...Object.fromEntries(new URLSearchParams(entityAffiliate.parameters.query)),
		});

		return `${entityUrl}?${newParams.toString()}`;
	}

	if (entity.type === 'network' || entity.isIndependent) {
		return entityUrl;
	}

	// channel has its own domain
	if (new URL(entityUrl).pathname === '/' && entityUrl !== entity.parent?.url) {
		return entityUrl;
	}

	if (entityAffiliate.parameters.dynamicEntity) {
		const entityPath = new URL(entityUrl).pathname;

		return format(entityAffiliate.parameters.dynamicEntity, {
			entityPath: entityAffiliate.parameters.prefixSlash
				? entityPath
				: entityPath.replace(/^\//, ''),
		});
	}

	if (affiliateUrl?.includes('/track')
		&& entityAffiliate.parameters.channel !== false) {
		const { pathname, search } = new URL(entityUrl);

		return `${affiliateUrl}${pathname.replace(/^\/trial/, '')}${search}`; // replace needed for Jules Jordan, verify behavior on other sites
	}

	return entityUrl;
}
