import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { useState, useRef, useMemo, useEffect } from 'react';
import { useReducedMotion, motion } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { donutChartTheme } from './DonutChart.theme.js';
import { getSpringAnimation, CIRCULAR_CHART_ANIMATIONS, getStaggerDelay } from '../utils/animation-utils.js';
import { resolveCssVariable, describeRingSegmentPath, interpolateHexColor, clamp } from './donut-utils.js';

/**
 * DonutChart component for displaying a percentage value with a circular progress indicator
 * Supports customization of size, thickness, animations, and theming
 */
const DonutChart = ({ variant = "solid", percentage, label, subtitle, size = 200, thickness = 2, segmentCount = 32, segmentGap = 0.35, showAnimation = true, className, children, theme: themeOverrides, colors, onAnimationStart, onAnimationEnd, onDrag, onDragStart, onDragEnd, ...props }) => {
    var _a, _b;
    const [isHovered, setIsHovered] = useState(false);
    const [hasAnimated, setHasAnimated] = useState(false);
    const shouldReduceMotion = useReducedMotion();
    const containerRef = useRef(null);
    const isSegmentedVariant = variant === "segmented";
    // Ensure percentage is between 0-100
    const safePercentage = Math.min(Math.max(0, percentage), 100);
    // Calculate SVG parameters - SIMPLE AND CLEAN
    const svgSize = 100;
    const center = svgSize / 2;
    const strokeWidth = thickness * 2;
    const radius = (svgSize - strokeWidth) / 2;
    const innerRadius = Math.max(0, radius - strokeWidth / 2);
    const outerRadius = radius + strokeWidth / 2;
    const circumference = 2 * Math.PI * radius;
    // Calculate progress - start from 0, animate to target
    const progressOffset = circumference - (safePercentage / 100) * circumference;
    // Merge theme with overrides
    const theme = {
        ...donutChartTheme,
        ...(themeOverrides || {}),
    };
    // Generate stable gradient ID based on component instance
    const gradientId = useMemo(() => `donut-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
    // Determine colors based on props or theme - simplified logic
    // Resolves CSS variables to computed values for SVG attribute compatibility
    const getColors = useMemo(() => {
        var _a, _b;
        // If colors prop has both from and to, use gradient
        if ((colors === null || colors === void 0 ? void 0 : colors.from) && (colors === null || colors === void 0 ? void 0 : colors.to)) {
            return {
                type: "gradient",
                from: resolveCssVariable(colors.from),
                to: resolveCssVariable(colors.to),
            };
        }
        // If colors prop has primary, use solid color
        if (colors === null || colors === void 0 ? void 0 : colors.primary) {
            return {
                type: "solid",
                color: resolveCssVariable(colors.primary),
            };
        }
        // Use theme defaults (gradient) - resolve CSS variables
        const primaryColor = resolveCssVariable(((_a = theme.colors) === null || _a === void 0 ? void 0 : _a.primary) || "", "#3b82f6");
        const secondaryColor = resolveCssVariable(((_b = theme.colors) === null || _b === void 0 ? void 0 : _b.secondary) || "", "#10b981");
        return {
            type: "gradient",
            from: primaryColor,
            to: secondaryColor,
        };
    }, [colors, theme.colors]);
    const segmentDefinitions = useMemo(() => {
        if (!isSegmentedVariant) {
            return [];
        }
        const totalSegments = Math.max(1, Math.floor(segmentCount));
        const gapRatio = clamp(segmentGap, 0, 0.8);
        const baseAngle = 360 / totalSegments;
        const gapAngle = baseAngle * gapRatio;
        const arcAngle = Math.max(0, baseAngle - gapAngle);
        const rotationOffset = 0 - gapAngle / 2; // Start at 12 o'clock (0 degrees)
        const activeValue = (safePercentage / 100) * totalSegments;
        const fullSegments = Math.floor(activeValue);
        const partialSegmentProgress = activeValue - fullSegments;
        return Array.from({ length: totalSegments }, (_, index) => {
            const startAngle = rotationOffset + index * baseAngle + gapAngle / 2;
            const endAngle = startAngle + arcAngle;
            const colorFactor = totalSegments === 1 ? 0 : index / (totalSegments - 1);
            const isFullActive = index < fullSegments;
            const isPartialActive = !isFullActive && index === fullSegments && partialSegmentProgress > 0;
            const activeSweep = isFullActive
                ? arcAngle
                : isPartialActive
                    ? arcAngle * partialSegmentProgress
                    : 0;
            return {
                trackPath: describeRingSegmentPath(center, center, innerRadius, outerRadius, startAngle, endAngle),
                activePath: activeSweep > 0
                    ? describeRingSegmentPath(center, center, innerRadius, outerRadius, startAngle, startAngle + activeSweep)
                    : null,
                colorFactor,
            };
        });
    }, [
        center,
        innerRadius,
        isSegmentedVariant,
        outerRadius,
        safePercentage,
        segmentCount,
        segmentGap,
    ]);
    // Handle component mount for animation
    useEffect(() => {
        if (showAnimation && !shouldReduceMotion) {
            setHasAnimated(true);
        }
        else {
            // If animations disabled, immediately show final state
            setHasAnimated(true);
        }
    }, [showAnimation, shouldReduceMotion]);
    // Handle hover interactions
    const handleMouseEnter = () => setIsHovered(true);
    const handleMouseLeave = () => setIsHovered(false);
    const containerSize = typeof size === "number" ? `${size}px` : size;
    // Get stroke color/url
    const getStroke = () => {
        if (getColors.type === "solid") {
            return getColors.color;
        }
        return `url(#${gradientId})`;
    };
    // Get glow color for hover effect
    const getGlowColor = () => {
        if (getColors.type === "solid") {
            return getColors.color;
        }
        return getColors.from;
    };
    const resolveSegmentFill = (factor) => {
        if (getColors.type === "solid") {
            return getColors.color;
        }
        return interpolateHexColor(getColors.from, getColors.to, factor);
    };
    return (jsxs(motion.div, { ref: containerRef, className: cn(theme.baseStyle, className), style: { width: containerSize, height: containerSize }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "progressbar", "aria-valuenow": safePercentage, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": `Progress: ${safePercentage}%`, ...props, children: [jsxs("svg", { viewBox: `0 0 ${svgSize} ${svgSize}`, width: "100%", height: "100%", className: "overflow-visible relative z-10 rounded-full", style: {
                    filter: isHovered
                        ? `drop-shadow(0 4px 4px ${getGlowColor()}60)`
                        : "none",
                    transition: "filter 1s ease",
                }, children: [jsx("defs", { children: getColors.type === "gradient" && (jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [jsx("stop", { offset: "0%", stopColor: getColors.from }), jsx("stop", { offset: "100%", stopColor: getColors.to })] })) }), isSegmentedVariant ? (jsxs("g", { children: [segmentDefinitions.map((segment, index) => {
                                var _a;
                                return (jsx("path", { d: segment.trackPath, fill: resolveCssVariable(((_a = theme.colors) === null || _a === void 0 ? void 0 : _a.track) || "", "#e5e7eb"), opacity: 0.25 }, `donut-track-${index}`));
                            }), segmentDefinitions.map((segment, index) => segment.activePath ? (jsx(motion.path, { d: segment.activePath, fill: resolveSegmentFill(segment.colorFactor), initial: { opacity: 0, scale: 0.95 }, animate: hasAnimated ? { opacity: 1, scale: 1 } : {}, transition: showAnimation && !shouldReduceMotion
                                    ? {
                                        ...getSpringAnimation(CIRCULAR_CHART_ANIMATIONS.donut.preset, shouldReduceMotion, CIRCULAR_CHART_ANIMATIONS.donut.initialDelay + getStaggerDelay(index, 0.015))
                                    }
                                    : { duration: 0 }, style: { transformOrigin: "50% 50%" } }, `donut-active-${index}`)) : null)] })) : (jsxs(Fragment, { children: [jsx("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: "#000000", strokeWidth: strokeWidth > 2 ? strokeWidth - 2 : 1, opacity: 0.05 }), jsx(motion.circle, { cx: center, cy: center, r: radius, fill: "none", stroke: getStroke(), strokeWidth: strokeWidth, strokeLinecap: "round", strokeDasharray: circumference, initial: { strokeDashoffset: circumference }, animate: hasAnimated ? { strokeDashoffset: progressOffset } : {}, transition: showAnimation && !shouldReduceMotion
                                    ? getSpringAnimation(CIRCULAR_CHART_ANIMATIONS.donut.preset, shouldReduceMotion, CIRCULAR_CHART_ANIMATIONS.donut.initialDelay)
                                    : { duration: 0 }, transform: `rotate(-90 ${center} ${center})`, style: {
                                    filter: isHovered ? `url(#glow-${gradientId})` : "none",
                                } })] }))] }), jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center z-20", children: [jsx("div", { className: cn((_a = theme.text) === null || _a === void 0 ? void 0 : _a.label), children: label !== undefined ? label : `${safePercentage}%` }), subtitle && jsx("div", { className: cn((_b = theme.text) === null || _b === void 0 ? void 0 : _b.subtitle), children: subtitle }), children && jsx("div", { children: children })] })] }));
};
DonutChart.displayName = "DonutChart";

export { DonutChart };
