import { IDossierStats } from './dossier-stats';
import { FileCountPerProcessingStatus, FileCountPerWorkflowStatus } from './types';
import { isProcessingStatuses, OCR_STATES, PENDING_STATES, PROCESSED_STATES, PROCESSING_STATES, ProcessingFileStatus } from '../files';

export const ProcessingTypes = {
    pending: 'pending',
    ocr: 'ocr',
    processing: 'processing',
    processed: 'processed',
} as const;

export type ProcessingType = keyof typeof ProcessingTypes;

export type ProcessingStats = Record<ProcessingType, number>;

export class DossierStats implements IDossierStats {
    readonly dossierId: string;
    readonly fileCountPerProcessingStatus: FileCountPerProcessingStatus;
    readonly fileCountPerWorkflowStatus: FileCountPerWorkflowStatus;
    readonly fileManipulationDate: string;
    readonly hasHintsNoRedactionsFilePresent: boolean;
    readonly hasNoFlagsFilePresent: boolean;
    readonly hasRedactionsFilePresent: boolean;
    readonly hasSuggestionsFilePresent: boolean;
    readonly hasUpdatesFilePresent: boolean;
    readonly numberOfPages: number;
    readonly numberOfFiles: number;
    readonly numberOfProcessingFiles: number;
    readonly processingStats: ProcessingStats;
    readonly numberOfSoftDeletedFiles: number;

    readonly hasFiles: boolean;

    constructor(stats: IDossierStats) {
        this.dossierId = stats.dossierId;
        this.fileCountPerProcessingStatus = stats.fileCountPerProcessingStatus;
        this.fileCountPerWorkflowStatus = stats.fileCountPerWorkflowStatus;
        this.fileManipulationDate = stats.fileManipulationDate;
        this.hasHintsNoRedactionsFilePresent = stats.hasHintsNoRedactionsFilePresent;
        this.hasNoFlagsFilePresent = stats.hasNoFlagsFilePresent;
        this.hasRedactionsFilePresent = stats.hasRedactionsFilePresent;
        this.hasSuggestionsFilePresent = stats.hasSuggestionsFilePresent;
        this.hasUpdatesFilePresent = stats.hasUpdatesFilePresent;
        this.numberOfPages = stats.numberOfPages;
        this.numberOfFiles = stats.numberOfFiles;
        this.numberOfSoftDeletedFiles = stats.numberOfSoftDeletedFiles;
        this.numberOfProcessingFiles = Object.entries<number>(this.fileCountPerProcessingStatus)
            .filter(([key]) => isProcessingStatuses.includes(key as ProcessingFileStatus))
            .reduce((count, [, value]) => count + value, 0);
        this.processingStats = this.#processingStats;
        this.hasFiles = this.numberOfFiles > 0;
    }

    get #processingStats(): ProcessingStats {
        return {
            pending: this.#getTotal(PENDING_STATES),
            processed: this.#getTotal(PROCESSED_STATES),
            processing: this.#getTotal(PROCESSING_STATES),
            ocr: this.#getTotal(OCR_STATES),
        };
    }

    #getTotal(states: ProcessingFileStatus[]): number {
        return states.reduce((total, state) => total + (this.fileCountPerProcessingStatus[state] || 0), 0);
    }
}
