import { Component } from '@angular/core';
import { Dossier, DownloadFileType, DownloadFileTypes, File, IReportTemplate, WorkflowFileStatuses } from '@red/domain';
import { downloadTypesForDownloadTranslations } from '@translations/download-types-translations';
import { ReportTemplateService } from '@services/report-template.service';
import { AbstractControl, FormBuilder } from '@angular/forms';
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
import { IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { Roles } from '@users/roles';
import { List } from '@iqser/common-ui/lib/utils';

export interface DownloadDialogData {
    readonly dossier: Dossier;
    readonly files: File[];
}

export interface DownloadDialogResult {
    downloadFileTypes: List<DownloadFileType>;
    reportTemplateIds: List;
    redactionPreviewColor: string;
}

@Component({
    templateUrl: './download-dialog.component.html',
    styleUrls: ['./download-dialog.component.scss'],
})
export class DownloadDialogComponent extends IqserDialogComponent<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult> {
    readonly iconButtonTypes = IconButtonTypes;
    readonly downloadTypes: { key: DownloadFileType; label: string }[] = this.#formDownloadTypes;
    readonly availableReportTypes = this.#availableReportTypes;
    readonly form = this.#getForm();
    initialFormValue = this.form.getRawValue();
    readonly roles = Roles;

    constructor(
        private readonly _defaultColorsService: DefaultColorsService,
        private readonly _reportTemplateController: ReportTemplateService,
        private readonly _formBuilder: FormBuilder,
    ) {
        super();
    }

    get reportTypesLength() {
        return this.form.controls.reportTemplateIds?.value?.length || 0;
    }

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

    get hasUnapprovedFiles() {
        return this.data.files.some(file => !file.isApproved);
    }

    get invalidDownload() {
        return (
            !this.form.controls.reportTemplateIds.value.length &&
            !!this.form.controls.downloadFileTypes.value.length &&
            this.form.controls.downloadFileTypes.value.every(type => type === DownloadFileTypes.REDACTED) &&
            !this.data.files.some(file => file.workflowStatus === WorkflowFileStatuses.APPROVED)
        );
    }

    override get valid() {
        return this.form.valid && !this.invalidDownload;
    }

    get #availableReportTypes() {
        const dossierTemplateId = this.data.dossier.dossierTemplateId;
        const result = this._reportTemplateController.getAvailableReportTemplates(dossierTemplateId);
        return result.then(values => values ?? []);
    }

    get #formDownloadTypes() {
        return ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED']
            .map((type: DownloadFileType) => ({
                key: type,
                label: downloadTypesForDownloadTranslations[type],
            }))
            .filter(type => {
                if (!this.data.files.some(file => file.workflowStatus === WorkflowFileStatuses.APPROVED)) {
                    return type.key !== DownloadFileTypes.REDACTED;
                }
                return true;
            });
    }

    get #selectedDownloadTypes() {
        return this.data.dossier.downloadFileTypes.filter(type => {
            if (!this.data.files.some(file => file.workflowStatus === WorkflowFileStatuses.APPROVED)) {
                return type !== DownloadFileTypes.REDACTED;
            }
            return true;
        });
    }

    override onEnterValidator() {
        return this.valid;
    }

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

    close() {
        const result: DownloadDialogResult = {
            reportTemplateIds: this.form.controls.reportTemplateIds.value,
            downloadFileTypes: this.form.controls.downloadFileTypes.value,
            redactionPreviewColor: this.form.controls.redactionPreviewColor.value,
        };

        if (result.reportTemplateIds.length === 0) {
            return this.dialogRef.close();
        }

        this.dialogRef.close(result);
    }

    #hasReportTemplateOrDownloadType(control: AbstractControl) {
        const atLeastAReportSelected = control.get('reportTemplateIds')?.value.length > 0;
        const atLeastATypeSelected = control.get('downloadFileTypes')?.value.length > 0;

        return atLeastATypeSelected || atLeastAReportSelected ? null : { reportTemplateIds: true, downloadFileTypes: true };
    }

    #getForm() {
        const previewColor = this._defaultColorsService.getColor(this.data.dossier.dossierTemplateId, 'previewColor');
        return this._formBuilder.group(
            {
                reportTemplateIds: [this.data.dossier.reportTemplateIds],
                downloadFileTypes: [this.#selectedDownloadTypes],
                redactionPreviewColor: [previewColor],
            },
            {
                validators: [control => this.#hasReportTemplateOrDownloadType(control), control => this.#isHexColor(control)],
            },
        );
    }

    #isHexColor(control: AbstractControl) {
        const color = control.get('redactionPreviewColor')?.value;
        const isHexColor = /^#[0-9A-F]{6}$/i.test(color);
        return isHexColor ? null : { redactionPreviewColor: true };
    }
}
