import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dossier, User } from '@red/domain';
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, IqserPermissionsService, SaveOptions } from '@iqser/common-ui';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';

import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { ConfigService } from '@services/config.service';

type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes';

interface NavItem {
    key: Section;
    title?: string;
    sideNavTitle?: string;
    readonly?: boolean;
    helpModeKey?: string;
    hide?: boolean;
}

@Component({
    templateUrl: './edit-dossier-dialog.component.html',
    styleUrls: ['./edit-dossier-dialog.component.scss'],
    providers: [dossiersServiceProvider],
})
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
    readonly #currentUser = getCurrentUser<User>();
    private _dossier: Dossier;
    readonly roles = Roles;
    navItems: NavItem[] = [];
    readonly iconButtonTypes = IconButtonTypes;
    activeNav: Section;
    readonly dossier$: Observable<Dossier>;
    @ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent;
    @ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent;
    @ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
    @ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent;
    @ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;

    constructor(
        readonly iqserPermissionsService: IqserPermissionsService,
        private readonly _dossiersService: DossiersService,
        private readonly _permissionsService: PermissionsService,
        protected readonly _dialogRef: MatDialogRef<EditDossierDialogComponent>,
        @Inject(MAT_DIALOG_DATA)
        private readonly _data: {
            dossierId: string;
            section?: Section;
        },
        readonly configService: ConfigService,
    ) {
        super(_dialogRef, true);
        this.dossier$ = this._dossiersService.getEntityChanged$(_data.dossierId).pipe(
            tap(dossier => {
                this._dossier = dossier;
                this._initializeNavItems();
            }),
        );
        this.activeNav = _data.section || 'dossierInfo';
    }

    get activeNavItem(): NavItem {
        return this.navItems.find(item => item.key === this.activeNav);
    }

    get activeComponent(): EditDossierSectionInterface {
        return {
            dossierInfo: this.generalInfoComponent,
            downloadPackage: this.downloadPackageComponent,
            dossierDictionary: this.dictionaryComponent,
            members: this.membersComponent,
            dossierAttributes: this.attributesComponent,
        }[this.activeNav];
    }

    get noPaddingTab(): boolean {
        return ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
    }

    get showHeading(): boolean {
        return !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
    }

    get showActionButtons(): boolean {
        return (
            (['dossierDictionary'].includes(this.activeNav) && this._permissionsService.canEditDossierDictionary(this._dossier)) ||
            (['members'].includes(this.activeNav) &&
                this.#currentUser.isManager &&
                this.iqserPermissionsService.has(Roles.dossiers.edit)) ||
            this._permissionsService.canEditDossier(this._dossier)
        );
    }

    get changed(): boolean {
        return this.activeComponent?.changed;
    }

    get valid(): boolean {
        return this.activeComponent?.valid;
    }

    get disabled(): boolean {
        return this.activeComponent?.disabled;
    }

    ngAfterViewInit() {
        if (!this._dossier.ownerId) {
            this._toaster.error(_('edit-dossier-dialog.missing-owner'));
        }
    }

    async save(options?: SaveOptions) {
        this._loadingService.start();
        const result = await this.activeComponent.save();
        this._loadingService.stop();

        if (result.success) {
            this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this._dossier.dossierName } });
        }

        if (result.success && options?.closeAfterSave) {
            this._dialogRef.close();
        }
    }

    revert() {
        this.activeComponent.revert();
    }

    changeTab(key: Section) {
        if (this.changed) {
            this._openConfirmDialog().then(async result => {
                if (result === ConfirmOptions.CONFIRM) {
                    await this.save();
                } else {
                    this.revert();
                }
                this.activeNav = key;
            });
        } else {
            this.activeNav = key;
        }
    }

    private _initializeNavItems(): void {
        this.navItems = [
            {
                key: 'dossierInfo',
                title: _('edit-dossier-dialog.nav-items.general-info'),
                sideNavTitle: _('edit-dossier-dialog.nav-items.dossier-info'),
                readonly: !this._dossier.isActive || !this._permissionsService.canEditDossier(this._dossier),
                helpModeKey: 'edit_dossier_dossier_info_DIALOG',
            },
            {
                key: 'downloadPackage',
                title: _('edit-dossier-dialog.nav-items.choose-download'),
                sideNavTitle: _('edit-dossier-dialog.nav-items.download-package'),
                readonly: !this._permissionsService.canEditDossier(this._dossier),
                helpModeKey: 'edit_dossier_download_package_DIALOG',
            },
            {
                key: 'dossierDictionary',
                sideNavTitle: _('edit-dossier-dialog.nav-items.dictionary'),
                title: _('edit-dossier-dialog.nav-items.dossier-dictionary'),
                readonly: !this._permissionsService.canEditDossierDictionary(this._dossier),
                helpModeKey: 'edit_dossier_dossier_dictionary_DIALOG',
                hide: this.configService.values.IS_DOCUMINE,
            },
            {
                key: 'members',
                title: _('edit-dossier-dialog.nav-items.team-members'),
                sideNavTitle: _('edit-dossier-dialog.nav-items.members'),
                readonly: !this._permissionsService.canEditTeamMembers(),
                helpModeKey: 'edit_dossier_members_DIALOG',
            },
            {
                key: 'dossierAttributes',
                title: _('edit-dossier-dialog.nav-items.dossier-attributes'),
                readonly: !this._permissionsService.canEditDossierAttributes(this._dossier),
                helpModeKey: 'edit_dossier_dossier_attributes_DIALOG',
            },
        ];
    }
}
