import { jsx as _jsx } from "react/jsx-runtime";
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, BarElement, Filler, Title, Tooltip, Legend, } from "chart.js";
import { Chart } from "react-chartjs-2";
import { formatterForUSD } from "../../../utils";
ChartJS.register(CategoryScale, Filler, LinearScale, BarElement, PointElement, LineElement, Title, Tooltip, Legend);
function BarLineChart({ values, view = "both", showLegend = true, valuesFormatter = formatterForUSD, barVariant = "dark", grace = "40%", aspectRatio = 4.5, startsFromZeroVariant = false, }) {
    const transformedValues = values.flatMap((item) => Object.keys(item).map((key) => ({ key: key, value: item[key] })));
    const transformedLabels = []; // this is the type defined in chartjs lib for labels as well
    transformedValues.forEach((value) => {
        transformedLabels.push([value.key.split("\n")]);
    });
    const maxValue = Math.max(...transformedValues.map((v) => v.value));
    const minVisiblePercentage = 0.07;
    const options = {
        responsive: true,
        aspectRatio: aspectRatio,
        maintainAspectRatio: true,
        scales: {
            y: {
                grace: grace,
                beginAtZero: true,
                border: {
                    color: "transparent",
                },
                grid: {
                    lineWidth: 2,
                    color: "#49494933",
                    tickColor: "transparent",
                },
                ticks: {
                    callback: function (value) {
                        const numericValue = typeof value === "string" ? parseInt(value, 10) : value;
                        return valuesFormatter.format(numericValue);
                    },
                    align: "start",
                    color: "#ADADAD",
                    count: 4,
                    font: {
                        family: "Rubik",
                        size: 14,
                        weight: 400,
                        lineHeight: "21px",
                    },
                },
            },
            x: {
                offset: startsFromZeroVariant ? false : true,
                grid: {
                    display: false,
                },
                ticks: {
                    color: "#868686",
                    font: {
                        family: "Rubik",
                        size: 14,
                        weight: 400,
                        lineHeight: "21px",
                    },
                },
            },
        },
        plugins: {
            legend: {
                display: showLegend,
                position: "bottom",
                align: "start",
                onClick: () => { },
                labels: {
                    boxHeight: 0,
                    boxWidth: 44,
                    padding: 20,
                    font: {
                        family: "Rubik",
                        size: 14,
                        weight: 400,
                        lineHeight: "21px",
                    },
                    generateLabels: () => {
                        return [
                            {
                                text: "Actual Data",
                                fillStyle: "transparent",
                                strokeStyle: "#FF8D4E",
                                fontColor: "#868686",
                                lineDash: [],
                            },
                            {
                                text: "Missing Data",
                                fillStyle: "transparent",
                                strokeStyle: "#FF8D4E",
                                fontColor: "#868686",
                                lineDash: [4, 8],
                            },
                        ];
                    },
                },
            },
            tooltip: {
                callbacks: {
                    title: function () {
                        return "";
                    },
                    label: function (context) {
                        if (startsFromZeroVariant && context.dataIndex === 0) {
                            return "";
                        }
                        if (context.dataset.type === "bar") {
                            const barDataset = context.dataset;
                            const realValue = barDataset.realData?.[context.dataIndex] ?? context.parsed.y;
                            return realValue ? valuesFormatter.format(realValue) : "$0";
                        }
                        if (context.dataset.type === "line") {
                            const lineDataset = context.dataset;
                            const realValue = lineDataset.realData?.[context.dataIndex] ?? context.parsed.y;
                            return realValue ? valuesFormatter.format(realValue) : "$0";
                        }
                    },
                },
                bodyColor: "#FF8D4E",
                bodyFont: {
                    family: "Inter",
                    size: 12,
                    weight: 300,
                    lineHeight: "18px",
                },
                displayColors: false,
                enabled: true,
                backgroundColor: "transparent",
                titleColor: "white",
                position: "nearest",
                xAlign: "center",
                yAlign: "bottom",
                bodySpacing: 10,
            },
            title: {
                display: false,
            },
            filler: {
                propagate: true,
            },
        },
    };
    const datasets = {
        labels: transformedLabels.flat(),
        datasets: [],
    };
    const lineData = {
        type: "line",
        data: transformedValues.map((val) => {
            const actualValue = val.value;
            return actualValue < maxValue * minVisiblePercentage && actualValue !== 0
                ? maxValue * minVisiblePercentage
                : actualValue;
        }),
        realData: transformedValues.map((val) => val.value),
        pointBackgroundColor: "#331C10",
        pointRadius: (context) => {
            if (startsFromZeroVariant) {
                return context.dataIndex === 0 ? 0 : 3;
            }
            return 3;
        },
        pointHoverRadius: (context) => {
            if (startsFromZeroVariant) {
                return context.dataIndex === 0 ? 0 : 4;
            }
            return 4;
        },
        backgroundColor: (context) => {
            const ctx = context.chart.ctx;
            const gradient = ctx.createLinearGradient(0, 0, 0, 200);
            gradient.addColorStop(0, "rgba(255, 141, 78, 0.2)");
            gradient.addColorStop(1, "rgba(35, 35, 35, 0)");
            return gradient;
        },
        borderColor: "#FF8D4E",
        borderCapStyle: "round",
        borderWidth: 1,
        fill: true,
        spanGaps: true,
        segment: {
            borderColor: (ctx) => {
                return ctx.p0.skip || ctx.p1.skip ? "#FF8D4E" : "#FF8D4E";
            },
            borderDash: (ctx) => {
                if (startsFromZeroVariant && ctx.p0DataIndex === 0)
                    return [5, 5];
                return ctx.p0.skip || ctx.p1.skip ? [5, 5] : [];
            },
        },
    };
    const barData = {
        type: "bar",
        data: transformedValues.map((val) => {
            const actualValue = val.value;
            // If the value is very small compared to max, boost it to minimum visible height
            return actualValue < maxValue * minVisiblePercentage && actualValue !== 0
                ? maxValue * minVisiblePercentage
                : actualValue;
        }),
        realData: transformedValues.map((val) => val.value),
        label: "",
        borderWidth: 1,
        backgroundColor: (context) => {
            if (barVariant === "dark")
                return "#4B4B4B";
            const ctx = context.chart.ctx;
            const gradient = ctx.createLinearGradient(0, 0, 0, 200);
            gradient.addColorStop(0, "rgba(255, 141, 78, 1)");
            gradient.addColorStop(1, "rgba(35, 35, 35, 0)");
            return gradient;
        },
        borderColor: barVariant === "dark" ? "#5E5E5E" : undefined,
        barThickness: 27,
        maxBarThickness: 27,
        hoverBorderColor: "#CC713E",
    };
    if (view === "line") {
        datasets.datasets.push(lineData);
    }
    else if (view === "bar") {
        datasets.datasets.push(barData);
    }
    else {
        datasets.datasets.push(lineData);
        datasets.datasets.push(barData);
    }
    return _jsx(Chart, { type: "line", id: "canvas", data: datasets, options: options });
}
export default BarLineChart;
