import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms';
import { NotificationPreferencesService } from '../../../services/notification-preferences.service';
import { BaseFormComponent, getConfig, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
    DocumentNotificationsTypes,
    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';

const RSS_EXCLUDED_SETTINGS = ['USER_PROMOTED_TO_APPROVER', 'USER_DEGRADED_TO_REVIEWER', 'ASSIGN_REVIEWER'];

@Component({
    templateUrl: './notifications-screen.component.html',
    styleUrls: ['./notifications-screen.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NotificationsScreenComponent extends BaseFormComponent implements OnInit {
    readonly #toaster = inject(Toaster);
    readonly #formBuilder = inject(UntypedFormBuilder);
    readonly #loadingService = inject(LoadingService);
    readonly #notificationPreferencesService = inject(NotificationPreferencesService);
    readonly #cdRef = inject(ChangeDetectorRef);
    readonly #config = getConfig();
    readonly notificationCategories = NotificationCategoriesValues;
    readonly notificationGroupsKeys = NotificationGroupsKeys;
    readonly notificationGroupsValues = NotificationGroupsValues;
    readonly translations = notificationsSettingsTranslations;
    readonly currentUser = getCurrentUser<User>();

    constructor() {
        super();
    }

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

    getRssFilteredSettings(settings: string[]) {
        if (this.#config.IS_DOCUMINE) {
            return settings.filter(s => !RSS_EXCLUDED_SETTINGS.includes(s));
        }
        return settings;
    }

    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 {
            const preferences = this.#filterNotificationPreferences();
            await firstValueFrom(this.#notificationPreferencesService.update(preferences));
        } catch (e) {
            this.#toaster.error(_('notifications-screen.error.generic'));
        }
        this.initialFormValue = JSON.parse(JSON.stringify(this.form.getRawValue()));
        this.#cdRef.markForCheck();
        this.#loadingService.stop();
    }

    #getForm() {
        return this.#formBuilder.group({
            inAppNotificationsEnabled: [undefined],
            emailNotificationsEnabled: [undefined],
            emailNotificationType: [undefined],
            emailNotifications: [undefined],
            inAppNotifications: [undefined],
        });
    }

    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();
    }

    #filterNotificationPreferences() {
        if (!this.#config.IS_DOCUMINE) {
            return this.form.value;
        }

        if (!this.isPreferenceChecked('inAppNotifications', DocumentNotificationsTypes.assignApprover)) {
            return {
                ...this.form.value,
                inAppNotifications: this.form
                    .get('inAppNotifications')
                    .value.filter((preference: string) => !RSS_EXCLUDED_SETTINGS.includes(preference)),
            };
        }
        if (!this.form.get('inAppNotifications').value.includes(DocumentNotificationsTypes.assignReviewer)) {
            return {
                ...this.form.value,
                inAppNotifications: [...this.form.get('inAppNotifications').value, DocumentNotificationsTypes.assignReviewer],
            };
        }

        return this.form.value;
    }
}
