import { Component, ViewEncapsulation, inject } from '@angular/core'
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'
import { filter, skip } from 'rxjs'
import { FuseMediaWatcherService } from '../shared'
import { Layout } from './layout.types'
import { EmptyLayoutComponent } from './layouts/empty/empty.component'
import { ClassicLayoutComponent } from './layouts/classic/classic.component'
import { CompactLayoutComponent } from './layouts/compact/compact.component'

@UntilDestroy({ checkProperties: true })
@Component({
	selector: 'kadi-layout',
	templateUrl: './layout.component.html',
	styleUrls: ['./layout.component.scss'],
	encapsulation: ViewEncapsulation.None,
	imports: [EmptyLayoutComponent, ClassicLayoutComponent, CompactLayoutComponent],
})
export class LayoutComponent {
	private readonly _activatedRoute = inject(ActivatedRoute)
	private readonly _router = inject(Router)
	private readonly _fuseMediaWatcherService = inject(FuseMediaWatcherService)

	layout: Layout = 'empty'

	constructor() {
		this._updateLayout()

		this._router.events
			.pipe(
				filter((event) => event instanceof NavigationEnd),
				untilDestroyed(this),
			)
			.subscribe(() => this._updateLayout())

		this._fuseMediaWatcherService.onMediaChange$
			.pipe(untilDestroyed(this), skip(1))
			.subscribe(({ matchingAliases }) => {
				const isTabletSize = matchingAliases.includes('md') && !matchingAliases.includes('xl')
				const layout: Layout = isTabletSize ? 'compact' : 'classic'
				this._updateLayout(layout)
			})
	}

	private _updateLayout(layout?: Layout): void {
		if (layout) {
			this.layout = layout
			return
		}

		let route = this._activatedRoute
		while (route.firstChild) {
			route = route.firstChild
		}

		// 1. Get the query parameter from the current route and set the layout
		if (route.snapshot) {
			const layoutFromQueryParam = route.snapshot.queryParamMap.get('layout') as Layout
			if (layoutFromQueryParam) {
				this.layout = layoutFromQueryParam
			}
		}

		// 2. Iterate through the paths and change the layout as we find
		// a config for it.
		//
		// The reason we do this is that there might be empty grouping
		// paths or componentless routes along the path. Because of that,
		// we cannot just assume that the layout configuration will be
		// in the last path's config or in the first path's config.
		//
		// So, we get all the paths that matched starting from root all
		// the way to the current activated route, walk through them one
		// by one and change the layout as we find the layout config. This
		// way, layout configuration can live anywhere within the path and
		// we won't miss it.
		//
		// Also, this will allow overriding the layout in any time so we
		// can have different layouts for different routes.
		const paths = route.pathFromRoot
		for (const path of paths) {
			if (path.routeConfig && path.routeConfig.data && path.routeConfig.data['layout']) {
				this.layout = path.routeConfig.data['layout']
			}
		}
	}
}
