import type { ComponentProps, CSSProperties, ReactNode } from 'react';
import { ResponsiveContainer } from 'recharts';
import { cn } from '@/lib/utils';

export type ChartConfig = Record<
    string,
    {
        label?: ReactNode;
        color?: string;
    }
>;

type ChartContainerProps = ComponentProps<'div'> & {
    config: ChartConfig;
};

export function ChartContainer({
    className,
    config,
    children,
    ...props
}: ChartContainerProps) {
    const style = Object.entries(config).reduce(
        (styles, [key, value]) => {
            if (value.color) {
                styles[`--color-${key}`] = value.color;
            }

            return styles;
        },
        {} as Record<string, string>,
    );

    return (
        <div
            data-slot="chart"
            className={cn(
                'flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line]:stroke-border [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke="#fff"]]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none',
                className,
            )}
            style={style as CSSProperties}
            {...props}
        >
            <ResponsiveContainer>{children}</ResponsiveContainer>
        </div>
    );
}

type ChartTooltipContentProps = ComponentProps<'div'> & {
    active?: boolean;
    label?: string | number;
    payload?: Array<{
        name?: string;
        value?: number | string;
        color?: string;
    }>;
    valueFormatter?: (value: number | string) => string;
};

export function ChartTooltipContent({
    active,
    label,
    payload,
    className,
    valueFormatter = (value) => String(value),
}: ChartTooltipContentProps) {
    if (!active || !payload?.length) {
        return null;
    }

    return (
        <div
            className={cn(
                'grid min-w-32 gap-1.5 rounded-lg border bg-popover px-3 py-2 text-xs text-popover-foreground shadow-xl',
                className,
            )}
        >
            {label !== undefined && (
                <p className="font-medium text-foreground">{label}</p>
            )}
            {payload.map((item) => (
                <div
                    key={item.name}
                    className="flex items-center justify-between gap-3"
                >
                    <span className="flex items-center gap-1.5 text-muted-foreground">
                        <span
                            className="size-2 rounded-full"
                            style={{ backgroundColor: item.color }}
                        />
                        {item.name}
                    </span>
                    <span className="font-mono font-medium tabular-nums">
                        {valueFormatter(item.value ?? 0)}
                    </span>
                </div>
            ))}
        </div>
    );
}
