import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BaseFormComponent, getConfig, IqserPermissionsService, LanguageService, LoadingService, Toaster } from '@iqser/common-ui';
import { TenantsService } from '@iqser/common-ui/lib/tenants';
import { TranslateService } from '@ngx-translate/core';
import { AppConfig, IProfile } from '@red/domain';
import { languagesTranslations } from '@translations/languages-translations';
import { Roles } from '@users/roles';
import { UserPreferenceService } from '@users/user-preference.service';
import { UserService } from '@users/user.service';
import { firstValueFrom } from 'rxjs';
import { UserProfileDialogService } from '../services/user-profile-dialog.service';

@Component({
    templateUrl: './user-profile-screen.component.html',
    styleUrls: ['./user-profile-screen.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UserProfileScreenComponent extends BaseFormComponent implements OnInit {
    #profileModel: IProfile;
    readonly translations = languagesTranslations;
    readonly devMode = this._userPreferenceService.isIqserDevMode;
    readonly changePasswordUrl: string;

    constructor(
        domSanitizer: DomSanitizer,
        private readonly _userService: UserService,
        private readonly _loadingService: LoadingService,
        private readonly _dialogService: UserProfileDialogService,
        private readonly _formBuilder: UntypedFormBuilder,
        private readonly _languageService: LanguageService,
        protected readonly _translateService: TranslateService,
        private readonly _permissionsService: IqserPermissionsService,
        protected readonly _userPreferenceService: UserPreferenceService,
        private readonly _changeRef: ChangeDetectorRef,
        private readonly _toaster: Toaster,
    ) {
        super();
        this._loadingService.start();
        const tenant = inject(TenantsService).activeTenantId;
        const realmUrl = `${getConfig<AppConfig>().OAUTH_URL}/realms/${tenant}`;
        this.changePasswordUrl = `${realmUrl}/account/password`;
    }

    get languageChanged(): boolean {
        return this.#profileModel['language'] !== this.form.get('language').value;
    }

    get themeChanged(): boolean {
        return this.#profileModel['darkTheme'] !== this.form.get('darkTheme').value;
    }

    get emailChanged(): boolean {
        return this.#profileModel['email'] !== this.form.get('email').value;
    }

    get profileChanged(): boolean {
        const keys = Object.keys(this.form.getRawValue());
        keys.splice(keys.indexOf('language'), 1);
        keys.splice(keys.indexOf('darkTheme'), 1);

        for (const key of keys) {
            if (this.#profileModel[key] !== this.form.get(key).value) {
                return true;
            }
        }

        return false;
    }

    get languages(): string[] {
        return this._translateService.langs;
    }

    ngOnInit() {
        this._initializeForm();
    }

    async save(): Promise<void> {
        try {
            if (this.profileChanged) {
                const value = this.form.getRawValue() as IProfile;

                if (this.emailChanged) {
                    const dialogRef = this._dialogService.openDialog('confirmPassword');
                    const password = await firstValueFrom(dialogRef.afterClosed());
                    if (!password) {
                        return;
                    }
                    value['password'] = password;
                }

                this._loadingService.start();
                await firstValueFrom(this._userService.updateMyProfile(value));

                await this._userService.loadCurrentUser();
                await firstValueFrom(this._userService.loadAll());
            }

            if (this.languageChanged) {
                await this._languageService.change(this.form.get('language').value);
            }

            if (this.themeChanged) {
                await this._userPreferenceService.saveTheme(this.form.get('darkTheme').value ? 'dark' : 'light');
            }

            this._initializeForm();

            this._toaster.success(_('user-profile-screen.update.success'));
        } catch (e) {
            this._loadingService.stop();
        }
    }

    private _getForm(): UntypedFormGroup {
        return this._formBuilder.group({
            email: ['', [Validators.required, Validators.email]],
            firstName: [''],
            lastName: [''],
            language: [''],
            darkTheme: [false],
        });
    }

    private _initializeForm(): void {
        try {
            this.form = this._getForm();
            if (!this._permissionsService.has(Roles.updateMyProfile)) {
                this.form.disable();
            }
            this.#profileModel = {
                email: this._userService.currentUser.email ?? '',
                firstName: this._userService.currentUser.firstName ?? '',
                lastName: this._userService.currentUser.lastName ?? '',
                language: this._languageService.currentLanguage ?? '',
                darkTheme: this._userPreferenceService.getTheme() === 'dark',
            };
            this.form.patchValue(this.#profileModel, { emitEvent: false });
            this.initialFormValue = this.form.getRawValue();
        } catch (e) {
        } finally {
            this._loadingService.stop();
            this._changeRef.markForCheck();
        }
    }
}
