import React, { CSSProperties, ReactNode, RefObject, RefCallback } from 'react';
import { BarcodeFormat } from 'barcode-detector';
export { setZXingModuleOverrides } from 'barcode-detector';

interface IScannerComponents {
    tracker?: TrackFunction;
    audio?: boolean;
    onOff?: boolean;
    finder?: boolean;
    torch?: boolean;
    zoom?: boolean;
}

interface IPoint {
    x: number;
    y: number;
}

interface IBoundingBox {
    x: number;
    y: number;
    width: number;
    height: number;
}

interface IUseScannerState {
    lastScan: number;
    lastOnScan: number;
    contentBefore: string[];
    lastScanHadContent: boolean;
}

interface IDetectedBarcode {
    boundingBox: IBoundingBox;
    cornerPoints: IPoint[];
    format: string;
    rawValue: string;
}

interface IStartTaskResult {
    type: 'start';
    data: {
        videoEl: HTMLVideoElement;
        stream: MediaStream;
        constraints: MediaTrackConstraints;
    };
}

interface IStopTaskResult {
    type: 'stop';
    data: {};
}

interface IStartCamera {
    constraints: MediaTrackConstraints;
    restart?: boolean;
    onRestarted: () => void;
}

interface IScannerStyles {
    container?: CSSProperties;
    video?: CSSProperties;
    finderBorder?: number;
}

interface IScannerClassNames {
    container?: string;
    video?: string;
}

type TrackFunction = (detectedCodes: IDetectedBarcode[], ctx: CanvasRenderingContext2D) => void;

interface IScannerProps {
    onScan: (detectedCodes: IDetectedBarcode[]) => void;
    onError?: (error: unknown) => void;
    constraints?: MediaTrackConstraints;
    formats?: BarcodeFormat[];
    paused?: boolean;
    children?: ReactNode;
    components?: IScannerComponents;
    styles?: IScannerStyles;
    classNames?: IScannerClassNames;
    allowMultiple?: boolean;
    scanDelay?: number;
    onSetup?: (videoElementRef: RefObject<HTMLVideoElement>, videoTrackRef: RefObject<MediaStreamTrack>) => void;
    restart?: boolean;
    onRestarted?: () => void;
}
declare function Scanner(props: IScannerProps): React.JSX.Element;

declare function useDevices(): MediaDeviceInfo[];

interface APLWindow {
    startX: number;
    startY: number;
    width: number;
    height: number;
}
interface UseWindowedExposureOptions {
    targetAPL?: number;
    getWindow?: (w: number, h: number) => APLWindow;
    updateInterval?: number;
}
interface UseWindowedExposureReturn {
    setVideoElementRef: RefCallback<HTMLVideoElement>;
    setCanvasRef: RefCallback<HTMLCanvasElement>;
    setVideoTrackRef: (v: MediaStreamTrack | null) => void;
    setPaused: (paused: boolean) => void;
    paused: boolean;
}
declare function useWindowedExposure(options?: UseWindowedExposureOptions): UseWindowedExposureReturn;

declare function outline(detectedCodes: IDetectedBarcode[], ctx: CanvasRenderingContext2D): void;
declare function boundingBox(detectedCodes: IDetectedBarcode[], ctx: CanvasRenderingContext2D): void;
declare function centerText(detectedCodes: IDetectedBarcode[], ctx: CanvasRenderingContext2D): void;

export { type IBoundingBox, type IDetectedBarcode, type IPoint, type IScannerClassNames, type IScannerComponents, type IScannerProps, type IScannerStyles, type IStartCamera, type IStartTaskResult, type IStopTaskResult, type IUseScannerState, Scanner, type TrackFunction, boundingBox, centerText, outline, useDevices, useWindowedExposure };
