import { Component, inject } from '@angular/core'
import { NonNullableFormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'
import { RouterLink } from '@angular/router'
import { DefaultService, UserResponse } from '@api-client/angular'
import { LoadingButtonDirective } from '@frontend/shared'
import { DialogService } from '@ngneat/dialog'
import { HotToastService } from '@ngxpert/hot-toast'
import { TranslocoDirective } from '@jsverse/transloco'
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'
import { Observable, filter, finalize, map, switchMap } from 'rxjs'
import { AuthService } from '../../../auth'
import { I18nService } from '../../../core'
import { CurrentPasswordModalComponent } from '../../../shared'
import { LucideChevronLeft } from '@lucide/angular'

@UntilDestroy({ checkProperties: true })
@Component({
	selector: 'kadi-account-settings',
	templateUrl: './account-settings.component.html',
	imports: [TranslocoDirective, RouterLink, ReactiveFormsModule, LoadingButtonDirective, LucideChevronLeft],
})
export class AccountSettingsComponent {
	private readonly _toast = inject(HotToastService)
	private readonly _apiService = inject(DefaultService)
	private readonly _authService = inject(AuthService)
	private readonly _i18nService = inject(I18nService)
	private readonly _formBuilder = inject(NonNullableFormBuilder)
	private readonly _dialogService = inject(DialogService)

	user: UserResponse | undefined
	loading = false

	nameForm = this._formBuilder.group({
		firstName: this._formBuilder.control('', [Validators.required, Validators.minLength(2)]),
		lastName: this._formBuilder.control('', [Validators.required, Validators.minLength(2)]),
	})

	passwordForm = this._formBuilder.group({
		password: this._formBuilder.control(''),
	})

	constructor() {
		this.loadUser(this._authService.userData.id)
	}

	savePassword(): void {
		if (this.passwordForm.invalid) return

		this.loading = true
		const formValue = this.passwordForm.getRawValue()

		this.requestCurrentPassword(this._i18nService.translate('Password'))
			.pipe(
				filter((password) => !!password),
				switchMap((currentPassword) => this.updatePassword(currentPassword as string, formValue.password)),
			)
			.pipe(
				untilDestroyed(this),
				finalize(() => (this.loading = false)),
			)
			.subscribe({
				next: () => {
					this._toast.success(this._i18nService.translate('Password has been updated'))
					this.passwordForm.reset()
					this.passwordForm.markAsPristine()
				},
				error: () => this._toast.error(this._i18nService.translate('update_user_error')),
			})
	}

	saveName(): void {
		if (this.nameForm.invalid) return

		this.loading = true
		const formValue = this.nameForm.getRawValue()

		this._apiService
			.userControllerUpdateById(this.user?.id as string, {
				id: this.user?.id as string,
				firstName: formValue.firstName,
				lastName: formValue.lastName,
			})
			.pipe(
				untilDestroyed(this),
				finalize(() => (this.loading = false)),
				switchMap(() => this._authService.loadUser()),
			)
			.subscribe({
				next: () => {
					this._toast.success(this._i18nService.translate('Name has been updated'))
					this.nameForm.markAsPristine()
				},
				error: (e) => this._toast.error(e.message),
			})
	}

	private updatePassword(currentPassword: string, newPassword: string): Observable<void> {
		return this._authService.updatePassword(currentPassword, newPassword)
	}

	private requestCurrentPassword(title: string): Observable<string | undefined> {
		const dialogRef = this._dialogService.open(CurrentPasswordModalComponent, {
			data: {
				title: this._i18nService.translate('enter_password_notice', { title }),
			},
		})
		return dialogRef.afterClosed$.pipe(map((value) => (value ? (value as string) : undefined)))
	}

	private loadUser(id: string): void {
		this._apiService
			.userControllerFindById(id)
			.pipe(untilDestroyed(this))
			.subscribe({
				next: (user) => {
					this.user = user
					this.nameForm.patchValue(user)
				},
			})
	}
}
