import { NgClass, NgStyle } from '@angular/common'
import { Component, inject } from '@angular/core'
import { RouterLink } from '@angular/router'
import { SessionInfo } from '@core/types'
import { DefaultService, TableResponse } from '@api-client/angular'
import { LoadingButtonDirective } from '@frontend/shared'
import { HotToastService } from '@ngxpert/hot-toast'
import { TranslocoDirective } from '@jsverse/transloco'
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'
import { finalize } from 'rxjs'
import { AuthService } from '../../../auth'
import { I18nService, TABLE_CONSTANTS } from '../../../core'
import { Coordinates, calculateRoomPlanCoordinates } from '../../../shared'
import { LucideChevronLeft, LucideUser, LucideX } from '@lucide/angular'

@UntilDestroy({ checkProperties: true })
@Component({
	selector: 'kadi-table-selection-settings',
	templateUrl: './table-selection-settings.component.html',
	styleUrls: ['./table-selection-settings.component.scss'],
	imports: [
		TranslocoDirective,
		RouterLink,
		NgStyle,
		NgClass,
		LoadingButtonDirective,
		LucideChevronLeft,
		LucideUser,
		LucideX,
	],
})
export class TableSelectionSettingsComponent {
	private readonly _toast = inject(HotToastService)
	private readonly _authService = inject(AuthService)
	private readonly _i18nService = inject(I18nService)
	private readonly _apiService = inject(DefaultService)

	tables: TableResponse[] = []
	subscribedTableIds: string[] = []
	coordinates: Coordinates | undefined
	user: SessionInfo
	loading = false

	POINT_LENGTH = TABLE_CONSTANTS.TABLE_POINT_LENGTH
	TableShape = TableResponse.ShapeEnum

	constructor() {
		this.user = this._authService.userData
		this.loadTables()
	}

	toggleTable(tableId: string): void {
		if (this.isTableSubscribed(tableId)) {
			this.removeSubscriber(tableId)
		} else {
			this.addSubscriber(tableId)
		}
	}

	selectAll(): void {
		for (const _table of this.tables) this.addSubscriber(_table.id)
	}

	selectNone(): void {
		for (const _table of this.tables) this.removeSubscriber(_table.id)
	}

	addSubscriber(tableId: string): void {
		this.subscribedTableIds.push(tableId)
	}

	removeSubscriber(tableId: string): void {
		const index = this.subscribedTableIds.indexOf(tableId)
		this.subscribedTableIds.splice(index, 1)
	}

	save(): void {
		this.loading = true
		this._apiService
			.roomPlanControllerSaveUserTableSubscriptions(this.user.id, this.subscribedTableIds)
			.pipe(
				untilDestroyed(this),
				finalize(() => (this.loading = false)),
				this._toast.observe({
					loading: this._i18nService.translate('update_table_selection_loading'),
					success: this._i18nService.translate('update_table_selection_success'),
					error: this._i18nService.translate('update_table_selection_error'),
				}),
			)
			.subscribe()
	}

	isTableSubscribed(tableId: string): boolean {
		return this.subscribedTableIds.includes(tableId)
	}

	private loadTables(): void {
		this._apiService
			.roomPlanControllerFindAllTables()
			.pipe(untilDestroyed(this))
			.subscribe({
				next: (tables) => {
					this.tables = tables
					this.subscribedTableIds = tables
						.filter((_table) => _table.subscribers?.includes(this.user.id))
						.map((_table) => _table.id)
					this.coordinates = calculateRoomPlanCoordinates(tables)
				},
			})
	}
}
