import React, { useState, useRef, useEffect } from 'react';
import { LineChart, XAxis, YAxis, CartesianGrid, Tooltip, Line, ResponsiveContainer, ReferenceArea } from 'recharts';
import { HOUR, DAY } from './constants';
const TIME_FORMATS = {
    LONG: 'dd.MM HH:mm',   // Для диапазона > 24 часов
    MEDIUM: 'HH:mm',       // Для диапазона > 1 часа
    SHORT: 'HH:mm:ss'      // Для коротких диапазонов
};

const LineChartComponent = ({
    chartData,
    metricName,
    colors,
    onRangeSelect,
    filteredData
}) => {
    const [selectionArea, setSelectionArea] = useState(null);
    const [isSelecting, setIsSelecting] = useState(false);
    const chartRef = useRef(null);


    const allTimestamps = Object.values(chartData)
        .flat()
        .map(point => point.timestamp)
        .filter((timestamp, index, self) => self.indexOf(timestamp) === index)
        .sort((a, b) => a - b);

    const data = allTimestamps.map(timestamp => {
        const point = { timestamp };

        const firstPoint = Object.values(chartData)
            .flat()
            .find(p => p.timestamp === timestamp);

        if (firstPoint) {
            point.time = firstPoint.time;
            point.fullTime = firstPoint.fullTime;
        }

        Object.keys(chartData).forEach(key => {
            const instanceData = chartData[key].find(p => p.timestamp === timestamp);
            point[key] = instanceData ? instanceData.value : null;
        });

        return point;
    });

    const displayData = filteredData || data;

    const instanceKeys = displayData.length
        ? Object.keys(displayData[0]).filter(k => !['timestamp', 'time', 'fullTime'].includes(k))
        : [];

    // Функция для определения оптимального формата времени в зависимости от диапазона
    const getTimeFormat = () => {
        if (!data.length) return TIME_FORMATS.SHORT;

        const range = data[data.length - 1].timestamp - data[0].timestamp;

        if (range > DAY) return TIME_FORMATS.LONG;
        if (range > HOUR) return TIME_FORMATS.MEDIUM;
        return TIME_FORMATS.SHORT;
    };

    useEffect(() => {
        const handleSelectStart = (e) => {
            if (isSelecting) {
                e.preventDefault();
            }
        };


        document.addEventListener('selectstart', handleSelectStart);
        return () => document.removeEventListener('selectstart', handleSelectStart);
    }, [isSelecting]);

    const handleMouseDown = (e) => {
        if (!e) return;

        // Получаем индекс точки по координатам
        const activeIndex = e.activeTooltipIndex;
        if (activeIndex === undefined || activeIndex < 0 || activeIndex >= data.length) return;

        setIsSelecting(true);
        setSelectionArea({
            start: data[activeIndex].timestamp,
            end: null,
            startIndex: activeIndex,
            endIndex: null
        });
    };

    const handleMouseMove = (e) => {
        if (!isSelecting || !selectionArea?.start || !e) return;

        const activeIndex = e.activeTooltipIndex;
        if (activeIndex === undefined || activeIndex < 0 || activeIndex >= data.length) return;

        setSelectionArea(prev => ({
            ...prev,
            end: data[activeIndex].timestamp,
            endIndex: activeIndex
        }));
    };

    const handleMouseUp = () => {
        if (!isSelecting || !selectionArea?.start || !selectionArea?.end) {
            setIsSelecting(false);
            setSelectionArea(null);
            return;
        }

        const startIndex = Math.min(selectionArea.startIndex, selectionArea.endIndex);
        const endIndex = Math.max(selectionArea.startIndex, selectionArea.endIndex);

        // Нормализуем индексы к диапазону [0, 1] для родительского компонента
        const normalizedStart = startIndex / (data.length - 1);
        const normalizedEnd = endIndex / (data.length - 1);

        onRangeSelect({
            startIndex: normalizedStart,
            endIndex: normalizedEnd
        });

        setIsSelecting(false);
        setSelectionArea(null);
    };

    const CustomTooltip = ({ active, payload, label }) => {
        if (active && payload && payload.length) {
            const currentPoint = data.find(point => point.timestamp === label);
            return (
                <div style={{
                    backgroundColor: '#fff',
                    padding: '10px',
                    border: '1px solid #ccc',
                    borderRadius: '4px',
                    boxShadow: '0 2px 5px rgba(0,0,0,0.1)'
                }}>
                    <p style={{ fontWeight: 'bold', marginBottom: '5px' }}>
                        {currentPoint?.fullTime || new Date(label).toLocaleString('ru-RU')}
                    </p>
                    {payload.map((item, index) => (
                        <p key={index} style={{ color: item.color }}>
                            {`Значение: ${item.value}`}
                        </p>
                    ))}
                </div>
            );
        }
        return null;
    };

    if (!data.length) {
        return <div style={{ padding: '20px', textAlign: 'center' }}>Нет данных для отображения</div>;
    }

    return (
        <div style={{ position: 'relative', height: '400px' }}>
            <ResponsiveContainer width="100%" height="100%">
                <LineChart
                    data={displayData}
                    onMouseDown={handleMouseDown}
                    onMouseMove={handleMouseMove}
                    onMouseUp={handleMouseUp}
                    margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
                    ref={chartRef}
                >
                    <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
                    <XAxis
                        dataKey="timestamp"
                        height={75}
                        tick={{ fontSize: 12, angle: -45, textAnchor: 'end' }}
                        interval={Math.max(1, Math.floor(data.length / 10))}
                        tickFormatter={(timestamp) => {
                            const date = new Date(timestamp);
                            const format = getTimeFormat();

                            if (format === 'dd.MM HH:mm') {
                                return date.toLocaleString('ru-RU', {
                                    day: '2-digit',
                                    month: '2-digit',
                                    hour: '2-digit',
                                    minute: '2-digit'
                                });
                            } else if (format === 'HH:mm') {
                                return date.toLocaleString('ru-RU', {
                                    hour: '2-digit',
                                    minute: '2-digit'
                                });
                            } else {
                                return date.toLocaleString('ru-RU', {
                                    hour: '2-digit',
                                    minute: '2-digit',
                                    second: '2-digit'
                                });
                            }
                        }}
                    />

                    <YAxis tick={{ fontSize: 12 }} />
                    <Tooltip content={<CustomTooltip />} />
                    {instanceKeys.map((instance, index) => (
                        <Line
                            key={instance}
                            type=""
                            dataKey={instance}
                            name={instance}
                            stroke={colors[index % colors.length]}
                            strokeWidth={2}
                            dot={false}
                            activeDot={{ r: 6 }}
                        />
                    ))}
                    {selectionArea?.start && selectionArea?.end && (
                        <ReferenceArea
                            x1={selectionArea.start}
                            x2={selectionArea.end}
                            strokeOpacity={0.3}
                            fill="#4a6baf"
                        />
                    )}
                </LineChart>
            </ResponsiveContainer>
        </div>
    );
};

export default React.memo(LineChartComponent);