import { ValuesOf } from '@iqser/common-ui/lib/utils';
import { EntityType, EntityTypes, EntryState, EntryStates, IEntityLogEntry } from '../redaction-log';

export const SuperTypes = {
    TextHighlight: 'text-highlight',
    IgnoredHint: 'hint-ignored',
    Skipped: 'skipped',
    Redaction: 'redaction',
    ManualRedaction: 'manual',
    ManualHint: 'manual-hint',
    Recommendation: 'recommendation',
    Hint: 'hint',
} as const;

export type SuperType = ValuesOf<typeof SuperTypes>;

function wrongSuperTypeHandler(): never | undefined {
    return undefined;
}

/**
 * https://knecon.atlassian.net/wiki/spaces/RED/pages/102072322/EntityLog+-+Enum+combinations
 */
export const SuperTypeMapper: Record<EntityType, Record<EntryState, (entry: IEntityLogEntry) => SuperType | undefined>> = {
    [EntityTypes.ENTITY]: {
        [EntryStates.APPLIED]: entry => {
            const hasManualChanges = entry.manualChanges.length;
            const hasEngines = entry.engines.length;
            if (hasManualChanges && !hasEngines) {
                return SuperTypes.ManualRedaction;
            }
            return SuperTypes.Redaction;
        },
        [EntryStates.SKIPPED]: () => SuperTypes.Skipped,
        [EntryStates.IGNORED]: () => SuperTypes.Skipped,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.HINT]: {
        [EntryStates.APPLIED]: wrongSuperTypeHandler,
        [EntryStates.SKIPPED]: entry => {
            const hasManualChanges = entry.manualChanges.length;
            const hasEngines = entry.engines.length;
            if (hasManualChanges && !hasEngines) {
                return SuperTypes.ManualHint;
            }
            return SuperTypes.Hint;
        },
        [EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.FALSE_POSITIVE]: {
        [EntryStates.APPLIED]: wrongSuperTypeHandler,
        [EntryStates.SKIPPED]: wrongSuperTypeHandler,
        [EntryStates.IGNORED]: wrongSuperTypeHandler,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.RECOMMENDATION]: {
        [EntryStates.APPLIED]: wrongSuperTypeHandler,
        [EntryStates.SKIPPED]: () => SuperTypes.Recommendation,
        [EntryStates.IGNORED]: wrongSuperTypeHandler,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.FALSE_RECOMMENDATION]: {
        [EntryStates.APPLIED]: wrongSuperTypeHandler,
        [EntryStates.SKIPPED]: wrongSuperTypeHandler,
        [EntryStates.IGNORED]: wrongSuperTypeHandler,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.AREA]: {
        [EntryStates.APPLIED]: () => SuperTypes.Redaction,
        [EntryStates.SKIPPED]: wrongSuperTypeHandler,
        [EntryStates.IGNORED]: wrongSuperTypeHandler,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.IMAGE]: {
        [EntryStates.APPLIED]: () => SuperTypes.Redaction,
        [EntryStates.SKIPPED]: () => SuperTypes.Skipped,
        [EntryStates.IGNORED]: () => SuperTypes.Skipped,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
    [EntityTypes.IMAGE_HINT]: {
        [EntryStates.APPLIED]: wrongSuperTypeHandler,
        [EntryStates.SKIPPED]: () => SuperTypes.Hint,
        [EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
        [EntryStates.REMOVED]: wrongSuperTypeHandler,
    },
};

export const LowLevelFilterTypes = {
    [SuperTypes.Hint]: true,
    [SuperTypes.Redaction]: true,
    [SuperTypes.Recommendation]: true,
    [SuperTypes.IgnoredHint]: true,
    [SuperTypes.Skipped]: true,
} as const;

export const FalsePositiveSuperTypes = {
    [SuperTypes.Hint]: true,
    [SuperTypes.Redaction]: true,
    [SuperTypes.IgnoredHint]: true,
    [SuperTypes.Skipped]: true,
} as const;
