import { NgForOf, NgIf } from '@angular/common';
import { AfterViewInit, Component, computed, Inject, Signal, signal, untracked, viewChild, WritableSignal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatIcon } from '@angular/material/icon';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { SideNavComponent } from '@common-ui/shared';
import {
    BaseDialogComponent,
    CircleButtonComponent,
    ConfirmOptions,
    HelpButtonComponent,
    IconButtonComponent,
    IconButtonTypes,
    IqserDenyDirective,
    SaveOptions,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { Dossier } from '@red/domain';
import { ConfigService } from '@services/config.service';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
import { PermissionsService } from '@services/permissions.service';
import { Roles } from '@users/roles';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';

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],
    standalone: true,
    imports: [
        TranslateModule,
        SideNavComponent,
        NgForOf,
        NgIf,
        MatIcon,
        EditDossierGeneralInfoComponent,
        EditDossierDownloadPackageComponent,
        EditDossierDictionaryComponent,
        EditDossierAttributesComponent,
        IconButtonComponent,
        HelpButtonComponent,
        IqserDenyDirective,
        CircleButtonComponent,
        EditDossierTeamComponent,
    ],
})
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
    readonly roles = Roles;
    readonly iconButtonTypes = IconButtonTypes;

    readonly activeNav: WritableSignal<Section>;
    readonly dossier: Signal<Dossier>;
    readonly navItems: Signal<NavItem[]>;
    readonly activeNavItem: Signal<NavItem>;
    readonly activeComponent: Signal<EditDossierSectionInterface>;
    readonly noPaddingTab: Signal<boolean>;
    readonly showHeading: Signal<boolean>;
    readonly showActionButtons: Signal<boolean>;

    readonly generalInfoComponent = viewChild(EditDossierGeneralInfoComponent);
    readonly downloadPackageComponent = viewChild(EditDossierDownloadPackageComponent);
    readonly dictionaryComponent = viewChild(EditDossierDictionaryComponent);
    readonly membersComponent = viewChild(EditDossierTeamComponent);
    readonly attributesComponent = viewChild(EditDossierAttributesComponent);

    constructor(
        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 = toSignal(this._dossiersService.getEntityChanged$(this._data.dossierId));
        this.navItems = computed(() => this._getNavItems(this.dossier()));
        this.activeNav = signal(this._data.section || 'dossierInfo');
        this.activeNavItem = computed(() => this.navItems().find(item => item.key === this.activeNav()));
        this.activeComponent = computed(() => this._getActiveComponent(this.activeNav()));
        this.noPaddingTab = computed(() => ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
        this.showHeading = computed(() => !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
        this.showActionButtons = computed(() => !this.activeNavItem().readonly);
    }

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

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

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

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

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

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

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

    revert() {
        untracked(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.set(key);
            });
        } else {
            this.activeNav.set(key);
        }
    }

    private _getActiveComponent(section: Section): EditDossierSectionInterface {
        return {
            dossierInfo: this.generalInfoComponent(),
            downloadPackage: this.downloadPackageComponent(),
            dossierDictionary: this.dictionaryComponent(),
            members: this.membersComponent(),
            dossierAttributes: this.attributesComponent(),
        }[section];
    }

    private _getNavItems(dossier: Dossier): NavItem[] {
        return [
            {
                key: 'dossierInfo',
                title: _('edit-dossier-dialog.nav-items.general-info'),
                sideNavTitle: _('edit-dossier-dialog.nav-items.dossier-info'),
                readonly: !this._permissionsService.canEditDossier(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(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(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(dossier),
                helpModeKey: 'edit_dossier_members_DIALOG',
            },
            {
                key: 'dossierAttributes',
                title: _('edit-dossier-dialog.nav-items.dossier-attributes'),
                readonly: !this._permissionsService.canEditDossierAttributes(dossier),
                helpModeKey: 'edit_dossier_dossier_attributes_DIALOG',
            },
        ];
    }
}
