import { Injectable, TemplateRef } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AddEntityDialogComponent } from '../dialogs/add-entity-dialog/add-entity-dialog.component';
import { AddEditCloneDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component';
import { EditColorDialogComponent } from '../dialogs/edit-color-dialog/edit-color-dialog.component';
import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component';
import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component';
import {
    ConfirmationDialogComponent,
    ConfirmOptions,
    DialogConfig,
    DialogService,
    IConfirmationDialogData,
    LoadingService,
    TitleColors,
} from '@iqser/common-ui';
import { UploadDictionaryDialogComponent } from '../dialogs/upload-dictionary-dialog/upload-dictionary-dialog.component';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { firstValueFrom, forkJoin } from 'rxjs';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { UserService } from '@users/user.service';
import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '@red/domain';
import { ReportTemplateService } from '@services/report-template.service';
import { ConfigureCertificateDialogComponent } from '../dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
import { AuditInfoDialogComponent } from '../dialogs/audit-info-dialog/audit-info-dialog.component';

type DialogType =
    | 'confirm'
    | 'addEntity'
    | 'editColor'
    | 'addEditUser'
    | 'smtpAuthConfig'
    | 'addEditCloneDossierTemplate'
    | 'auditInfo'
    | 'uploadDictionary'
    | 'configureCertificate';

@Injectable()
export class AdminDialogService extends DialogService<DialogType> {
    protected readonly _config: DialogConfig<DialogType> = {
        confirm: {
            component: ConfirmationDialogComponent,
            dialogConfig: { disableClose: false },
        },
        addEntity: {
            component: AddEntityDialogComponent,
            dialogConfig: { autoFocus: true },
        },
        editColor: {
            component: EditColorDialogComponent,
            dialogConfig: { autoFocus: true },
        },
        addEditUser: {
            component: AddEditUserDialogComponent,
            dialogConfig: { autoFocus: true },
        },
        smtpAuthConfig: {
            component: SmtpAuthDialogComponent,
            dialogConfig: { autoFocus: true },
        },
        addEditCloneDossierTemplate: {
            component: AddEditCloneDossierTemplateDialogComponent,
            dialogConfig: { width: '950px', autoFocus: true },
        },
        uploadDictionary: {
            component: UploadDictionaryDialogComponent,
        },
        configureCertificate: {
            component: ConfigureCertificateDialogComponent,
            dialogConfig: { disableClose: false, maxHeight: '100vh' },
        },
        auditInfo: {
            component: AuditInfoDialogComponent,
        },
    };

    constructor(
        protected readonly _dialog: MatDialog,
        private readonly _activeDossiersService: ActiveDossiersService,
        private readonly _loadingService: LoadingService,
        private readonly _userService: UserService,
        private readonly _reportTemplateService: ReportTemplateService,
    ) {
        super(_dialog);
    }

    deleteUsers(userIds: string[], cb?: () => Promise<void> | void): void {
        const data: IConfirmationDialogData = {
            title: _('confirm-delete-users.title'),
            question: _('confirm-delete-users.warning'),
            confirmationText: _('confirm-delete-users.delete'),
            denyText: _('confirm-delete-users.cancel'),
            titleColor: TitleColors.WARN,
            translateParams: { usersCount: 1, dossiersCount: this._getUsersDossiersCount(userIds) },
            checkboxes: [
                { value: false, label: _('confirm-delete-users.impacted-dossiers') },
                { value: false, label: _('confirm-delete-users.impacted-documents') },
            ],
            toastMessage: _('confirm-delete-users.toast-error'),
        };

        this.openDialog('confirm', data, async result => {
            if (result === ConfirmOptions.CONFIRM) {
                this._loadingService.start();
                await firstValueFrom(this._userService.delete(userIds));
                await cb();
                this._loadingService.stop();
            }
        });
    }

    async deleteAttributes(
        attributes: IFileAttributeConfig[] | IDossierAttributeConfig[],
        dossierTemplateId: string,
        impactedTemplatesRef: TemplateRef<unknown>,
        type: 'dossier' | 'file',
        cb: () => Promise<void> | void,
    ): Promise<void> {
        this._loadingService.start();
        const templates$ = attributes
            .map(a => a.placeholder)
            .map(placeholder => this._reportTemplateService.getTemplatesByPlaceholder(dossierTemplateId, placeholder as string));
        const templates: IReportTemplate[] = (await firstValueFrom(forkJoin(templates$))).flat();
        const templateIds = new Set<string>(templates.map(t => t.templateId));
        const uniqueTemplates = Array.from(templateIds).map(id => templates.find(t => t.templateId === id));
        this._loadingService.stop();

        const data: IConfirmationDialogData = {
            title: _('confirm-delete-attribute.title'),
            question: _('confirm-delete-attribute.warning'),
            confirmationText: _('confirm-delete-attribute.delete'),
            denyText: _('confirm-delete-attribute.cancel'),
            titleColor: TitleColors.WARN,
            checkboxes: [
                {
                    value: false,
                    label:
                        type === 'dossier'
                            ? _('confirm-delete-attribute.dossier-impacted-documents')
                            : _('confirm-delete-attribute.file-impacted-documents'),
                },
                {
                    value: false,
                    label:
                        type === 'dossier'
                            ? _('confirm-delete-attribute.dossier-lost-details')
                            : _('confirm-delete-attribute.file-lost-details'),
                },
            ],
            toastMessage: _('confirm-delete-attribute.toast-error'),
            translateParams: { reportsCount: uniqueTemplates.length, count: attributes.length, name: attributes[0].label },
        };

        if (templates.length) {
            data.checkboxes.push({
                value: false,
                label: _('confirm-delete-attribute.impacted-report'),
                extraContent: impactedTemplatesRef,
                extraContentData: { templates: uniqueTemplates },
            });
        }

        this.openDialog('confirm', data, async () => {
            await cb();
        });
    }

    private _getUsersDossiersCount(userIds: string[]): number {
        return this._activeDossiersService.all.filter(dw => userIds.reduce((prev, userId) => prev || dw.memberIds.includes(userId), false))
            .length;
    }
}
