import {NativeModules} from 'react-native';
import type {CapturedResultFilter, CaptureVisionRouter} from '../cvr'
import {EnumCapturedResultItemType} from '../core'
import type { CrossVerificationCriteria } from './CrossVerificationCriteria';

// @ts-ignore Check whether __turboModuleProxy exists, it may not
const isTurboModuleEnabled = global.__turboModuleProxy != null;

const DynamsoftMultiCrossFilterModule = isTurboModuleEnabled ?
    require("./NativeDynamsoftMultiCrossFilterModule").default :
    NativeModules.DynamsoftMultiCrossFilterModule;

/**
 * The MultiFrameResultCrossFilter class offers a set of API functions designed for managing and filtering results from multiple image frames,
 * typically used in consecutive frames of a streaming video.
 *
 * @see {@link CapturedResultFilter}
 * @see {@link CaptureVisionRouter.addFilter}
 * */
export class MultiFrameResultCrossFilter implements CapturedResultFilter {
    private filterId = "";

    constructor() {
        this.filterId = DynamsoftMultiCrossFilterModule.createInstance()
    }

    /**@internal*/
    _getFilterId(): string {
        return this.filterId;
    }

    destroy() {
        DynamsoftMultiCrossFilterModule.destroy(this.filterId)
    }

    /**
     * Enables or disables the verification of specific result item types.
     * <p>Code Snippet:</p>
     *
     * ```
     * let filter = new MultiFrameResultCrossFilter();
     * filter.enableResultCrossVerification(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, true); //enable
     * //...
     * filter.enableResultCrossVerification(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, false); //disable
     * ```
     *
     * @param resultItemTypes - Specifies one or multiple specific result item types.
     * @param enable - Boolean to toggle verification on or off.
     * @see {@link EnumCapturedResultItemType}
     * */
    enableResultCrossVerification(resultItemTypes: EnumCapturedResultItemType | number, enable: boolean) {
        DynamsoftMultiCrossFilterModule.enableResultCrossVerification(this.filterId, resultItemTypes, enable)
    }

    /**
     * Checks if verification is active for a given result item type.
     * @param type - Specifies one specific result item type.
     * @return Promise<void> - A promise that resolves a boolean indicating the status of verification for the specified type.
     * */
    isResultCrossVerificationEnabled(type: EnumCapturedResultItemType | number): Promise<boolean> {
        return DynamsoftMultiCrossFilterModule.isResultCrossVerificationEnabled(this.filterId, type);
    }

    /**
     * Enables or disables the deduplication process for one or multiple specific result item types.
     * <p>Code Snippet:</p>
     *
     * ```
     * let filter = new MultiFrameResultCrossFilter();
     * filter.enableResultDeduplication(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, true); //enable
     * //...
     * filter.enableResultDeduplication(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, false); //disable
     * ```
     *
     * @param resultItemTypes - Specifies one or multiple specific result item types.
     * @param enable - Boolean to toggle deduplication on or off.
     * @see {@link EnumCapturedResultItemType}
     * */
    enableResultDeduplication(resultItemTypes: EnumCapturedResultItemType | number, enable: boolean) {
        DynamsoftMultiCrossFilterModule.enableResultDeduplication(this.filterId, resultItemTypes, enable);
    }

    /**
     * Checks if deduplication is active for a given result item type.
     * @param type - Specifies one specific result item type.
     * @return Promise<boolean> - A promise that resolves a boolean indicating the deduplication status for the specified type.
     * */
    isResultDeduplicationEnabled(type: EnumCapturedResultItemType | number): Promise<boolean> {
        return DynamsoftMultiCrossFilterModule.isResultDeduplicationEnabled(this.filterId, type);
    }

    /**
     * Sets the interval during which duplicates are disregarded for one or multiple specific result item types.
     *
     * @param types Specifies one or multiple specific result item types.
     * @param time Time in milliseconds during which duplicates are disregarded.
     * */
    setDuplicateForgetTime(types: EnumCapturedResultItemType | number, time: number) {
        DynamsoftMultiCrossFilterModule.setDuplicateForgetTime(this.filterId, types, time);
    }

    /**
     * Gets the interval during which duplicates are disregarded for a given result item type.
     * @param type Specifies one specific result item type.
     * @return Promise<boolean> - A promise that resolves  the maximum overlapping frames count for a given result item type.
     * */
    getDuplicateForgetTime(type: EnumCapturedResultItemType | number): Promise<number> {
        return DynamsoftMultiCrossFilterModule.getDuplicateForgetTime(this.filterId, type);
    }

    /**
     * Enables or disables the to-the-latest overlapping feature of one or multiple specific result item types.
     * <p>Code Snippet:</p>
     *
     * ```
     * let filter = new MultiFrameResultCrossFilter();
     * filter.enableLatestOverlapping(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, true); //enable
     * //...
     * filter.enableLatestOverlapping(EnumCapturedResultItemType.CRIT_BARCODE | EnumCapturedResultItemType.CRIT_TEXT_LINE, false); //disable
     * ```
     *
     * @param resultItemTypes - Specifies one or multiple specific result item types.
     * @param enable - Boolean to toggle to-the-latest overlapping on or off.
     * @see {@link EnumCapturedResultItemType}
     * */
    enableLatestOverlapping(resultItemTypes: EnumCapturedResultItemType | number, enable: boolean) {
        return DynamsoftMultiCrossFilterModule.enableLatestOverlapping(this.filterId, resultItemTypes, enable);
    }

    /**
     * Checks if to-the-latest overlapping is active for a given result item type.
     * @param type - Specifies one specific result item type.
     * @return Promise<void> - A promise that resolves a boolean indicating the to-the-latest overlapping status for the specified type.
     * */
    isLatestOverlappingEnabled(type: EnumCapturedResultItemType | number): Promise<boolean> {
        return DynamsoftMultiCrossFilterModule.isLatestOverlappingEnabled(this.filterId, type)
    }

    /**
     * Set the maximum overlapping frames count for one or multiple specific result item types.
     * You can set it higher if:
     * - You capture device is stationary or moving stably.
     * - You want to further improve the read-rate.
     *
     * @param types Specifies one or multiple specific result item types.
     * @param maxOverlappingFrames The maximum overlapping frame count for the overlapping.
     * */
    setMaxOverlappingFrames(types: EnumCapturedResultItemType | number, maxOverlappingFrames: number) {
        DynamsoftMultiCrossFilterModule.setMaxOverlappingFrames(this.filterId, types, maxOverlappingFrames);
    }

    /**
     * Get the maximum overlapping frames count for a given result item type.
     *
     * @param type Specifies a result item type.
     * @return {Promise<number>} A promise that resolves the maximum overlapping frame count for the overlapping..
     * */
    getMaxOverlappingFrames(type: EnumCapturedResultItemType | number): Promise<number> {
        return DynamsoftMultiCrossFilterModule.getMaxOverlappingFrames(this.filterId, type);
    }

    /**
     * Set the criteria for cross-verification of one or multiple specific result item types.
     *
     * @param types Specifies one or multiple specific result item types.
     * @param criteria The criteria for cross-verification, including parameters such as frameWindow and minConsistentFrames.
     * @see {@link CrossVerificationCriteria}
     * */
    setResultCrossVerificationCriteria(types: EnumCapturedResultItemType | number, criteria: CrossVerificationCriteria) {
        DynamsoftMultiCrossFilterModule.setResultCrossVerificationCriteria(this.filterId, types, criteria);
    }

    /**
     * Get the criteria for cross-verification of a given result item type.
     *
     * @param type Specifies a result item type.
     * @return {Promise<CrossVerificationCriteria>} A promise that resolves the criteria for cross-verification, including parameters such as frameWindow and minConsistentFrames.
     * @see {@link CrossVerificationCriteria}
     * */
    getResultCrossVerificationCriteria(type: EnumCapturedResultItemType | number): Promise<CrossVerificationCriteria> {
        return DynamsoftMultiCrossFilterModule.getResultCrossVerificationCriteria(this.filterId, type);
    }
}
