import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { NotificationPreferencesService } from '../../../services/notification-preferences.service';
import { BaseFormComponent, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
    NotificationCategoriesValues,
    NotificationGroupsKeys,
    NotificationGroupsValues,
    SkipSimpleUserNotifications,
    User,
} from '@red/domain';
import { firstValueFrom } from 'rxjs';
import { notificationsSettingsTranslations } from '@translations/notifications-settings-translations';
import { getCurrentUser } from '@iqser/common-ui/lib/users';

@Component({
    templateUrl: './notifications-screen.component.html',
    styleUrls: ['./notifications-screen.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NotificationsScreenComponent extends BaseFormComponent implements OnInit {
    readonly notificationCategories = NotificationCategoriesValues;
    readonly notificationGroupsKeys = NotificationGroupsKeys;
    readonly notificationGroupsValues = NotificationGroupsValues;
    readonly translations = notificationsSettingsTranslations;
    readonly currentUser = getCurrentUser<User>();

    constructor(
        private readonly _toaster: Toaster,
        private readonly _formBuilder: UntypedFormBuilder,
        private readonly _loadingService: LoadingService,
        private readonly _notificationPreferencesService: NotificationPreferencesService,
        private readonly _changeRef: ChangeDetectorRef,
    ) {
        super();
    }

    async ngOnInit(): Promise<void> {
        await this._initializeForm();
    }

    isCategoryActive(category: string) {
        return this.form.get(`${category}Enabled`).value;
    }

    isPreferenceChecked(category: string, preference: string) {
        return this.form.get(category).value.includes(preference);
    }

    addRemovePreference(checked: boolean, category: string, preference: string) {
        let preferences: string[] = this.form.get(category).value;

        if (checked) {
            preferences.push(preference);
        } else {
            preferences = preferences.filter(p => p !== preference);
        }

        const unique = Array.from(new Set(preferences));
        this.form.get(category).setValue(unique);
    }

    skipPreference(preference): boolean {
        return !this.currentUser.isManager && SkipSimpleUserNotifications.includes(preference);
    }

    async save() {
        this._loadingService.start();
        try {
            await firstValueFrom(this._notificationPreferencesService.update(this.form.value));
        } catch (e) {
            this._toaster.error(_('notifications-screen.error.generic'));
        }
        this.initialFormValue = JSON.parse(JSON.stringify(this.form.getRawValue()));
        this._changeRef.markForCheck();
        this._loadingService.stop();
    }

    private _getForm(): UntypedFormGroup {
        return this._formBuilder.group({
            inAppNotificationsEnabled: [undefined],
            emailNotificationsEnabled: [undefined],
            emailNotificationType: [undefined],
            emailNotifications: [undefined],
            inAppNotifications: [undefined],
        });
    }

    private async _initializeForm() {
        this._loadingService.start();

        this.form = this._getForm();
        const notificationPreferences = await firstValueFrom(this._notificationPreferencesService.get());
        this.form.patchValue(notificationPreferences);
        this.initialFormValue = JSON.parse(JSON.stringify(this.form.getRawValue()));

        this._loadingService.stop();
    }
}
