import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { BaseFormComponent, getConfig, IqserPermissionsService, isIqserDevMode, LoadingService } from '@iqser/common-ui';
import { AsControl } from '@iqser/common-ui/lib/utils';
import { Roles } from '@users/roles';
import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.service';

interface PreferencesForm {
    // preferences
    autoExpandFiltersOnActions: boolean;
    openScmDialogByDefault: boolean;
    tableExtractionType: string;
    // warnings preferences
    loadAllAnnotationsWarning: boolean;

    [k: string]: any;
}

type Screen = 'preferences' | 'warnings-preferences';

const Screens = {
    PREFERENCES: 'preferences',
    WARNING_PREFERENCES: 'warnings-preferences',
} as const;

@Component({
    selector: 'redaction-preferences',
    templateUrl: './preferences.component.html',
    styleUrls: ['./preferences.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PreferencesComponent extends BaseFormComponent implements OnInit {
    readonly form: FormGroup<AsControl<PreferencesForm>>;
    readonly currentScreen: Screen;
    readonly screens = Screens;
    initialFormValue: PreferencesForm;
    readonly roles = Roles;
    readonly config = getConfig();
    readonly isIqserDevMode = isIqserDevMode();

    constructor(
        route: ActivatedRoute,
        readonly userPreferenceService: UserPreferenceService,
        private readonly _formBuilder: FormBuilder,
        private readonly _permissionsService: IqserPermissionsService,
        private readonly _changeRef: ChangeDetectorRef,
        private readonly _loadingService: LoadingService,
    ) {
        super();
        this.form = this._formBuilder.group({
            // preferences
            autoExpandFiltersOnActions: [this.userPreferenceService.getAutoExpandFiltersOnActions()],
            openScmDialogByDefault: [this.userPreferenceService.getOpenScmDialogByDefault()],
            tableExtractionType: [this.userPreferenceService.getTableExtractionType()],
            // warnings preferences
            loadAllAnnotationsWarning: [this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
        });

        if (!this._permissionsService.has(Roles.managePreferences)) {
            this.form.disable();
        }

        if (!this._permissionsService.has(Roles.getTables)) {
            this.form.controls.tableExtractionType.disable();
        }

        this.initialFormValue = this.form.getRawValue();
        this.currentScreen = route.snapshot.data.screen;
    }

    ngOnInit() {
        this._loadingService.stop();
    }

    async save(): Promise<any> {
        if (this.form.controls.autoExpandFiltersOnActions.value !== this.userPreferenceService.getAutoExpandFiltersOnActions()) {
            await this.userPreferenceService.toggleAutoExpandFiltersOnActions();
        }
        if (this.form.controls.openScmDialogByDefault.value !== this.userPreferenceService.getOpenScmDialogByDefault()) {
            await this.userPreferenceService.toggleOpenScmDialogByDefault();
        }

        if (this.form.controls.tableExtractionType.value !== this.userPreferenceService.getTableExtractionType()) {
            await this.userPreferenceService.save(PreferencesKeys.tableExtractionType, this.form.controls.tableExtractionType.value);
        }

        if (
            this.form.controls.loadAllAnnotationsWarning.value !==
            this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)
        ) {
            await this.userPreferenceService.save(
                PreferencesKeys.loadAllAnnotationsWarning,
                String(this.form.controls.loadAllAnnotationsWarning.value),
            );
        }

        await this.userPreferenceService.reload();
        this.#patchValues();

        this.initialFormValue = this.form.getRawValue();
        this._changeRef.markForCheck();
    }

    #patchValues() {
        this.form.patchValue({
            autoExpandFiltersOnActions: this.userPreferenceService.getAutoExpandFiltersOnActions(),
            openScmDialogByDefault: this.userPreferenceService.getOpenScmDialogByDefault(),
            tableExtractionType: this.userPreferenceService.getTableExtractionType(),
            loadAllAnnotationsWarning: this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),
        });
    }
}
