import { KeyValuePipe, NgForOf, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, OnInit, signal } from '@angular/core';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ReplaceNbspPipe } from '@common-ui/pipes/replace-nbsp.pipe';
import { BaseDialogComponent, CircleButtonComponent, EditableInputComponent, IconButtonComponent } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { ComponentLogEntry, IFile, WorkflowFileStatuses } from '@red/domain';
import { FilesMapService } from '@services/files/files-map.service';
import { UserPreferenceService } from '@users/user-preference.service';
import { firstValueFrom } from 'rxjs';
import { ComponentLogService } from '@services/files/component-log.service';

interface ScmData {
    file: IFile;
}

@Component({
    templateUrl: './structured-component-management-dialog.component.html',
    styleUrls: ['./structured-component-management-dialog.component.scss'],
    standalone: true,
    changeDetection: ChangeDetectionStrategy.OnPush,
    imports: [
        NgIf,
        EditableInputComponent,
        NgForOf,
        KeyValuePipe,
        TranslateModule,
        CircleButtonComponent,
        IconButtonComponent,
        MatCheckboxModule,
        MatDialogModule,
        ReplaceNbspPipe,
    ],
})
export class StructuredComponentManagementDialogComponent extends BaseDialogComponent implements OnInit {
    readonly componentLogData = signal<ComponentLogEntry[] | undefined>(undefined);
    readonly openScmDialogByDefault = signal(this.userPreferences.getOpenScmDialogByDefault());

    constructor(
        protected readonly _dialogRef: MatDialogRef<StructuredComponentManagementDialogComponent>,
        private readonly _componentLogService: ComponentLogService,
        readonly userPreferences: UserPreferenceService,
        private readonly _filesMapService: FilesMapService,
        @Inject(MAT_DIALOG_DATA) readonly data: ScmData,
    ) {
        super(_dialogRef);
    }

    get canEdit() {
        return this.data.file.workflowStatus !== WorkflowFileStatuses.APPROVED;
    }

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

    getValueCellId(index: number) {
        return `value-cell-${index}`;
    }

    originalOrder = (): number => 0;

    exportJSON() {
        return firstValueFrom(
            this._componentLogService.exportJSON(
                this.data.file.dossierTemplateId,
                this.data.file.dossierId,
                this.data.file.fileId,
                this.data.file.filename,
            ),
        );
    }

    exportXML() {
        return firstValueFrom(
            this._componentLogService.exportXML(
                this.data.file.dossierTemplateId,
                this.data.file.dossierId,
                this.data.file.fileId,
                this.data.file.filename,
            ),
        );
    }

    async exportAllInDossier() {
        const allFilesInDossier = this._filesMapService.get(this.data.file.dossierId);
        for (const file of allFilesInDossier) {
            await firstValueFrom(
                this._componentLogService.exportJSON(this.data.file.dossierTemplateId, file.dossierId, file.fileId, file.filename),
            );
            await firstValueFrom(
                this._componentLogService.exportXML(this.data.file.dossierTemplateId, file.dossierId, file.fileId, file.filename),
            );
        }
    }

    save() {
        return this.exportJSON();
    }

    async toggleOpenScmDialogByDefault() {
        await this.userPreferences.toggleOpenScmDialogByDefault();
        await this.userPreferences.reload();
        this.openScmDialogByDefault.set(this.userPreferences.getOpenScmDialogByDefault());
    }

    async undo(originalKey: string) {
        this._loadingService.start();
        await firstValueFrom(this._componentLogService.revertOverride(this.data.file.dossierId, this.data.file.fileId, [originalKey]));
        await this.#loadData();
    }

    async saveEdit(event: string, originalKey: string) {
        this._loadingService.start();
        await firstValueFrom(this._componentLogService.override(this.data.file.dossierId, this.data.file.fileId, { [originalKey]: event }));
        await this.#loadData();
    }

    async #loadData(): Promise<void> {
        this._loadingService.start();
        const componentLogData = await firstValueFrom(
            this._componentLogService.getComponentLogData(
                this.data.file.dossierTemplateId,
                this.data.file.dossierId,
                this.data.file.fileId,
            ),
        );
        this.componentLogData.set(componentLogData);
        this._loadingService.stop();
    }
}
