import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed } from '@angular/core';
import { FormGroup, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
    BaseFormComponent,
    IconButtonComponent,
    IqserPermissionsService,
    LanguageService,
    LoadingService,
    Toaster,
} from '@iqser/common-ui';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { 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';
import { NgForOf, NgIf } from '@angular/common';
import { MatFormField } from '@angular/material/form-field';
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
import { MatSlideToggle } from '@angular/material/slide-toggle';
import { PdfViewer } from '../../../../pdf-viewer/services/pdf-viewer.service';
import { formControlToSignal } from '@utils/functions';
import { AsControl } from '@common-ui/utils';

interface UserProfileForm {
    email: string;
    firstName: string;
    lastName: string;
    language: string;
    darkTheme: boolean;
}

@Component({
    templateUrl: './user-profile-screen.component.html',
    styleUrls: ['./user-profile-screen.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    standalone: true,
    imports: [
        ReactiveFormsModule,
        NgIf,
        MatFormField,
        MatSelect,
        MatOption,
        NgForOf,
        TranslateModule,
        MatSlideToggle,
        IconButtonComponent,
        MatSelectTrigger,
    ],
})
export class UserProfileScreenComponent extends BaseFormComponent {
    readonly form: FormGroup<AsControl<UserProfileForm>> = this.#getForm();
    initialFormValue = this.form.getRawValue();
    readonly translations = languagesTranslations;
    readonly devMode = this._userPreferenceService.isIqserDevMode;

    readonly profileKeys = ['email', 'firstName', 'lastName'];
    readonly languages = this._translateService.langs;
    readonly language = formControlToSignal<UserProfileForm['language']>(this.form.controls.language);
    readonly languageSelectLabel = computed(() => this.translations[this.language()]);

    constructor(
        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,
        private readonly _pdfViewer: PdfViewer,
    ) {
        super();
        if (!this._permissionsService.has(Roles.updateMyProfile)) {
            this.form.disable();
        }
        this._loadingService.stop();
    }

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

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

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

    get profileChanged(): boolean {
        return this.profileKeys.some(key => this.initialFormValue[key] !== this.form.get(key).value);
    }

    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.controls.language.value);
                await this._pdfViewer.instance?.UI.setLanguage(this._languageService.currentLanguage);
            }

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

            this.initialFormValue = this.form.getRawValue();
            this._changeRef.markForCheck();
            this._loadingService.stop();
            this._toaster.success(_('user-profile-screen.update.success'));
        } catch (e) {
            this._loadingService.stop();
        }
    }

    async resetPassword() {
        await this._userService.createResetPasswordAction();
    }

    #getForm() {
        return this._formBuilder.group({
            email: [this._userService.currentUser.email ?? '', [Validators.required, Validators.email]],
            firstName: [this._userService.currentUser.firstName ?? ''],
            lastName: [this._userService.currentUser.lastName ?? ''],
            language: [this._userPreferenceService.getLanguage()],
            darkTheme: [this._userPreferenceService.getTheme() === 'dark'],
        });
    }
}
