import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import {
    BaseFormComponent,
    getConfig,
    IconButtonComponent,
    IqserAllowDirective,
    IqserPermissionsService,
    isIqserDevMode,
    KEYS,
    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';
import { DialogDefaultsComponent } from './dialog-defaults/dialog-defaults.component';
import { NgClass, NgIf } from '@angular/common';
import { MatSlideToggle } from '@angular/material/slide-toggle';
import { TranslateModule } from '@ngx-translate/core';
import { MatCheckbox } from '@angular/material/checkbox';

interface PreferencesForm {
    // preferences
    autoExpandFiltersOnActions: boolean;
    tableExtractionType: string;
    // warnings preferences
    loadAllAnnotationsWarning: boolean;
    helpModeDialog: boolean;
    overwriteFileOption: 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,
    standalone: true,
    imports: [
        DialogDefaultsComponent,
        NgClass,
        NgIf,
        ReactiveFormsModule,
        MatSlideToggle,
        TranslateModule,
        IqserAllowDirective,
        MatCheckbox,
        IconButtonComponent,
    ],
})
export class PreferencesComponent extends BaseFormComponent implements OnInit {
    readonly #formBuilder = inject(FormBuilder);
    readonly #permissionsService = inject(IqserPermissionsService);
    readonly #changeRef = inject(ChangeDetectorRef);
    readonly #loadingService = inject(LoadingService);
    readonly #userPreferenceService = inject(UserPreferenceService);

    readonly form: FormGroup<AsControl<PreferencesForm>>;
    readonly currentScreen: Screen;
    readonly screens = Screens;
    initialFormValue: PreferencesForm;
    readonly roles = Roles;
    readonly config = getConfig();
    readonly isIqserDevMode = isIqserDevMode();

    get #isOverwriteFileOptionActive() {
        return !(this.#userPreferenceService.getOverwriteFileOption() === 'undefined');
    }

    constructor(route: ActivatedRoute) {
        super();
        this.form = this.#formBuilder.group({
            // preferences
            autoExpandFiltersOnActions: [this.#userPreferenceService.getAutoExpandFiltersOnActions()],
            tableExtractionType: [this.#userPreferenceService.getTableExtractionType()],
            // warnings preferences
            loadAllAnnotationsWarning: [this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
            helpModeDialog: [this.#userPreferenceService.getBool(KEYS.helpModeDialog)],
            overwriteFileOption: [this.#isOverwriteFileOptionActive],
        });

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

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

        if (!this.#isOverwriteFileOptionActive) {
            this.form.controls.overwriteFileOption.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.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),
            );
        }

        if (this.form.controls.helpModeDialog.value !== this.#userPreferenceService.getBool(KEYS.helpModeDialog)) {
            await this.#userPreferenceService.save(KEYS.helpModeDialog, String(this.form.controls.helpModeDialog.value));
        }

        if (this.form.controls.overwriteFileOption.enabled && !this.form.controls.overwriteFileOption.value) {
            await this.#userPreferenceService.saveOverwriteFileOption('undefined');
        }

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

        this.initialFormValue = this.form.getRawValue();
        this.#changeRef.markForCheck();
    }

    #patchValues() {
        this.form.patchValue({
            autoExpandFiltersOnActions: this.#userPreferenceService.getAutoExpandFiltersOnActions(),
            tableExtractionType: this.#userPreferenceService.getTableExtractionType(),
            loadAllAnnotationsWarning: this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),
            helpModeDialog: this.#userPreferenceService.getBool(KEYS.helpModeDialog),
            overwriteFileOption: this.#isOverwriteFileOptionActive,
        });

        if (!this.#isOverwriteFileOptionActive) {
            this.form.controls.overwriteFileOption.disable();
        }
    }
}
