import { computed, effect, Injectable, Signal, signal } from '@angular/core';
import { merge } from 'rxjs';
import { map, startWith, withLatestFrom } from 'rxjs/operators';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { FilesMapService } from '@services/files/files-map.service';
import { File, IFileAttributeConfig } from '@red/domain';
import { MultiSelectService } from './multi-select.service';
import { ExcludedPagesService } from './excluded-pages.service';

@Injectable()
export class DocumentInfoService {
    readonly shown: Signal<boolean>;
    readonly hidden: Signal<boolean>;
    readonly #show$ = signal(false);

    constructor(
        private readonly _dossierTemplatesService: DossierTemplatesService,
        private readonly _fileAttributesService: FileAttributesService,
        private readonly _filesMapService: FilesMapService,
        private readonly _multiSelectService: MultiSelectService,
        private readonly _excludedPagesService: ExcludedPagesService,
    ) {
        this.hidden = computed(() => !this.#show$());
        this.shown = this.#show$.asReadonly();
        effect(
            () => {
                if (this.shown()) {
                    this._multiSelectService.deactivate();
                    this._excludedPagesService.hide();
                }
            },
            { allowSignalWrites: true },
        );
    }

    fileAttributes$(fileId: string, dossierId: string, dossierTemplateId: string) {
        const getAttributes = () => this._fileAttributesService.getFileAttributeConfig(dossierTemplateId).fileAttributeConfigs;
        const dossierTemplateChange$ = this._dossierTemplatesService.getEntityChanged$(dossierTemplateId);
        const fileChange$ = this._filesMapService.watch$(dossierId, fileId);
        return merge(dossierTemplateChange$, fileChange$).pipe(
            map(getAttributes),
            startWith(getAttributes()),
            withLatestFrom(fileChange$),
            map(values => this._toAttributes(...values)),
        );
    }

    show() {
        this.#show$.set(true);
    }

    hide() {
        this.#show$.set(false);
    }

    toggle() {
        this.#show$.set(!this.#show$());
    }

    private _toAttributes(attributes: IFileAttributeConfig[], file: File) {
        return attributes.map(attr => ({
            label: attr.label,
            value: file?.fileAttributes?.attributeIdToValue[attr.id],
            type: attr.type,
        }));
    }
}
