<template>
	<iframe
		v-if="campaign?.banner?.type === 'html'"
		ref="iframe"
		:width="campaign.banner.width"
		:height="campaign.banner.height"
		:src="getSource(campaign)"
		scrolling="none"
		marginwidth="0"
		marginheight="0"
		class="campaign frame"
		data-umami-event="campaign-click"
		:data-umami-event-campaign-id="`${campaign.entity.slug}-${campaign.id}`"
	/>

	<a
		v-else-if="campaign"
		:href="campaign.url || campaign.affiliate?.url"
		target="_blank"
		class="campaign"
		data-umami-event="campaign-click"
		:data-umami-event-campaign-id="`${campaign.entity.slug}-${campaign.id}`"
	>
		<img
			:src="getSource(campaign)"
			:width="campaign.banner.width"
			:height="campaign.banner.height"
			class="campaign-banner"
		>
	</a>
</template>

<script>
function ratioFilter(banner) {
	if (!banner) {
		return false;
	}

	if (this.minHeight && banner.height < this.minHeight) {
		return false;
	}

	if (this.maxHeight && banner.height > this.minHeight) {
		return false;
	}

	if (banner.type === 'html' && banner.width > window.innerWidth) {
		// usually non-scalable iframes
		return false;
	}

	if (this.minRatio && banner.ratio < this.minRatio) {
		return false;
	}

	if (this.maxRatio && banner.ratio > this.maxRatio) {
		return false;
	}

	return true;
}

function getSource(campaign) {
	if (campaign.banner.entity.type === 'network' || !campaign.banner.entity.parent) {
		return `/banners/${campaign.banner.entity.slug}/${campaign.banner.id}.${campaign.banner.type || 'jpg'}`;
	}

	if (campaign.banner.entity.type === 'channel' && campaign.banner.entity.parent?.type === 'network') {
		return `/banners/${campaign.banner.entity.parent.slug}/${campaign.banner.entity.slug}/${campaign.banner.id}.${campaign.banner.type || 'jpg'}`;
	}

	return null;
}

function entityCampaign() {
	const bannerCampaigns = this.entity.campaigns
		.concat(this.entity.children?.flatMap((child) => child.campaigns))
		.concat(this.entity.parent?.campaigns)
		.filter((campaignX) => campaignX && this.ratioFilter(campaignX.banner));

	if (bannerCampaigns.length > 0) {
		const randomCampaign = bannerCampaigns[Math.floor(Math.random() * bannerCampaigns.length)];

		this.campaign = randomCampaign;
		this.$emit('campaign', randomCampaign);

		return randomCampaign;
	}

	if (this.allowGeneric) {
		return this.genericCampaign();
	}

	this.$emit('campaign', null);

	return null;
}

function tagCampaign() {
	const campaignBanners = this.tag.banners.filter((banner) => banner.campaigns.length > 0 && this.ratioFilter(banner));
	const banner = campaignBanners[Math.floor(Math.random() * campaignBanners.length)];

	if (banner?.campaigns.length > 0) {
		const randomCampaign = {
			...banner.campaigns[Math.floor(Math.random() * banner.campaigns.length)],
			banner,
		};

		this.campaign = randomCampaign;
		this.$emit('campaign', randomCampaign);

		return randomCampaign;
	}

	if (this.allowGeneric) {
		return this.genericCampaign();
	}

	this.$emit('campaign', null);

	return null;
}

async function genericCampaign() {
	const randomCampaign = await this.$store.dispatch('fetchRandomCampaign', { minRatio: this.minRatio, maxRatio: this.maxRatio });

	this.campaign = randomCampaign;
	this.$emit('campaign', randomCampaign);

	return randomCampaign;
}

async function specificCampaign(campaignId) {
	const campaign = await this.$store.dispatch('fetchCampaign', campaignId);

	this.campaign = campaign;
	this.$emit('campaign', campaign);

	return campaign;
}

async function mounted() {
	if (this.$route.query.campaign) {
		await this.specificCampaign(this.$route.query.campaign);
		return;
	}

	if (this.entity) {
		await this.entityCampaign();
		return;
	}

	if (this.tag) {
		await this.tagCampaign();
		return;
	}

	await this.genericCampaign();
}

export default {
	props: {
		entity: {
			type: Object,
			default: null,
		},
		tag: {
			type: Object,
			default: null,
		},
		minHeight: {
			type: Number,
			default: null,
		},
		maxHeight: {
			type: Number,
			default: null,
		},
		minRatio: {
			type: Number,
			default: null,
		},
		allowGeneric: {
			type: Boolean,
			default: false,
		},
		maxRatio: {
			type: Number,
			default: null,
		},
	},
	emits: ['campaign'],
	data() {
		return {
			campaign: null,
		};
	},
	mounted,
	methods: {
		entityCampaign,
		genericCampaign,
		getSource,
		ratioFilter,
		specificCampaign,
		tagCampaign,
	},
};
</script>

<style lang="scss" scoped>
.campaign {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: none;
}

.campaign-banner {
	height: auto;
	width: auto;
	max-height: 100%;
	max-width: 100%;
}

.frame-container {
	position: relative;
	font-size: 0;
}

.frame-target {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
}
</style>