import { booleanAttribute, Component, computed, inject, input, Input, OnChanges, ViewChild } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { CircleButtonComponent, CircleButtonType, CircleButtonTypes, getConfig, IqserDialog, Toaster } from '@iqser/common-ui';
import { Dossier, File, IFile, ProcessingFileStatuses } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { DownloadDialogComponent } from '@shared/dialogs/download-dialog/download-dialog.component';
import { FileDownloadService } from '@upload-download/services/file-download.service';
import { APP_BASE_HREF } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
import { firstValueFrom } from 'rxjs';
import { ComponentLogService } from '@services/files/component-log.service';

@Component({
    selector: 'redaction-file-download-btn',
    templateUrl: './file-download-btn.component.html',
    standalone: true,
    imports: [CircleButtonComponent, TranslateModule, MatMenu, MatMenuItem, MatMenuTrigger],
})
export class FileDownloadBtnComponent implements OnChanges {
    readonly files = input.required<File[]>();
    readonly dossier = input.required<Dossier>();
    readonly buttonId = input.required<string>();
    readonly tooltipPosition = input<'above' | 'below' | 'before' | 'after'>('above');
    readonly type = input<CircleButtonType>(CircleButtonTypes.default);
    readonly tooltipClass = input<string>();
    readonly disabled = input<boolean>(false);
    readonly singleFileDownload = input<boolean>(false);
    readonly dossierDownload = input(false, { transform: booleanAttribute });
    readonly dropdownButton = computed(() => this.isDocumine && (this.dossierDownload() || this.singleFileDownload()));
    tooltip: string;
    canDownloadFiles: boolean;
    invalidDownload = false;
    readonly #appBaseHref = inject(APP_BASE_HREF);
    protected readonly isDocumine = getConfig().IS_DOCUMINE;
    @ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger;

    constructor(
        private readonly _permissionsService: PermissionsService,
        private readonly _fileDownloadService: FileDownloadService,
        private readonly _componentLogService: ComponentLogService,
        private readonly _dialog: IqserDialog,
        private readonly _toaster: Toaster,
    ) {}

    ngOnChanges(): void {
        this.invalidDownload = this.files().some(file => file.processingStatus === ProcessingFileStatuses.ERROR);
        this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files(), this.dossier());
        if (this.canDownloadFiles) {
            if (this.isDocumine && !this.dropdownButton()) {
                this.tooltip = _('dossier-overview.report-download');
            } else {
                this.tooltip = _('dossier-overview.download-file');
            }
        } else {
            this.tooltip = _('dossier-overview.download-file-disabled');
        }
    }

    async downloadFiles($event?: MouseEvent) {
        $event?.stopImmediatePropagation();
        this.menuTrigger?.closeMenu();
        const ref = this._dialog.openDefault(DownloadDialogComponent, {
            data: { dossier: this.dossier(), files: this.files() },
        });
        const result = await ref.result();
        if (!result) {
            return;
        }

        const downloadRequest = this._fileDownloadService.downloadFiles({
            dossierId: this.dossier().id,
            fileIds: this.files().map(f => f.id),
            ...result,
        });

        await downloadRequest
            .then(() =>
                this._toaster.info(_('download-status.queued'), {
                    params: { downloadHref: `${this.#appBaseHref}/main/downloads` },
                }),
            )
            .catch(() => this._toaster.error(_('download-status.error')));
    }

    downloadComponentAsJSON($event: MouseEvent) {
        $event.stopImmediatePropagation();
        this.menuTrigger?.closeMenu();
        const fileToDownload = !this.dossierDownload() ? this.files()[0] : null;
        return firstValueFrom(this._componentLogService.exportJSON(this.dossier().dossierTemplateId, this.dossier().id, fileToDownload));
    }

    async downloadComponentAsXML($event: MouseEvent) {
        $event.stopImmediatePropagation();
        this.menuTrigger?.closeMenu();
        const fileToDownload = !this.dossierDownload() ? this.files()[0] : null;
        return firstValueFrom(this._componentLogService.exportXML(this.dossier().dossierTemplateId, this.dossier().id, fileToDownload));
    }
}
