import { inject, Injectable } from '@angular/core';
import { GenericService, IqserPermissionsService, QueryParam } from '@iqser/common-ui';
import { IWatermark, Watermark } from '@red/domain';
import { firstValueFrom, forkJoin, Observable, of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { mapEach } from '@iqser/common-ui/lib/utils';
import { Roles } from '@users/roles';

interface IsUsedResponse {
    value: boolean;
}

@Injectable({
    providedIn: 'root',
})
export class WatermarkService extends GenericService<IWatermark> {
    protected readonly _defaultModelPath = 'watermark';

    readonly #watermarksMapService = inject(WatermarksMapService);
    readonly #allowed = inject(IqserPermissionsService).has(Roles.watermarks.read);

    async deleteWatermark(dossierTemplateId: string, watermarkId: number) {
        await firstValueFrom(super.delete(null, `${this._defaultModelPath}/${watermarkId}`));
        return firstValueFrom(this.loadForDossierTemplate(dossierTemplateId));
    }

    async saveWatermark(body: IWatermark) {
        const watermark = await firstValueFrom(this._post(body, `${this._defaultModelPath}`));
        await firstValueFrom(this.loadForDossierTemplate(watermark.dossierTemplateId));
        return this.#watermarksMapService.get(watermark.dossierTemplateId, watermark.id);
    }

    loadForDossierTemplate(dossierTemplateId: string): Observable<Watermark[]> {
        const queryParams: QueryParam[] = [{ key: 'dossierTemplateId', value: dossierTemplateId }];
        return this.getAll(this._defaultModelPath, queryParams).pipe(
            mapEach(entity => new Watermark(entity)),
            tap(entities => this.#watermarksMapService.set(dossierTemplateId, entities.sort(this.sortByStatusFn))),
        );
    }

    loadAll(dossierTemplateIds: string[]): Observable<Watermark[]> {
        if (!this.#allowed) {
            return of([]);
        }
        return forkJoin(dossierTemplateIds.map(id => this.loadForDossierTemplate(id))).pipe(map(arrays => [].concat(...arrays)));
    }

    async isWatermarkUsed(watermarkId: number) {
        const queryParams: QueryParam[] = [{ key: 'watermarkId', value: watermarkId }];
        const result = await firstValueFrom(this.getAll<IsUsedResponse>(`${this._defaultModelPath}/used`, queryParams));
        return result.value;
    }

    sortByStatusFn = (a: Watermark, b: Watermark) => {
        if (a.enabled === b.enabled) {
            return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
        }
        return a.enabled ? -1 : 1;
    };
}
