<script setup lang="ts">
	import { LogoSize } from '@/components/Logo/LogoSize'
	import { cnamLightTheme } from '@/designTokens/tokens/cnam/cnamLightTheme'
	import { computed } from 'vue'
	import type { RouteLocationRaw } from 'vue-router'
	import Logo from '../Logo/Logo.vue'
	import { dividerDimensionsMapping } from './dividerDimensionsMapping'
	import { locales as defaultLocales } from './locales'
	import { secondaryLogoMapping } from './secondaryLogoMapping'
	import type { Theme } from './types'
	import SyHeading from '@/components/SyHeading/SyHeading.vue'
	import { useLocales } from '@/composables/useLocales'
	import { useHomeLinkFallback } from '@/composables/useHomeLinkFallback'
	import type { DeepPartial } from '@/utils/locales/mergeLocales'

	const props = withDefaults(
		defineProps<{
			theme?: Theme
			serviceTitle?: string
			serviceSubTitle?: string
			mobileVersion?: boolean
			reduceLogo?: boolean
			homeLink?: {
				ariaLabel?: string
				to?: RouteLocationRaw
				href?: string
			}
			headingLevelTitle?: 1 | 2 | 3 | 4 | 5 | 6
			headingLevelSubtitle?: 1 | 2 | 3 | 4
			locales?: DeepPartial<typeof defaultLocales>
		}>(), {
			theme: 'default',
			serviceTitle: undefined,
			serviceSubTitle: undefined,
			mobileVersion: false,
			reduceLogo: false,
			headingLevelTitle: 1,
			headingLevelSubtitle: 2,
			homeLink: () => ({
				href: '/',
			}),
			locales: () => ({}),
		})

	const locales = useLocales(defaultLocales, () => props.locales)

	const slots = defineSlots<{
		'default'(): unknown
		'brand-content'(): unknown
	}>()

	const service = computed(() => {
		if (props.theme === 'compte-entreprise') {
			const { title, subTitle } = locales.value.compteEntreprise

			return {
				title,
				subTitle,
			}
		}

		return {
			title: props.serviceTitle || '',
			subTitle: props.serviceSubTitle || '',
		}
	})

	const mobileWithSecondaryLogo = computed(() => {
		return props.mobileVersion && hasSecondaryLogo.value
	})

	const height = computed(() => {
		if (mobileWithSecondaryLogo.value) {
			return '32px'
		}

		return props.mobileVersion ? '40px' : '64px'
	})

	const isRisquePro = computed(() => {
		return !props.reduceLogo && props.theme === 'risque-pro'
	})

	const isCompteEntreprise = computed(() => {
		return props.theme === 'compte-entreprise'
	})

	const isCompteAmeliMobile = computed(() => {
		return props.theme === 'compte-ameli' && props.mobileVersion
	})

	const hideSignature = computed(() => {
		return (
			props.reduceLogo
			|| isCompteEntreprise.value
			|| isCompteAmeliMobile.value
		)
	})

	const secondaryLogo = computed(() => {
		if (props.theme in secondaryLogoMapping) {
			return secondaryLogoMapping[props.theme as keyof typeof secondaryLogoMapping]
		}
		return null
	})

	const hasSecondaryLogo = computed(() => {
		return Boolean(secondaryLogo.value)
	})

	const hasSecondaryLogoLink = computed(() => {
		return (
			props.theme === 'ameli-pro'
			|| props.theme === 'ameli'
		)
	})

	const { containerComponent: logoContainerComponent, homeHref } = useHomeLinkFallback(() => props.homeLink)

	// Le libellé du lien d'accueil : sans `ariaLabel`, on n'annonce que le libellé générique
	// (une concaténation naïve produisait « undefined Retour vers accueil du site »).
	const homeLinkLabel = computed(() => {
		return [props.homeLink?.ariaLabel, locales.value.homeLinkLabel]
			.filter(Boolean)
			.join(' ')
	})

	const secondaryLogoCtnComponent = computed(() => {
		return hasSecondaryLogoLink.value
			? logoContainerComponent.value
			: 'div'
	})

	const secondaryLogoLabel = computed(() => {
		return hasSecondaryLogoLink.value && secondaryLogo.value
			? `${locales.value.homeLinkPrefix} ${secondaryLogo.value.alt}`
			: null
	})

	const avatar = computed(() => {
		return props.reduceLogo ? hasSecondaryLogo.value : false
	})

	const hasBrandSlot = computed(() => {
		return Boolean(slots['brand-content'])
	})

	const showBrandContent = computed(() => {
		return Boolean(
			service.value.title || service.value.subTitle || hasBrandSlot.value || hasSecondaryLogo.value,
		)
	})

	const showDivider = computed(() => {
		if (props.reduceLogo) {
			return false
		}

		return showBrandContent.value
	})

	const showServiceSubTitle = computed(() => {
		return Boolean(
			service.value.title && service.value.subTitle && !props.mobileVersion,
		)
	})

	const dividerColor = computed(() => {
		switch (props.theme) {
		case 'cnam':
		case 'ameli-pro':
			return cnamLightTheme.secondary
		case 'compte-entreprise':
			return cnamLightTheme.risquePro
		default:
			return cnamLightTheme.primary
		}
	})

	const dividerDimensions = computed(() => {
		if (props.mobileVersion) {
			return hasSecondaryLogo.value
				? dividerDimensionsMapping.xSmall
				: dividerDimensionsMapping.small
		}
		return dividerDimensionsMapping.normal
	})

	const logoSize = computed(() => {
		if (props.mobileVersion) {
			return hasSecondaryLogo.value
				? LogoSize.X_SMALL
				: LogoSize.SMALL
		}
		return LogoSize.NORMAL
	})
</script>

<template>
	<div
		:style="{ height: height }"
		class="vd-logo-brand-section d-flex flex-wrap"
	>
		<component
			:is="logoContainerComponent"
			:to="logoContainerComponent === 'router-link' ? homeLink?.to : undefined"
			:href="logoContainerComponent === 'a' ? homeHref : undefined"
			class="vd-home-link"
		>
			<Logo
				:hide-signature="hideSignature"
				:hide-organism="isCompteAmeliMobile"
				:risque-pro="isRisquePro"
				:aria-label="homeLinkLabel"
				:avatar="avatar"
				:size="logoSize"
				:class="{ 'mr-2': avatar }"
			/>
		</component>

		<slot>
			<svg
				v-if="showDivider"
				:width="dividerDimensions.width"
				:style="{ height: dividerDimensions.height }"
				:fill="dividerColor"
				focusable="false"
				aria-hidden="true"
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 22 64"
				class="vd-divider"
			>
				<path d="M14.3 49.3c-.2 0-.4-.2-.4-.4V14.2c0-.2.2-.4.4-.4.3 0 .5.2.5.4v34.7c0 .2-.2.4-.5.4Z" />
			</svg>

			<component
				:is="secondaryLogoCtnComponent"
				v-if="secondaryLogo"
				:aria-label="secondaryLogoLabel"
				:to="secondaryLogoCtnComponent === 'router-link' ? homeLink?.to : undefined"
				:href="secondaryLogoCtnComponent === 'a' ? homeHref : undefined"
				class="vd-home-link"
			>
				<img
					:src="secondaryLogo.src"
					:alt="secondaryLogo.alt"
				>
			</component>

			<div
				v-else-if="showBrandContent"
				class="vd-title-container d-flex justify-center flex-column text-primary"
			>
				<slot name="brand-content">
					<SyHeading
						v-if="service.title"
						:class="{
							'vd-compte-entreprise-title': isCompteEntreprise,
							'vd-title text-caption text-md-subtitle-1 font-weight-medium': headingLevelTitle === 1,
							'vd-title text-caption font-weight-medium': headingLevelTitle !== 1,
						}"
						:level="headingLevelTitle"
					>
						<template v-if="typeof service.title === 'string'">
							<span>
								{{ service.title }}
							</span>
						</template>

						<template v-else>
							<span>
								{{ service.title.text }}
							</span>
							<span>
								{{ service.title.highlight }}
							</span>
						</template>
					</SyHeading>

					<SyHeading
						v-if="showServiceSubTitle"
						class="vd-title text-caption"
						:level="headingLevelSubtitle"
					>
						{{ service.subTitle }}
					</SyHeading>
				</slot>
			</div>
		</slot>
	</div>
</template>

<style lang="scss" scoped>
.vd-logo-brand-section {
	.vd-title-container {
		overflow: hidden;
	}

	:deep(.vd-title) {
		line-height: 1.45 !important;
	}

	.vd-compte-entreprise-title {
		font-weight: 700 !important;

		span {
			color: rgb(var(--v-theme-risquePro));
		}
	}

	:deep(img) {
		width: auto;
		height: 100%;
		flex: none;
	}

	svg,
	.vd-home-link {
		flex: none;
	}

	// cursor: pointer uniquement quand le conteneur est interactif (a, router-link)
	a.vd-home-link,
	.vd-home-link[href] {
		cursor: pointer;
	}
}
</style>
