import { jsx, jsxs, Fragment } from "react/jsx-runtime";
import React__default from "react";
function getCSSVariableColor(variable) {
  if (typeof window === "undefined") {
    return variable;
  }
  const computed = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
  if (!computed) {
    return variable;
  }
  if (/^\d+\s+\d+\s+\d+$/.test(computed)) {
    return `rgb(${computed})`;
  }
  if (/^\d+deg\s+\d+%\s+\d+%$/.test(computed)) {
    return `hsl(${computed})`;
  }
  return computed;
}
const CHART_COLORS = {
  chart1: "--color-chart-1",
  chart2: "--color-chart-2",
  chart3: "--color-chart-3",
  chart4: "--color-chart-4",
  chart5: "--color-chart-5",
  chart6: "--color-chart-6"
};
function getDefaultChartColor(index) {
  const colorKeys = Object.values(CHART_COLORS);
  const colorVar = colorKeys[index % colorKeys.length];
  return getCSSVariableColor(colorVar);
}
function getDefaultChartColors() {
  return Object.values(CHART_COLORS).map(getCSSVariableColor);
}
function createColorGetter(customColors) {
  return (index) => {
    if (customColors && customColors[index]) {
      return customColors[index];
    }
    return getDefaultChartColor(index);
  };
}
function formatLargeNumber(value, locale = typeof navigator !== "undefined" ? navigator.language : "en-US", options) {
  const num = typeof value === "string" ? Number.parseFloat(value) : value;
  if (Number.isNaN(num)) {
    const str = String(value);
    if (/^\d{4}-\d{2}-\d{2}/.test(str)) {
      try {
        const date = new Date(str);
        return new Intl.DateTimeFormat(locale, {
          month: "short",
          day: "numeric"
        }).format(date);
      } catch {
        return str;
      }
    }
    return str;
  }
  const absNum = Math.abs(num);
  if (absNum >= 1e3) {
    return new Intl.NumberFormat(locale, {
      notation: "compact",
      compactDisplay: "short",
      maximumFractionDigits: 1,
      ...options
    }).format(num);
  }
  return new Intl.NumberFormat(locale, {
    maximumFractionDigits: 2,
    ...options
  }).format(num);
}
function truncateText(text, maxLength, locale = typeof navigator !== "undefined" ? navigator.language : "en-US", preferWordBoundary = true) {
  if (!text) return "";
  const str = String(text);
  if (str.length <= maxLength) return str;
  if (maxLength <= 3) return "…";
  if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
    try {
      if (preferWordBoundary) {
        const IntlSegmenter = Intl.Segmenter;
        const segmenter = new IntlSegmenter(locale, { granularity: "word" });
        const segments = Array.from(segmenter.segment(str));
        let result = "";
        let currentLength = 0;
        for (const segment of segments) {
          const segmentTyped = segment;
          const nextLength = currentLength + segmentTyped.segment.length;
          if (nextLength > maxLength - 1) {
            if (result === "") {
              return truncateByGrapheme(str, maxLength, locale);
            }
            return result.trim() + "…";
          }
          result += segmentTyped.segment;
          currentLength = nextLength;
        }
        return result;
      } else {
        return truncateByGrapheme(str, maxLength, locale);
      }
    } catch {
      console.warn("Intl.Segmenter failed, using fallback truncation");
    }
  }
  const truncated = str.substring(0, maxLength - 1);
  const lastSpace = truncated.lastIndexOf(" ");
  if (preferWordBoundary && lastSpace > maxLength * 0.7) {
    return truncated.substring(0, lastSpace) + "…";
  }
  return truncated + "…";
}
function truncateByGrapheme(text, maxLength, locale) {
  if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
    try {
      const IntlSegmenter = Intl.Segmenter;
      const segmenter = new IntlSegmenter(locale, { granularity: "grapheme" });
      const segments = Array.from(segmenter.segment(text));
      let result = "";
      let count = 0;
      for (const segment of segments) {
        if (count >= maxLength - 1) break;
        const segmentTyped = segment;
        result += segmentTyped.segment;
        count++;
      }
      return result + "…";
    } catch {
      return text.substring(0, maxLength - 1) + "…";
    }
  }
  return text.substring(0, maxLength - 1) + "…";
}
function detectLabelType(label) {
  const str = String(label).trim();
  if (/^\d{4}-\d{2}-\d{2}/.test(str)) return "date";
  if (/^[\$€£¥₹]/.test(str) || /[\$€£¥₹]$/.test(str)) return "currency";
  if (/^-?\d+(\.\d+)?$/.test(str)) return "number";
  return "text";
}
function formatLabel(label, locale = typeof navigator !== "undefined" ? navigator.language : "en-US") {
  const type = detectLabelType(label);
  switch (type) {
    case "number":
      return formatLargeNumber(label, locale);
    case "date":
      try {
        const date = new Date(label);
        if (!Number.isNaN(date.getTime())) {
          return new Intl.DateTimeFormat(locale, {
            month: "short",
            day: "numeric",
            year: "2-digit"
          }).format(date);
        }
      } catch {
      }
      return label;
    case "currency": {
      const match = label.match(/([$€£¥₹])?([\d,.]+)([$€£¥₹])?/);
      if (match) {
        const [, prefix, num, suffix] = match;
        const symbol = prefix || suffix || "$";
        const value = Number.parseFloat(num.replaceAll(",", ""));
        if (!Number.isNaN(value)) {
          return formatLargeNumber(value, locale, {
            style: "currency",
            currency: symbol === "$" ? "USD" : symbol === "€" ? "EUR" : symbol === "£" ? "GBP" : "USD",
            notation: value >= 1e3 ? "compact" : "standard"
          });
        }
      }
      return label;
    }
    default:
      return label;
  }
}
function calculateLabelSettings(labels, availableWidth = 800, locale = typeof navigator !== "undefined" ? navigator.language : "en-US") {
  if (!labels || labels.length === 0) {
    return {
      angle: 0,
      fontSize: 10,
      truncateLength: 0,
      showTooltip: false,
      formatLabels: false,
      locale
    };
  }
  const labelTypes = labels.map((label) => detectLabelType(String(label)));
  const hasNumbers = labelTypes.includes("number");
  const hasDates = labelTypes.includes("date");
  const hasCurrency = labelTypes.includes("currency");
  const shouldFormat = hasNumbers || hasDates || hasCurrency;
  const formattedLabels = shouldFormat ? labels.map((label) => formatLabel(String(label), locale)) : labels.map(String);
  const maxLength = Math.max(...formattedLabels.map((label) => label.length));
  const labelCount = labels.length;
  const avgWidthPerLabel = availableWidth / labelCount;
  const getPixelWidth = (text, fontSize2) => {
    let width = 0;
    for (const char of text) {
      if (/[iltrf1\.]/.test(char)) width += fontSize2 * 0.35;
      else if (/[wmWM]/.test(char)) width += fontSize2 * 0.8;
      else if (/[0-9]/.test(char)) width += fontSize2 * 0.55;
      else if (/[A-Z]/.test(char)) width += fontSize2 * 0.65;
      else width += fontSize2 * 0.5;
    }
    return width;
  };
  let angle = 0;
  let fontSize = 10;
  let truncateLength = 0;
  let showTooltip = false;
  const maxPixelWidth = getPixelWidth(
    formattedLabels.reduce((a, b) => a.length > b.length ? a : b, ""),
    fontSize
  );
  const spacePerLabel = avgWidthPerLabel - 8;
  const spaceRatio = maxPixelWidth / spacePerLabel;
  if (spaceRatio <= 0.8) {
    angle = 0;
    fontSize = 10;
    truncateLength = 0;
    showTooltip = false;
  } else if (spaceRatio <= 1.2) {
    angle = 0;
    fontSize = 10;
    truncateLength = 0;
    showTooltip = false;
  } else if (spaceRatio <= 1.8) {
    angle = -30;
    fontSize = 10;
    truncateLength = 0;
    showTooltip = false;
  } else if (spaceRatio <= 2.5) {
    angle = -45;
    fontSize = 9;
    const maxCharsAtAngle = Math.floor(
      spacePerLabel * 1.4 / (fontSize * 0.5)
    );
    truncateLength = maxLength > maxCharsAtAngle ? maxCharsAtAngle : 0;
    showTooltip = truncateLength > 0 && truncateLength < maxLength;
  } else {
    angle = -45;
    fontSize = 9;
    const maxCharsAtAngle = Math.floor(
      spacePerLabel * 1.4 / (fontSize * 0.5)
    );
    truncateLength = Math.min(20, maxCharsAtAngle);
    showTooltip = true;
  }
  if (hasNumbers && !hasDates && !hasCurrency) {
    if (maxLength > 6) {
      angle = Math.min(angle, -30);
      showTooltip = true;
    }
  }
  if (hasDates) {
    angle = Math.min(angle, -30);
    fontSize = Math.max(fontSize, 9);
  }
  return {
    angle,
    fontSize,
    truncateLength,
    showTooltip,
    formatLabels: shouldFormat,
    locale
  };
}
function CustomXAxisTick({
  x,
  y,
  payload,
  angle = 0,
  fontSize = 10,
  truncateLength = 0,
  showTooltip = false,
  formatLabels = false,
  locale = typeof navigator !== "undefined" ? navigator.language : "en-US"
}) {
  const originalText = String(payload.value);
  const formattedText = formatLabels ? formatLabel(originalText, locale) : originalText;
  const displayText = truncateLength > 0 ? truncateText(formattedText, truncateLength, locale, true) : formattedText;
  const isTruncated = truncateLength > 0 && formattedText.length > truncateLength;
  const needsTooltip = isTruncated || showTooltip || formattedText !== originalText;
  let textAnchor = "middle";
  let dx = 0;
  let dy = 12;
  if (angle < 0) {
    textAnchor = "end";
    dx = -4;
    dy = 4;
  }
  const textElement = /* @__PURE__ */ jsx(
    "text",
    {
      x: dx,
      y: dy,
      fill: "hsl(var(--text-tertiary))",
      fontSize,
      textAnchor,
      transform: `rotate(${angle})`,
      className: "select-none",
      children: displayText
    }
  );
  return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: needsTooltip ? /* @__PURE__ */ jsxs(Fragment, { children: [
    textElement,
    /* @__PURE__ */ jsx(
      "rect",
      {
        x: angle < 0 ? dx - 30 : dx - 20,
        y: dy - 10,
        width: angle < 0 ? 60 : 40,
        height: 20,
        fill: "transparent",
        style: { cursor: "help" },
        children: /* @__PURE__ */ jsx("title", { children: originalText !== formattedText ? `${originalText}
${formattedText}` : originalText })
      }
    ),
    isTruncated && /* @__PURE__ */ jsx(
      "text",
      {
        x: dx + (angle < 0 ? -2 : 15),
        y: dy,
        fill: "hsl(var(--text-tertiary))",
        fontSize: fontSize * 0.8,
        opacity: 0.5,
        textAnchor: angle < 0 ? "start" : "start",
        transform: `rotate(${angle})`,
        children: "⋯"
      }
    )
  ] }) : textElement });
}
function CustomYAxisTick({
  x,
  y,
  payload,
  fontSize = 10,
  truncateLength = 20,
  formatLabels = false,
  locale = typeof navigator !== "undefined" ? navigator.language : "en-US"
}) {
  const [isHovered, setIsHovered] = React__default.useState(false);
  const originalText = String(payload.value);
  const formattedText = formatLabels ? formatLabel(originalText, locale) : originalText;
  const displayText = truncateLength > 0 ? truncateText(formattedText, truncateLength, locale, true) : formattedText;
  const isTruncated = truncateLength > 0 && formattedText.length > truncateLength;
  const needsTooltip = isTruncated || formattedText !== originalText;
  const textElement = /* @__PURE__ */ jsx(
    "text",
    {
      x: -8,
      y: 4,
      fill: "hsl(var(--text-tertiary))",
      fontSize,
      textAnchor: "end",
      className: "select-none",
      style: {
        fontWeight: isHovered ? 500 : 400,
        transition: "font-weight 0.15s ease"
      },
      children: displayText
    }
  );
  return /* @__PURE__ */ jsx(
    "g",
    {
      transform: `translate(${x},${y})`,
      onMouseEnter: () => setIsHovered(true),
      onMouseLeave: () => setIsHovered(false),
      children: needsTooltip ? /* @__PURE__ */ jsxs(Fragment, { children: [
        textElement,
        /* @__PURE__ */ jsx(
          "rect",
          {
            x: -150,
            y: -8,
            width: 142,
            height: 16,
            fill: "transparent",
            style: { cursor: "help" },
            children: /* @__PURE__ */ jsx("title", { children: originalText !== formattedText ? `${originalText}
${formattedText}` : originalText })
          }
        ),
        isTruncated && /* @__PURE__ */ jsx(
          "text",
          {
            x: -6,
            y: 4,
            fill: "hsl(var(--text-tertiary))",
            fontSize: fontSize * 0.8,
            opacity: 0.5,
            textAnchor: "start",
            children: "⋯"
          }
        )
      ] }) : textElement
    }
  );
}
const renderCustomLegend = (props) => {
  const { payload } = props;
  if (!payload || !Array.isArray(payload)) {
    return null;
  }
  const filteredPayload = payload.filter((entry) => entry.type !== "none");
  return /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap items-center justify-start gap-4 text-xs text-secondary", children: filteredPayload.map((entry, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-1.5", children: [
    /* @__PURE__ */ jsx(
      "span",
      {
        className: "inline-block h-2 w-2 rounded-xs",
        style: { backgroundColor: entry.color || "#000" }
      }
    ),
    /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: entry.value })
  ] }, `item-${index}`)) });
};
const defaultLegendProps = {
  content: renderCustomLegend,
  verticalAlign: "top",
  align: "left",
  wrapperStyle: {
    paddingBottom: "20px"
  }
};
const defaultChartMargin = {
  top: 12,
  right: 3,
  left: 2,
  bottom: 8
};
function getChartMargin(showLegend = false) {
  return {
    ...defaultChartMargin,
    top: showLegend ? 0 : defaultChartMargin.top
  };
}
function extractDataRange(data, configKeys) {
  if (!data || data.length === 0 || !configKeys || configKeys.length === 0) {
    return null;
  }
  const allValues = [];
  for (const item of data) {
    for (const key of configKeys) {
      const value = item[key];
      if (typeof value === "number" && !Number.isNaN(value)) {
        allValues.push(value);
      }
    }
  }
  if (allValues.length === 0) {
    return null;
  }
  return {
    min: Math.min(...allValues),
    max: Math.max(...allValues)
  };
}
function calculateYAxisWidth(minValue, maxValue, fontSize = 10) {
  if (minValue === void 0 || maxValue === void 0) {
    return 50;
  }
  const getPixelWidth = (text, fontSize2) => {
    let width = 0;
    for (const char of text) {
      if (/[wmWM]/.test(char)) {
        width += fontSize2 * 0.85;
      } else if (/[kK]/.test(char)) {
        width += fontSize2 * 0.55;
      } else if (/[0-9]/.test(char)) {
        width += fontSize2 * 0.6;
      } else if (/[A-Z]/.test(char)) {
        width += fontSize2 * 0.7;
      } else if (/[iltrf\.]/.test(char)) {
        width += fontSize2 * 0.4;
      } else if (char === "-") {
        width += fontSize2 * 0.5;
      } else {
        width += fontSize2 * 0.55;
      }
    }
    return width;
  };
  const testValues = [minValue, maxValue];
  if (minValue <= 0 && maxValue >= 0) {
    testValues.push(0);
  }
  const range = maxValue - minValue;
  if (range > 0) {
    testValues.push(minValue + range * 0.25);
    testValues.push(minValue + range * 0.5);
    testValues.push(minValue + range * 0.75);
  }
  const formattedLabels = testValues.map(
    (val) => defaultYAxisTickFormatter(val)
  );
  const longestLabel = formattedLabels.reduce(
    (a, b) => a.length > b.length ? a : b
  );
  const labelWidth = getPixelWidth(longestLabel, fontSize);
  const padding = 12;
  return Math.ceil(labelWidth + padding);
}
const defaultYAxisWidth = 60;
const defaultYAxisTickFormatter = (value) => {
  const locale = typeof navigator !== "undefined" ? navigator.language : "en-US";
  const num = typeof value === "string" ? Number.parseFloat(value) : value;
  if (Number.isNaN(num)) return String(value);
  if (Math.abs(num) >= 1e3) {
    return new Intl.NumberFormat(locale, {
      notation: "compact",
      compactDisplay: "short",
      maximumFractionDigits: 1
    }).format(num);
  }
  return new Intl.NumberFormat(locale, {
    maximumFractionDigits: 0
  }).format(num);
};
const defaultGridProps = {
  stroke: "hsl(var(--text-secondary))",
  strokeWidth: 1,
  strokeOpacity: 0.5,
  strokeDasharray: "0.25 4",
  strokeLinecap: "round",
  strokeLinejoin: "bevel",
  vertical: false
};
export {
  CHART_COLORS,
  CustomXAxisTick,
  CustomYAxisTick,
  calculateLabelSettings,
  calculateYAxisWidth,
  createColorGetter,
  defaultChartMargin,
  defaultGridProps,
  defaultLegendProps,
  defaultYAxisTickFormatter,
  defaultYAxisWidth,
  extractDataRange,
  formatLargeNumber,
  getCSSVariableColor,
  getChartMargin,
  getDefaultChartColor,
  getDefaultChartColors,
  renderCustomLegend,
  truncateText
};
