import { Injectable } from '@angular/core';
import { GenericService, QueryParam, Toaster } from '@iqser/common-ui';
import { Dossier, File, IPageExclusionRequest } from '@red/domain';
import { catchError, tap } from 'rxjs/operators';
import { FilesService } from './files/files.service';
import { FilesMapService } from './files/files-map.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { firstValueFrom, of } from 'rxjs';
import { List } from '@iqser/common-ui/lib/utils';

export interface ReanalyzeQueryParams {
    force?: boolean;
    triggeredByUser?: boolean;
}

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

    constructor(
        private readonly _toaster: Toaster,
        private readonly _filesService: FilesService,
        private readonly _filesMapService: FilesMapService,
    ) {
        super();
    }

    async excludePages(body: IPageExclusionRequest, file: File) {
        const dossierId = file.dossierId;
        await firstValueFrom(this._post(body, `exclude-pages/${dossierId}/${file.id}`));
        return await this._filesService.reload(dossierId, file);
    }

    async includePages(body: IPageExclusionRequest, file: File) {
        const dossierId = file.dossierId;
        await firstValueFrom(this._post(body, `include-pages/${dossierId}/${file.id}`));
        return await this._filesService.reload(dossierId, file);
    }

    async reanalyzeFilesForDossier(files: List<File>, dossierId: string, params?: ReanalyzeQueryParams) {
        const fileIds = files.map(f => f.id);
        const queryParams: QueryParam[] = [];
        if (params?.force) {
            queryParams.push({ key: 'force', value: true });
        }
        if (params?.triggeredByUser) {
            queryParams.push({ key: 'triggeredByUser', value: true });
        }

        await firstValueFrom(this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams));
        return firstValueFrom(this._filesService.loadAll(dossierId));
    }

    async toggleAnalysis(dossierId: string, files: List<File>, excluded?: boolean) {
        const fileIds = files.map(f => f.id);
        const queryParams: QueryParam[] = [];
        if (excluded) {
            queryParams.push({ key: 'excluded', value: excluded });
        }

        await firstValueFrom(this._post(fileIds, `toggle-analysis/${dossierId}/bulk`, queryParams));
        return firstValueFrom(this._filesService.loadAll(dossierId));
    }

    toggleAutomaticAnalysis(dossierId: string, files: File[]) {
        const fileIds = files.map(file => file.id);
        const excluded = !files[0].excludedFromAutomaticAnalysis;
        const queryParams: QueryParam[] = [{ key: 'excluded', value: excluded }];
        return this._post(fileIds, `toggle-automatic-analysis/${dossierId}/bulk`, queryParams).pipe(
            tap(() => this._filesMapService.replaceFiles(files, 'excludedFromAutomaticAnalysis', value => !value)),
            tap(() =>
                this._toaster.success(_('toggle-auto-analysis-message.success'), {
                    params: { toggleOperation: excluded ? 'Deactivated' : 'Activated' },
                }),
            ),
            catchError(() => {
                this._toaster.error(_('toggle-auto-analysis-message.error'));
                return of({});
            }),
        );
    }

    async ocrFiles(files: List<File>, dossierId: string) {
        const fileIds = files.map(f => f.id);
        await firstValueFrom(this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`));
        return firstValueFrom(this._filesService.loadAll(dossierId));
    }

    async reanalyzeDossier(dossier: Dossier, force?: boolean) {
        const { dossierId } = dossier;
        const queryParams: QueryParam[] = [];
        if (force) {
            queryParams.push({ key: 'force', value: force });
        }

        await firstValueFrom(this._post({}, `reanalyze/${dossierId}`, queryParams));
        return await firstValueFrom(this._filesService.loadAll(dossierId));
    }
}
