import { CSSProperties } from 'react';
import { DOMAttributes } from 'react';
import { ForwardedRef } from 'react';
import { JSX } from 'react/jsx-runtime';
import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { RefObject } from 'react';
import { SVGProps } from 'react';

declare type ActiveBar = CSSProperties | boolean;

declare type Axes = {
    [key: string | number]: Axis;
};

declare interface Axis {
    id: number | string;
    min: number;
    max: number;
    xAxis: {
        domain: number[];
        range: number[];
    };
    yAxis: {
        domain: number[];
        range: number[];
    };
    getX: (x: number) => number;
    getY: (y: number | null | number[]) => number | number[];
    getPoint: (point: [number, number | null | number[]]) => [number, number | number[]];
}

export declare const Band: {
    <TData>(props: BandProps<TData>): JSX.Element | null;
    displayName: string;
};

export declare type BandProps<TData> = Omit<PresentationAttributesWithProps<SVGPathElement>, "points"> & BandShapeExtraProps & InternalShapeProps<TData>;

declare interface BandShapeExtraProps extends ShapeProps {
    dots?: LineDot;
    activeDot?: LineDot;
    curved?: boolean | number;
    connectNulls?: boolean;
}

declare type BandShapeProps = Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "width" | "height"> & BandShapeExtraProps;

export declare const Bar: {
    <TData>(props: BarProps<TData>): JSX.Element | null;
    displayName: string;
};

export declare type BarProps<TData> = Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "radius"> & BarShapeProps & InternalShapeProps<TData>;

declare interface BarShapeExtraProps extends ShapeProps {
    radius?: SparklinesRadius;
    activeBar?: ActiveBar;
    barWidth?: number;
    maxBarWidth?: number;
    barGap?: number | string;
    positive?: Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "radius" | "width" | "height"> & {
        radius?: SparklinesRadius;
    };
    negative?: Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "radius" | "width" | "height"> & {
        radius?: SparklinesRadius;
    };
}

declare type BarShapeProps = Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "radius" | "width" | "height"> & BarShapeExtraProps;

declare type DataKey = string | number;

declare interface DotProps extends SVGProps<SVGCircleElement> {
    className?: string;
    cx?: number;
    cy?: number;
    r?: number;
    dot?: ReactElement<SVGElement> | ((props: DotProps) => ReactElement<SVGElement>);
    show?: LineDotsVisibility;
    color?: string;
}

declare interface InternalShapeProps<TData> {
    sparklineData?: UseSparklineData<TData>;
    data?: SparklineData<TData>;
    width?: number;
    height?: number;
    margin?: SparklinesMargin;
    withBarAdjustment?: boolean;
    activeIndex?: number | null;
    clipPathId?: string;
    tooltip?: boolean;
    startAtZero?: boolean;
    zeroBaseline?: boolean;
}

export declare const Line: {
    <TData>(props: LineProps<TData>): JSX.Element | null;
    displayName: string;
};

declare type LineDot = ReactElement<SVGElement> | ((props: DotProps) => ReactElement<SVGElement>) | DotProps | boolean | undefined | null;

declare type LineDotsVisibility = "START" | "END" | "START_END" | boolean;

export declare type LineProps<TData> = Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name"> & LineShapeProps & InternalShapeProps<TData>;

declare interface LineShapeExtraProps extends ShapeProps {
    dots?: LineDot;
    activeDot?: LineDot;
    curved?: boolean | number;
    connectNulls?: boolean;
}

declare type LineShapeProps = Omit<PresentationAttributesWithProps<SVGPathElement>, "points" | "name" | "width" | "height"> & LineShapeExtraProps;

declare type Margin = {
    top: number;
    right: number;
    bottom: number;
    left: number;
};

declare type PresentationAttributesWithProps<T> = Omit<SVGProps<T>, keyof DOMAttributes<T>>;

export declare const ReferenceLine: <TData>({ x, y, data, ...rest }: ReferenceLineProps<TData>) => JSX.Element | null;

declare interface ReferenceLineExtraProps extends ShapeProps {
    x?: number | string;
    y?: number;
}

export declare type ReferenceLineProps<TData> = Omit<PresentationAttributesWithProps<SVGLineElement>, "points"> & ReferenceLineExtraProps & InternalShapeProps<TData>;

declare interface ShapeProps {
    dataKey?: DataKey;
    style?: CSSProperties;
    labelColor?: string;
    name?: string;
    axis?: string | number;
}

declare interface SparklineData<TData> {
    dataKey: DataKey;
    color: string;
    axis: Axis;
    entries: SparklineDataEntry<TData>[];
    values: (number | number[] | null)[];
    points: [number, number | null | number[]][];
    pointsDefined: [number, number | number[]][];
    coords: [number, number | number[]][];
}

declare interface SparklineDataEntry<TData> {
    label: any;
    dataKey: DataKey;
    x: number;
    y: number | null | number[];
    index: number;
    original: TData;
    color: string;
}

declare interface SparklineOptions {
    max?: number;
    min?: number;
    startAtZero?: boolean;
    zeroBaseline?: boolean;
    withBarAdjustment?: boolean;
    limit?: number;
    height: number;
    width: number;
    margin: Margin;
}

export declare const SparklinesBand: <TData>(props: SparklinesLineProps<TData> & {
    ref?: ForwardedRef<SVGRectElement>;
}) => ReturnType<typeof SparklinesBandInner>;

declare const SparklinesBandInner: <TData>({ height, max, width, withBarAdjustment, children, preserveAspectRatio, min, margin, limit, style, data, dataKey, dots, curved, activeDot, name, label, clip, labelColor, responsive, onMouseMove, onMouseEnter, onMouseLeave, onClick, startAtZero, zeroBaseline, connectNulls, ...rest }: SparklinesBandProps<TData>, ref: ForwardedRef<SVGRectElement>) => JSX.Element;

export declare type SparklinesBandProps<TData> = SparklinesComposedProps<TData> & BandShapeProps;

export declare const SparklinesBar: <TData>(props: SparklinesBarProps<TData> & {
    ref?: ForwardedRef<SVGRectElement>;
}) => ReturnType<typeof SparklinesBarInner>;

declare const SparklinesBarInner: <TData>({ height, activeBar, barWidth, maxBarWidth, barGap, max, width, withBarAdjustment, children, radius, preserveAspectRatio, min, margin, limit, style, data, dataKey, clip, name, label, responsive, onMouseMove, onMouseEnter, onMouseLeave, labelColor, onClick, startAtZero, zeroBaseline, positive, negative, ...rest }: SparklinesBarProps<TData>, ref: ForwardedRef<SVGRectElement>) => JSX.Element;

export declare type SparklinesBarProps<TData> = SparklinesComposedProps<TData> & BarShapeProps;

export declare const SparklinesComposed: <TData>(props: SparklinesComposedProps<TData> & {
    ref?: ForwardedRef<SVGRectElement>;
}) => ReturnType<typeof SparklinesComposedInner>;

declare const SparklinesComposedInner: <TData>({ data, width, height, margin, children, max, min, limit, preserveAspectRatio, responsive, style, label, withBarAdjustment, clip, startAtZero, onMouseMove, onMouseEnter, onMouseLeave, onClick, zeroBaseline, ...rest }: SparklinesComposedProps<TData>, ref: ForwardedRef<SVGRectElement>) => JSX.Element;

export declare interface SparklinesComposedProps<TData> {
    margin?: SparklinesMargin;
    min?: number;
    max?: number;
    data?: TData[];
    limit?: number;
    width?: number;
    height?: number;
    preserveAspectRatio?: string;
    responsive?: boolean;
    style?: CSSProperties;
    withBarAdjustment?: boolean;
    label?: ReactNode;
    children?: any;
    clip?: boolean;
    startAtZero?: boolean;
    zeroBaseline?: boolean;
    onMouseMove?: (event: MouseEvent, data: SparklinesEventData<TData>) => void;
    onMouseLeave?: (event: MouseEvent, data: SparklinesEventData<TData>) => void;
    onMouseEnter?: (event: MouseEvent, data: SparklinesEventData<TData>) => void;
    onClick?: (event: MouseEvent, data: SparklinesEventData<TData>) => void;
}

export declare interface SparklinesDataEntry<TData> {
    dataKey: DataKey;
    x: number;
    y: number;
    value: number | null;
    index: number;
    entry: TData;
    color: string;
}

export declare interface SparklinesEventData<TData> {
    activeIndex: number | null;
    activeEntry: SparklineDataEntry<TData>[];
}

export declare const SparklinesLine: <TData>(props: SparklinesLineProps<TData> & {
    ref?: ForwardedRef<SVGRectElement>;
}) => ReturnType<typeof SparklinesLineInner>;

declare const SparklinesLineInner: <TData>({ height, max, width, withBarAdjustment, children, preserveAspectRatio, min, margin, limit, style, data, dataKey, dots, curved, activeDot, name, label, clip, labelColor, responsive, onMouseMove, onMouseEnter, onMouseLeave, onClick, startAtZero, zeroBaseline, connectNulls, ...rest }: SparklinesLineProps<TData>, ref: ForwardedRef<SVGRectElement>) => JSX.Element;

export declare type SparklinesLineProps<TData> = SparklinesComposedProps<TData> & LineShapeProps;

declare type SparklinesMargin = number | Partial<{
    top: number;
    right: number;
    bottom: number;
    left: number;
}>;

declare type SparklinesRadius = number | Partial<{
    topLeft: number;
    topRight: number;
    bottomLeft: number;
    bottomRight: number;
}>;

export declare const Tooltip: {
    (props: TooltipProps): JSX.Element;
    displayName: string;
};

declare type TooltipContent = ReactElement | ((props: TooltipProps) => ReactNode) | undefined;

export declare interface TooltipPayload {
    name?: DataKey;
    value?: number | null | number[];
    dataKey?: DataKey;
    color?: string;
}

export declare interface TooltipProps {
    content?: TooltipContent;
    contentStyle?: CSSProperties;
    coords?: {
        x: number;
        y: number;
    };
    itemStyle?: CSSProperties;
    label?: ReactNode;
    labelStyle?: CSSProperties;
    payload?: Array<TooltipPayload>;
    separator?: string;
    wrapperStyle?: CSSProperties;
    formatter?: (payload: TooltipPayload) => ReactNode;
}

export declare function useContainerWidth({ enabled, defaultWidth, }: UseContainerWidthOptions): UseContainerWidthResult;

declare interface UseContainerWidthOptions {
    enabled: boolean;
    defaultWidth: number;
}

declare interface UseContainerWidthResult {
    containerRef: RefObject<HTMLDivElement | null>;
    width: number;
    isReady: boolean;
}

declare interface UseSparklineData<TData> {
    originalData: TData[];
    dataKeys: DataKey[];
    labels: (ReactNode | ((data: any) => ReactNode))[];
    axes: Axes;
    options: SparklineOptions;
    sparklines: SparklineData<TData>[];
}

export { }
