import { jsxs, jsx } from 'react/jsx-runtime';
import { useRef, useState, useMemo, useEffect } from 'react';
import { motion } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { useTooltipPosition } from '../hooks/useTooltipPosition.js';
import { useChart } from '../ChartContainer.js';
import { ChartTooltip } from '../shared/ChartTooltip/ChartTooltip.js';
import { HeatmapCell } from './HeatmapCell.js';
import { processHeatmapData, createGridMatrix, calculateIntensity, getDefaultTooltipContent } from './utils/heatmapUtils.js';
import { HeatmapLegend } from './HeatmapLegend.js';
import { heatmapTheme } from './Heatmap.theme.js';

/**
 * Heatmap component for visualizing data in a grid format with color intensity
 * Supports weekly, monthly, hourly views and custom data structures
 */
const Heatmap = ({ data: dataProp, config: configProp, color = 'primary', colorScale = { steps: 10, minOpacity: 0.1 }, layout = { gap: 6 }, axis = { showXAxis: true, showYAxis: true }, tooltip = { enabled: true }, legend = { enabled: true }, valueRange, onCellClick, cellRenderer, className, variant = 'default', children, ...props }) => {
    // Get data and config from context if not provided as props
    const chartContext = useChart();
    const data = dataProp || chartContext.data;
    const config = configProp || chartContext.config;
    const containerRef = useRef(null);
    const [dimensions, setDimensions] = useState({ width: 600, height: 400 });
    // Detect if device is mobile/touch
    const isMobile = typeof window !== 'undefined' &&
        ('ontouchstart' in window || navigator.maxTouchPoints > 0);
    // Use the new tooltip positioning hook
    const { tooltipData, tooltipRef, handleMouseEnter, handleMouseMove, handleMouseLeave, } = useTooltipPosition({
        containerRef,
        isMobile,
    });
    // Process data
    const processedData = useMemo(() => {
        return processHeatmapData(data, valueRange);
    }, [data, valueRange]);
    const { xCategories, yCategories, minValue, maxValue } = processedData;
    // Create grid matrix
    const gridMatrix = useMemo(() => {
        return createGridMatrix(data, xCategories, yCategories);
    }, [data, xCategories, yCategories]);
    // Measure container dimensions
    useEffect(() => {
        const updateDimensions = () => {
            if (containerRef.current) {
                const { width, height } = containerRef.current.getBoundingClientRect();
                setDimensions({ width, height });
            }
        };
        updateDimensions();
        const resizeObserver = new ResizeObserver(updateDimensions);
        if (containerRef.current) {
            resizeObserver.observe(containerRef.current);
        }
        return () => {
            resizeObserver.disconnect();
        };
    }, []);
    // Simple color resolution - similar to AreaChart
    const getCellColor = () => {
        var _a;
        // Check config for custom color
        if ((_a = config === null || config === void 0 ? void 0 : config.value) === null || _a === void 0 ? void 0 : _a.color) {
            const customColor = config.value.color;
            // Support direct hex/rgb colors
            if (customColor.startsWith('#') || customColor.startsWith('rgb')) {
                return customColor;
            }
            // Support CSS variables
            if (customColor.startsWith('var(')) {
                return customColor;
            }
            // Support semantic color strings
            return `var(--color-${customColor})`;
        }
        // Use color prop (semantic color)
        return `var(--color-${color})`;
    };
    const cellColor = getCellColor();
    // Handle cell hover using new tooltip system
    const handleCellHover = (data, event) => {
        if (!tooltip.enabled)
            return;
        const content = tooltip.formatter
            ? tooltip.formatter(data)
            : getDefaultTooltipContent(data);
        handleMouseEnter(event, content);
    };
    // Handle cell mouse move using new tooltip system
    const handleCellMouseMove = (data, event) => {
        if (!tooltip.enabled || !tooltipData)
            return;
        handleMouseMove(event);
    };
    // Handle cell leave using new tooltip system
    const handleCellLeave = () => {
        if (!tooltip.enabled)
            return;
        handleMouseLeave();
    };
    // Calculate grid styles
    const gridStyles = {
        display: 'grid',
        gridTemplateColumns: `repeat(${xCategories.length}, 1fr)`,
        gridTemplateRows: `repeat(${yCategories.length}, 1fr)`,
        gap: typeof layout.gap === 'number' ? `${layout.gap}px` : layout.gap,
        width: '100%',
        height: '100%',
    };
    // Render axis labels - using theme for base styles
    const renderXAxisLabels = () => {
        if (!axis.showXAxis)
            return null;
        return (jsxs("div", { className: cn("flex justify-between items-center px-1 py-2", heatmapTheme.axisLabelStyle), style: { gridColumn: `1 / -1` }, role: "list", "aria-label": "X-axis labels", "aria-describedby": "heatmap-x-axis-description", children: [xCategories.map((category, index) => (jsx("div", { className: "flex-1 text-center px-1", style: {
                        transform: axis.xAxisRotation ? `rotate(${axis.xAxisRotation}deg)` : undefined
                    }, role: "listitem", "aria-label": `X-axis label: ${axis.xAxisFormatter
                        ? axis.xAxisFormatter(category, index)
                        : String(category)}`, children: axis.xAxisFormatter
                        ? axis.xAxisFormatter(category, index)
                        : String(category) }, category))), jsxs("span", { id: "heatmap-x-axis-description", className: "sr-only", children: ["X-axis contains ", xCategories.length, " categories representing the horizontal dimension of the heatmap"] })] }));
    };
    const renderYAxisLabels = () => {
        if (!axis.showYAxis)
            return null;
        return (jsxs("div", { className: cn("grid pr-3", heatmapTheme.axisLabelStyle), style: {
                gridTemplateRows: `repeat(${yCategories.length}, 1fr)`,
                gap: typeof layout.gap === 'number' ? `${layout.gap}px` : layout.gap,
                height: '100%',
            }, role: "list", "aria-label": "Y-axis labels", "aria-describedby": "heatmap-y-axis-description", children: [yCategories.map((category, index) => (jsx("div", { className: "flex items-center justify-end", style: {
                        transform: axis.yAxisRotation ? `rotate(${axis.yAxisRotation}deg)` : undefined
                    }, role: "listitem", "aria-label": `Y-axis label: ${axis.yAxisFormatter
                        ? axis.yAxisFormatter(category, index)
                        : String(category)}`, children: axis.yAxisFormatter
                        ? axis.yAxisFormatter(category, index)
                        : String(category) }, category))), jsxs("span", { id: "heatmap-y-axis-description", className: "sr-only", children: ["Y-axis contains ", yCategories.length, " categories representing the vertical dimension of the heatmap"] })] }));
    };
    return (jsxs("div", { ref: containerRef, className: cn(heatmapTheme.containerStyle, variant === 'bordered' && 'border border-gray-200 dark:border-gray-700 rounded-lg p-4', variant === 'minimal' && 'p-2', className), ...props, children: [jsxs("div", { className: "flex flex-1 min-h-0", children: [axis.showYAxis && (jsxs("div", { className: "flex-shrink-0 w-16 flex flex-col", children: [axis.showXAxis && jsx("div", { className: "flex-shrink-0 h-8" }), jsx("div", { className: "flex-1", children: renderYAxisLabels() })] })), jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [axis.showXAxis && (jsx("div", { className: "flex-shrink-0 h-8", children: renderXAxisLabels() })), jsx("div", { className: "flex-1 relative min-h-0", children: jsx(motion.div, { style: gridStyles, initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.5, ease: 'easeOut' }, className: heatmapTheme.gridStyle, children: gridMatrix.flat().map((cellData, index) => {
                                        const intensity = calculateIntensity(cellData.value, minValue, maxValue);
                                        `${cellData.x}-${cellData.y}`;
                                        // Skip null values entirely
                                        if (cellData.value === null) {
                                            return (jsx("div", { className: "bg-transparent" }, `${cellData.x}-${cellData.y}-${index}`));
                                        }
                                        const CellComponent = cellRenderer || HeatmapCell;
                                        return (jsx(CellComponent, { data: cellData, intensity: intensity, minOpacity: colorScale === null || colorScale === void 0 ? void 0 : colorScale.minOpacity, color: cellColor, onClick: onCellClick, onHover: handleCellHover, onMouseMove: handleCellMouseMove, onLeave: handleCellLeave, className: "rounded-sm" }, `${cellData.x}-${cellData.y}-${index}`));
                                    }) }) })] })] }), ((legend === null || legend === void 0 ? void 0 : legend.enabled) !== false) && (jsx("div", { className: "flex-shrink-0 mt-2", children: jsx(HeatmapLegend, { colorKey: "value", color: cellColor, minValue: minValue, maxValue: maxValue, labels: legend === null || legend === void 0 ? void 0 : legend.labels }) })), tooltip.enabled && (jsx(ChartTooltip, { content: tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.content, active: !!tooltipData, position: tooltipData ? { x: tooltipData.x, y: tooltipData.y } : { x: 0, y: 0 }, tooltipRef: tooltipRef })), children] }));
};

export { Heatmap };
