import { Injectable } from '@angular/core';
import { Dossier, DossierAttributeConfig, DossierAttributeWithValue, IDossierAttribute, IDossierAttributeConfig } from '@red/domain';
import { firstValueFrom, Observable } from 'rxjs';
import { EntitiesService } from '@iqser/common-ui';
import { map, tap } from 'rxjs/operators';
import { List, mapEach } from '@iqser/common-ui/lib/utils';

@Injectable({
    providedIn: 'root',
})
export class DossierAttributesService extends EntitiesService<IDossierAttributeConfig, DossierAttributeConfig> {
    protected readonly _defaultModelPath = 'dossier-attributes';
    protected readonly _entityClass = DossierAttributeConfig;

    async getWithValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> {
        const attributes = await firstValueFrom(this.getAttributes(dossier.id));
        const attributesConfig = await firstValueFrom(this.getConfig(dossier.dossierTemplateId));

        return attributesConfig.map(config => ({
            ...config,
            value: attributes.find(attr => attr.dossierAttributeConfigId === config.id)?.value,
        }));
    }

    setAttributes(dossier: Dossier, dossierAttributeList: List<IDossierAttribute>) {
        return this._post<{ dossierAttributeList?: List<IDossierAttribute> }>(
            { dossierAttributeList },
            `${this._defaultModelPath}/set/${dossier.id}`,
        );
    }

    delete(ids: List, dossierTemplateId: string): Observable<unknown> {
        const queryParams = ids.map(id => ({ key: 'dossierAttributeIds', value: id }));
        return this._post(null, `${this._defaultModelPath}/config/delete/${dossierTemplateId}`, queryParams);
    }

    loadAll(dossierTemplateId: string): Observable<DossierAttributeConfig[]> {
        return this.getConfig(dossierTemplateId).pipe(
            map(entities => entities ?? []),
            mapEach(entity => new DossierAttributeConfig(entity)),
            tap(entities => this.setEntities(entities)),
        );
    }

    createOrUpdate(attributeConfig: IDossierAttributeConfig, dossierTemplateId: string) {
        const url = `${this._defaultModelPath}/config/${dossierTemplateId}`;
        return firstValueFrom(this._post(attributeConfig, url));
    }

    getConfig(dossierTemplateId: string): Observable<List<IDossierAttributeConfig>> {
        return this._getOne<{ dossierAttributeConfigs: List<IDossierAttributeConfig> }>(['config', dossierTemplateId]).pipe(
            map(res => res.dossierAttributeConfigs),
        );
    }

    getAttributes(dossierId: string): Observable<List<IDossierAttribute>> {
        return this._getOne<{ dossierAttributeList?: List<IDossierAttribute> }>([dossierId]).pipe(map(res => res.dossierAttributeList));
    }
}
