import { Component, inject, OnInit } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
    ButtonConfig,
    IconButtonTypes,
    ListingComponent,
    listingProvidersFactory,
    LoadingService,
    SearchPositions,
    TableColumnConfig,
} from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui/lib/filtering';
import { TranslateService } from '@ngx-translate/core';
import { DonutChartConfig, User, UserTypes } from '@red/domain';
import { RouterHistoryService } from '@services/router-history.service';
import { TranslateChartService } from '@services/translate-chart.service';
import { rolesTranslations } from '@translations/roles-translations';
import { Roles } from '@users/roles';
import { UserService } from '@users/user.service';
import { firstValueFrom, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { userTypeChecker, userTypeFilters } from '../../../../utils';
import { AdminDialogService } from '../../services/admin-dialog.service';

function configToFilter({ key, label }: DonutChartConfig) {
    return new NestedFilter({
        id: key,
        label,
    });
}

@Component({
    templateUrl: './user-listing-screen.component.html',
    styleUrls: ['./user-listing-screen.component.scss'],
    providers: listingProvidersFactory<User>({
        entitiesService: UserService,
        component: UserListingScreenComponent,
    }),
})
export class UserListingScreenComponent extends ListingComponent<User> implements OnInit {
    readonly routerHistoryService = inject(RouterHistoryService);
    readonly searchPositions = SearchPositions;
    readonly translations = rolesTranslations;
    readonly roles = Roles;
    readonly currentUser = this._userService.currentUser;
    readonly canDeleteSelected$ = this.#canDeleteSelected$;
    readonly tableHeaderLabel = _('user-listing.table-header.title');
    readonly tableColumnConfigs: TableColumnConfig<User>[] = [
        { label: _('user-listing.table-col-names.name'), width: '2fr' },
        { label: _('user-listing.table-col-names.email') },
        { label: _('user-listing.table-col-names.active'), class: 'flex-center' },
        { label: _('user-listing.table-col-names.roles') },
    ];
    readonly buttonConfigs: readonly ButtonConfig[] = [
        {
            label: _('user-listing.add-new'),
            action: (): void => this.openAddEditUserDialog(),
            type: IconButtonTypes.primary,
            icon: 'iqser:plus',
            disabled$: this._userService.currentUser$.pipe(map(user => !user.isAdmin)),
            helpModeKey: 'create_user',
        },
    ];
    collapsedDetails = false;
    chartConfig: DonutChartConfig[] = [];

    constructor(
        private readonly _userService: UserService,
        private readonly _loadingService: LoadingService,
        private readonly _dialogService: AdminDialogService,
        private readonly _translateService: TranslateService,
        private readonly _translateChartService: TranslateChartService,
    ) {
        super();
    }

    get #canDeleteSelected$(): Observable<boolean> {
        const entities$ = this.listingService.selectedEntities$;
        return entities$.pipe(map(all => !all.find(u => u.id === this.currentUser.id)));
    }

    canDeactivate(user: User): boolean {
        return !((this.currentUser.isUserAdmin && !this.currentUser.isAdmin && user.isAdmin) || this.currentUser.id === user.id);
    }

    async ngOnInit() {
        await this.#loadData();
    }

    openAddEditUserDialog(user?: User) {
        this._dialogService.openDialog('addEditUser', user, async () => {
            await this.#loadData();
        });
    }

    openDeleteUsersDialog(userIds: string[]) {
        this._dialogService.deleteUsers(userIds, async () => {
            await this.#loadData();
        });
    }

    getDisplayRoles(user: User) {
        const oldRedRoles = user.roles.filter(role => role.startsWith('RED_'));
        const translatedRoles = oldRedRoles.map(role => this._translateService.instant(this.translations[role]));
        return translatedRoles.join(', ') || this._translateService.instant(this.translations['NO_ROLE']);
    }

    async toggleActive(user: User) {
        this._loadingService.start();
        await firstValueFrom(this._userService.toggleStatus(user));
        await this.#loadData();
    }

    bulkDelete() {
        this.openDeleteUsersDialog(this.listingService.selectedIds as string[]);
    }

    deleteDisabled(user: User): boolean {
        const userAdmin = user.roles.includes('RED_ADMIN');
        const currentUserAdmin = this._userService.currentUser.roles.includes('RED_ADMIN');
        return user.id === this._userService.currentUser.id || (userAdmin && !currentUserAdmin);
    }

    async #loadData() {
        await firstValueFrom(this._userService.loadAll());
        this.#computeStats();
        this._loadingService.stop();
    }

    #computeStats() {
        this.chartConfig = this._translateChartService.translateRoles(
            UserTypes.map(type => ({
                value: this.allEntities.filter(userTypeFilters[type]).length,
                color: type.replace('RED_', ''),
                label: type,
                key: type,
            })).filter(type => type.value > 0),
        );

        this.#computeAllFilters();
    }

    #computeAllFilters() {
        const roleFiltersGroup = {
            slug: 'roleFilters',
            filters: this.chartConfig.map(configToFilter),
            checker: userTypeChecker,
        };
        this.filterService.addFilterGroups([roleFiltersGroup]);
    }
}
