import { cn } from '@/lib/utils';

export type MonthChartPoint = {
    label: string;
    projectedUsd: number;
    actualUsd: number | null;
};

function finiteUsd(value: number): number {
    return typeof value === 'number' && Number.isFinite(value) ? value : 0;
}

/** Abrevia etiquetas largas del eje X del gráfico. */
function abbreviateChartLabel(label: string): string {
    const segments = label.split(' – ');
    if (segments.length === 2) {
        return `${abbreviateChartSegment(segments[0])}–${abbreviateChartSegment(segments[1])}`;
    }

    return abbreviateChartSegment(label);
}

function abbreviateChartSegment(segment: string): string {
    const match = segment.trim().match(/^(\S+)\s+(\d+(?:-\d+)?)$/u);
    if (!match) {
        return segment.length > 12 ? `${segment.slice(0, 11)}…` : segment;
    }

    return `${match[1].slice(0, 3)} ${match[2]}`;
}

/** Gráfico de barras en SVG (proyectado vs acreditado) por mes — sin deps externas. */
export function MonthlyGainsChart({ data }: { data: MonthChartPoint[] }) {
    if (data.length === 0) {
        return (
            <p className="text-sm text-muted-foreground">
                Sin períodos configurados.
            </p>
        );
    }

    const plotW = 480;
    const plotH = 168;
    const padL = 48;
    const padR = 16;
    const padT = 20;
    const padB = 36;
    const innerW = plotW - padL - padR;
    const innerH = plotH - padT - padB;

    const maxUsd = Math.max(
        ...data.flatMap((d) => [
            finiteUsd(d.projectedUsd),
            finiteUsd(d.actualUsd ?? 0),
        ]),
        1,
    );

    const baselineY = padT + innerH;

    const n = data.length;
    const gapfrac = 0.14;
    const barPairW = innerW / Math.max(n, 1);
    const singleBarW =
        barPairW *
        ((1 - gapfrac * 3) /
            2);

    return (
        <div className="space-y-3">
            <div className="overflow-x-auto">
                <svg
                    aria-label="Comparativa de ganancia mensual proyectada y acreditada"
                    className="min-h-[220px] min-w-[500px] w-full max-w-[640px] text-muted-foreground"
                    role="img"
                    viewBox={`0 0 ${plotW} ${plotH}`}
                    preserveAspectRatio="xMidYMid meet"
                >
                    <text
                        className="fill-muted-foreground"
                        fontSize={10}
                        x={padL}
                        y={padT - 6}
                    >
                        Máximo {maxUsd.toFixed(0)} US$ en el período
                    </text>

                    {/* Eje */}
                    <line
                        className="stroke-border"
                        strokeWidth={1}
                        x1={padL}
                        x2={plotW - padR}
                        y1={baselineY}
                        y2={baselineY}
                    />
                    <line
                        className="stroke-border opacity-40"
                        strokeWidth={1}
                        x1={padL}
                        x2={padL}
                        y1={padT}
                        y2={baselineY}
                    />

                    {data.map((point, index) => {
                        const pUsd = finiteUsd(point.projectedUsd);

                        const gx = padL + index * barPairW + barPairW * gapfrac;
                        const xP = gx;
                        const xA = gx + singleBarW + barPairW * gapfrac;

                        const hp = innerH * (pUsd / maxUsd) * 0.98;
                        const yp = baselineY - Math.max(hp, 3);

                        const has = point.actualUsd !== null;
                        const av = finiteUsd(point.actualUsd ?? 0);
                        const ha = has ? innerH * (av / maxUsd) * 0.98 : 0;
                        const ya = has ? baselineY - Math.max(ha, 3) : baselineY;

                        return (
                            <g key={point.label}>
                                <title>{`${point.label} — proyectado US$ ${pUsd.toFixed(2)}; acreditado ${has ? `US$ ${av.toFixed(2)}` : 'sin registrar'}`}</title>
                                <rect
                                    className="fill-muted-foreground/45"
                                    height={baselineY - yp}
                                    rx={5}
                                    width={singleBarW}
                                    x={xP}
                                    y={yp}
                                />
                                <rect
                                    className={cn(
                                        has
                                            ? 'fill-primary'
                                            : 'fill-transparent stroke-border opacity-55',
                                    )}
                                    height={has ? Math.max(baselineY - ya, 3) : 2}
                                    rx={5}
                                    strokeDasharray={has ? undefined : '2 4'}
                                    width={singleBarW}
                                    x={xA}
                                    y={
                                        has
                                            ? ya
                                            : baselineY - 2
                                    }
                                />
                                <text
                                    className="fill-muted-foreground"
                                    dominantBaseline="hanging"
                                    fontSize={9}
                                    textAnchor="middle"
                                    x={gx + barPairW / 2 - barPairW * gapfrac / 2}
                                    y={baselineY + 6}
                                >
                                    {abbreviateChartLabel(point.label)}
                                </text>
                            </g>
                        );
                    })}
                </svg>
            </div>

            <div className="flex flex-wrap gap-x-6 gap-y-2 text-xs text-muted-foreground">
                <span className="inline-flex items-center gap-2">
                    <span className="inline-block size-3 rounded-sm bg-muted-foreground/45" />{' '}
                    Proyectado (plan pactado sobre capital).
                </span>
                <span className="inline-flex items-center gap-2">
                    <span className="inline-block size-3 rounded-sm bg-primary" />{' '}
                    Acreditado (suma de días en ese mes calendario).
                </span>
            </div>
        </div>
    );
}
