import React, { useState } from 'react';
import { createPortal } from 'react-dom';
import { useCharts } from './ChartsHook';
import { TooltipBubble } from '../Tooltip/TooltipBubble';
import { useTheme } from '../../core/theme/ThemeProvider';

interface TooltipSeries {
    key: string;
    label: string;
    color: string;
    accessor: (d: any) => number;
}

interface ChartTooltipProps {
    series: TooltipSeries[];
    formatX?: (value: any) => string;
    formatY?: (value: any) => string;
}

export const ChartTooltip: React.FC<ChartTooltipProps> = ({
    series,
    formatX = (val) => val.toString(),
    formatY = (val) => val.toLocaleString(),
}) => {
    const { dataset, xScale, yScale, dimensions, xAccessor } = useCharts();
    const { theme } = useTheme();
    const [hoveredData, setHoveredData] = useState<{
        point: any;
        x: number;
        y: number;
    } | null>(null);

    const handleMouseMove = (event: React.MouseEvent<SVGRectElement>) => {
        if (!dataset || dataset.length === 0) return;

        const { left } = event.currentTarget.getBoundingClientRect();
        // The `left` from getBoundingClientRect on the rect already includes the parent SVG's
        // position and the <g> transform's marginLeft. We just need to subtract it from
        // the viewport-relative clientX to get the mouse position relative to the bounded area.
        const mouseX = event.clientX - left;

        const hoveredXValue = xScale.invert(mouseX);
        
        // Find the closest data point by iterating through the data
        let closestPoint = dataset[0];
        let minDiff = Math.abs(xAccessor(dataset[0], 0) - hoveredXValue);

        for (let i = 1; i < dataset.length; i++) {
            const diff = Math.abs(xAccessor(dataset[i], i) - hoveredXValue);
            if (diff < minDiff) {
                minDiff = diff;
                closestPoint = dataset[i];
            }
        }
        
        setHoveredData({
            point: closestPoint,
            x: event.clientX,
            y: event.clientY,
        });
    };

    const handleMouseLeave = () => {
        setHoveredData(null);
    };

    const svgX = hoveredData ? xScale(xAccessor(hoveredData.point, 0)) : null;

    return (
        <g>
            <rect
                x={0}
                y={0}
                width={dimensions.boundedWidth}
                height={dimensions.boundedHeight}
                fill="transparent"
                onMouseMove={handleMouseMove}
                onMouseLeave={handleMouseLeave}
            />

            {hoveredData && svgX !== null && (
                <>
                    <line
                        x1={svgX} x2={svgX}
                        y1={0} y2={dimensions.boundedHeight}
                        stroke={theme.colors.border}
                        strokeWidth={1}
                        strokeDasharray="3 3"
                        pointerEvents="none"
                    />

                    {series.map(({ key, color, accessor }) => {
                        const yValue = accessor(hoveredData.point);
                        if (yValue === null || yValue === undefined) return null;
                        return (
                            <circle
                                key={key}
                                cx={svgX}
                                cy={yScale(yValue)}
                                r={4}
                                fill={color}
                                stroke={theme.colors.background}
                                strokeWidth={2}
                                pointerEvents="none"
                            />
                        )
                    })}
                    
                    {createPortal(
                        <TooltipBubble style={{
                            position: 'fixed',
                            top: hoveredData.y,
                            left: hoveredData.x,
                            transform: `translate(${hoveredData.x > window.innerWidth / 2 ? '-110%' : '10%'}, -50%)`,
                        }}>
                           <div style={{ marginBottom: '0.5rem', fontWeight: '600', color: theme.colors.text }}>
                               {formatX(xAccessor(hoveredData.point, 0))}
                           </div>
                           <div style={{ display: 'grid', gridTemplateColumns: 'auto auto auto', gap: '0.25rem 1rem', alignItems: 'center' }}>
                                {series.map(({ key, label, color, accessor }) => (
                                    <React.Fragment key={key}>
                                        <div style={{ width: '10px', height: '10px', backgroundColor: color, borderRadius: '50%' }} />
                                        <span style={{ color: theme.colors.textSecondary }}>{label}:</span>
                                        <span style={{ fontWeight: '500', textAlign: 'right' }}>{formatY(accessor(hoveredData.point))}</span>
                                    </React.Fragment>
                                ))}
                           </div>
                        </TooltipBubble>,
                        document.body
                    )}
                </>
            )}
        </g>
    );
};