import {
	ConnectionPositionPair,
	FlexibleConnectedPositionStrategy,
	GlobalPositionStrategy,
	Overlay,
	OverlayRef,
} from '@angular/cdk/overlay'
import { ComponentPortal } from '@angular/cdk/portal'
import { ElementRef, Injectable, Injector, inject } from '@angular/core'
import { ReservationResponse } from '@api-client/angular'
import { AddReservationComponent } from './add-reservation.component'
import { RESERVATION_MODAL_DATA } from './tokens'

type Options = { origin?: ElementRef }

@Injectable({
	providedIn: 'root',
})
export class AddReservationService {
	private readonly _overlay = inject(Overlay)

	add(options: Options): void {
		this.openModal(options)
	}

	edit(reservation: ReservationResponse, options?: Options) {
		this.openModal(options ?? {}, reservation)
	}

	private openModal(options: Options, reservation?: ReservationResponse) {
		const position = options.origin
			? this.createConnectedPositionStrategy(options.origin)
			: this.createGlobalPositionStrategy()

		const overlayRef = this._overlay.create({
			positionStrategy: position,
			hasBackdrop: true,
			panelClass: 'add-reservation-panel',
			maxHeight: '95vh',
		})
		const injector = this.createInjector(overlayRef, reservation)
		const portal = new ComponentPortal(AddReservationComponent, null, injector)
		overlayRef.attach(portal)
		overlayRef.backdropClick().subscribe(() => {
			overlayRef.detach()
			overlayRef.dispose()
		})
	}

	private createConnectedPositionStrategy(origin: ElementRef): FlexibleConnectedPositionStrategy {
		return this._overlay
			.position()
			.flexibleConnectedTo(origin)
			.withPositions([
				new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'top' }),
			])
	}

	private createGlobalPositionStrategy(): GlobalPositionStrategy {
		return this._overlay.position().global().centerHorizontally().centerVertically('20px')
	}

	private createInjector(overlayRef: OverlayRef, reservation?: ReservationResponse): Injector {
		return Injector.create({
			providers: [{ provide: RESERVATION_MODAL_DATA, useValue: { overlayRef, reservation } }],
		})
	}
}
