import { Component, Inject, OnInit } from '@angular/core';
import { Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { BaseDialogComponent, getConfig, IconButtonTypes, IqserPermissionsService, SaveOptions } from '@iqser/common-ui';
import { TenantsService } from '@iqser/common-ui/lib/tenants';
import { DOSSIER_TEMPLATE_ID, DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { ReportTemplateService } from '@services/report-template.service';
import { downloadTypesTranslations } from '@translations/download-types-translations';
import { Roles } from '@users/roles';
import dayjs from 'dayjs';
import { firstValueFrom } from 'rxjs';
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';

interface DialogData {
    readonly dossierTemplateId?: string;
}

@Component({
    templateUrl: './add-dossier-dialog.component.html',
    styleUrls: ['./add-dossier-dialog.component.scss'],
})
export class AddDossierDialogComponent extends BaseDialogComponent implements OnInit {
    readonly config = getConfig();
    readonly roles = Roles;
    readonly iconButtonTypes = IconButtonTypes;
    hasDueDate = false;
    readonly downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(
        (type: DownloadFileType) => ({
            key: type,
            label: downloadTypesTranslations[type],
        }),
    );
    dossierTemplates: IDossierTemplate[];
    availableReportTypes: IReportTemplate[] = [];
    dossierTemplateId: string;

    constructor(
        readonly permissionsService: IqserPermissionsService,
        private readonly _tenantsService: TenantsService,
        private readonly _activeDossiersService: ActiveDossiersService,
        private readonly _dossierTemplatesService: DossierTemplatesService,
        private readonly _reportTemplateService: ReportTemplateService,
        private readonly _router: Router,
        private readonly _dialogService: DossiersDialogService,
        protected readonly _dialogRef: MatDialogRef<AddDossierDialogComponent>,
        @Inject(MAT_DIALOG_DATA) readonly data: DialogData,
    ) {
        super(_dialogRef);
        this.#getDossierTemplates();
        this.form = this.#getForm();
        this.initialFormValue = this.form.getRawValue();
    }

    get reportTemplateIdsLength() {
        return this.form.controls['reportTemplateIds']?.value?.length || 0;
    }

    get downloadFileTypesLength() {
        return this.form.controls['downloadFileTypes']?.value?.length || 0;
    }

    get disabled() {
        if (this.hasDueDate && this.form.get('dueDate').value === null) {
            return true;
        }

        return this.form.invalid;
    }

    async ngOnInit(): Promise<void> {
        await this.dossierTemplateChanged(this.form.get('dossierTemplateId').value);
    }

    reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;

    async save(options?: SaveOptions) {
        this._loadingService.start();
        const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this.#formToObject()));
        if (savedDossier) {
            await this._router.navigate([`/${this._tenantsService.activeTenantId}${savedDossier.routerLink}`]);
            if (options?.addMembers) {
                this._dialogService.openDialog('editDossier', {
                    dossierId: savedDossier.id,
                    section: 'members',
                });
            }
            this._dialogRef.close(savedDossier);
        }
        this._loadingService.stop();
    }

    async dossierTemplateChanged(dossierTemplateId: string) {
        this.dossierTemplateId = dossierTemplateId;

        // get current selected dossierTemplate
        const dossierTemplate = this.dossierTemplates.find(r => r.dossierTemplateId === dossierTemplateId);

        if (!dossierTemplate) {
            this.availableReportTypes = [];
            this.form.patchValue(
                {
                    downloadFileTypes: [],
                    reportTemplateIds: [],
                },
                { emitEvent: false },
            );
            return;
        }

        this._loadingService.start();
        this.availableReportTypes = (await this._reportTemplateService.getAvailableReportTemplates(dossierTemplateId)) || [];
        if (this.config.IS_DOCUMINE) {
            const firstReport = this.availableReportTypes.at(0);
            const reportTemplateIds = firstReport ? [firstReport.templateId] : [];
            this.form.patchValue(
                {
                    reportTemplateIds: reportTemplateIds,
                },
                { emitEvent: false },
            );
        } else {
            this.form.patchValue(
                {
                    downloadFileTypes: dossierTemplate.downloadFileTypes,
                },
                { emitEvent: false },
            );
        }

        this._loadingService.stop();
    }

    #getForm() {
        return this._formBuilder.group(
            {
                dossierName: [null, Validators.required],
                dossierTemplateId: [this.data?.dossierTemplateId, Validators.required],
                downloadFileTypes: [null],
                reportTemplateIds: [null],
                description: [null],
                dueDate: [null],
                watermarkId: [null],
                previewWatermarkId: [null],
            },
            {
                validators: control => {
                    const hasReports = control.value.reportTemplateIds?.length > 0;
                    const hasDownloadTypes = control.value.downloadFileTypes?.length > 0;
                    return hasReports || hasDownloadTypes ? null : { downloadPackage: true };
                },
            },
        );
    }

    #getDossierTemplates() {
        this.dossierTemplates = this._dossierTemplatesService.all
            .filter(r => {
                const notYetValid = !!r.validFrom && dayjs(r.validFrom).isAfter(dayjs());
                const notValidAnymore = !!r.validTo && dayjs(r.validTo).add(1, 'd').isBefore(dayjs());
                return !(notYetValid || notValidAnymore) && r.isActive;
            })
            .sort((t1, t2) => t1.name.toLowerCase().localeCompare(t2.name.toLowerCase()));
    }

    #formToObject(): IDossierRequest {
        return {
            dossierName: this.form.get('dossierName').value,
            description: this.form.get('description').value,
            dueDate: this.hasDueDate ? this.form.get('dueDate').value : undefined,
            dossierTemplateId: this.form.get(DOSSIER_TEMPLATE_ID).value,
            downloadFileTypes: this.form.get('downloadFileTypes').value,
            reportTemplateIds: this.form.get('reportTemplateIds').value,
            watermarkId: this.form.get('watermarkId').value,
            previewWatermarkId: this.form.get('previewWatermarkId').value,
        };
    }
}
