import React, { useState, useEffect, useMemo } from 'react';
import LineChartComponent from './LineChartComponent';
import DateRangeSelector from '../Charts2/Components/DateRangeSelector';
import metricsService from '../Charts2/Components/metricsService';
import { Button, Radio, message, Tag, Spin } from 'antd';
import moment from 'moment';
import StatusLogTable from '../Charts2/Components/StatusLogTable';
import { Box, IconButton, Tooltip as MuiTooltip } from '@mui/material';
import { ListAlt } from '@mui/icons-material';

const SystemChart = ({ metricInfo, chartHeight = 580 }) => {
    const {
        name: metricName,
        filters = {},
        title = metricName,
        description,
        context = {},
        ranges = [],
        multipleLines = false,
        lineKey = 'device'
    } = metricInfo || {};

    const { device, source_id } = context;

    const [rawData, setRawData] = useState([]);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);
    const [metricMeta, setMetricMeta] = useState({});
    const [mode, setMode] = useState('realtime');
    const [startDate, setStartDate] = useState(moment().subtract(1, 'hour').toDate());
    const [endDate, setEndDate] = useState(moment().toDate());
    const [isLiveUpdating, setIsLiveUpdating] = useState(false);
    const [showLogs, setShowLogs] = useState(false);
    const [statusLogs, setStatusLogs] = useState([]);

    const MAX_POINTS = 1000;
    const TIME_WINDOW_MS = 3600 * 1000;

    const subscriptionKey = useMemo(() => {
        const filterParts = [];
        if (device) filterParts.push(`device=${encodeURIComponent(device)}`);
        if (source_id) filterParts.push(`source_id=${encodeURIComponent(source_id)}`);
        return `${metricName}${filterParts.length ? `?${filterParts.join('&')}` : ''}`;
    }, [metricName, device, source_id]);

    const formatMetricData = (dataArray) => {
        return dataArray.map(item => ({
            ...item,
            timestamp: item.timestamp,
            value: parseFloat(item.value),
            name: item.__name__ || metricName,
            status: parseInt(item.status) || 0,
            device: item.device?.trim() || null,
            source_id: item.source_id || null,
            description: item.description || description,
            lineId: item[lineKey] || 'default'
        }));
    };

    const calculateStep = (start, end) => {
        const duration = end.getTime() - start.getTime();
        return Math.max(Math.floor(duration / (MAX_POINTS * 1000)), 1);
    };

    const fetchHistoricalData = async (start, end) => {
        setIsLoading(true);
        setError(null);

        try {
            const extendedFilters = {
                ...filters,
                ...(device && { device: device.toString() }),
                ...(source_id && { source_id: source_id.toString() })
            };

            const step = calculateStep(start, end);
            const data = await metricsService.fetchMetricsRange(
                metricName,
                Math.floor(start.getTime() / 1000),
                Math.floor(end.getTime() / 1000),
                step,
                extendedFilters
            );

            const formattedData = formatMetricData(data);
            setRawData(formattedData);

            if (formattedData.length > 0) {
                setMetricMeta({
                    type: data[0]?.type,
                    description: data[0]?.description || description,
                    instance: data[0]?.instance,
                    job: data[0]?.job
                });
            }
        } catch (err) {
            console.error(`Error loading historical data for ${metricName}:`, err);
            setError(err.message);
            message.error(`Failed to load historical data: ${err.message}`);
        } finally {
            setIsLoading(false);
        }
    };

    const startRealtimeUpdates = () => {
        setIsLiveUpdating(true);
        setIsLoading(true);

        const end = new Date();
        const start = new Date(end.getTime() - TIME_WINDOW_MS);
        fetchHistoricalData(start, end).finally(() => setIsLoading(false));

        return metricsService.subscribeToMetric(
            subscriptionKey,
            (newData) => {
                setRawData(prev => {
                    const now = Date.now();
                    const cutoffTime = now - TIME_WINDOW_MS;

                    const formattedNewData = formatMetricData(newData)
                        .filter(point => point.timestamp >= cutoffTime);

                    const filteredPrev = prev.filter(point => point.timestamp >= cutoffTime);

                    // Объединяем данные, удаляем дубликаты
                    const merged = [...filteredPrev, ...formattedNewData]
                        .filter((v, i, a) =>
                            a.findIndex(t =>
                                t.timestamp === v.timestamp &&
                                t[lineKey] === v[lineKey]
                            ) === i
                        );

                    return merged;
                });
            },
            5000, // Интервал обновления 5 секунд
            {
                ...filters,
                ...(device && { device }),
                ...(source_id && { source_id })
            }
        );
    };

    const stopRealtimeUpdates = () => {
        setIsLiveUpdating(false);
        metricsService.unsubscribeFromMetric(subscriptionKey);
    };

    const handleCustomRangeApply = () => {
        if (startDate && endDate) {
            fetchHistoricalData(startDate, endDate);
        }
    };

    // Обновляем логи статусов
    useEffect(() => {
        if (rawData.length > 0) {
            const logs = [];
            const devices = [...new Set(rawData.map(item => item[lineKey]))];

            devices.forEach(dev => {
                const deviceData = rawData
                    .filter(item => item[lineKey] === dev)
                    .sort((a, b) => a.timestamp - b.timestamp);

                if (deviceData.length > 0) {
                    logs.push(deviceData[0]); // Первая точка

                    for (let i = 1; i < deviceData.length; i++) {
                        if (deviceData[i].status !== deviceData[i - 1].status) {
                            logs.push(deviceData[i]);
                        }
                    }
                }
            });

            setStatusLogs(logs.sort((a, b) => b.timestamp - a.timestamp));
        }
    }, [rawData, lineKey]);

    useEffect(() => {
        let unsubscribe;

        if (mode === 'realtime') {
            unsubscribe = startRealtimeUpdates();
        } else {
            stopRealtimeUpdates();
            fetchHistoricalData(startDate, endDate);
        }

        return () => {
            if (unsubscribe) unsubscribe();
            stopRealtimeUpdates();
        };
    }, [mode, metricName, device, source_id]);

    const metaInfo = [
        metricMeta.instance && `Instance: ${metricMeta.instance}`,
        metricMeta.job && `Job: ${metricMeta.job}`,
        metricMeta.type && `Type: ${metricMeta.type}`
    ].filter(Boolean).join(' | ');

    return (
        <div style={{ position: 'relative' }}>
            <div style={{ marginBottom: 16 }}>
                <Radio.Group
                    value={mode}
                    onChange={(e) => setMode(e.target.value)}
                    buttonStyle="solid"
                    style={{ marginBottom: 10 }}
                >
                    <Radio.Button value="realtime">Режим реального времени</Radio.Button>
                    <Radio.Button value="historical">Исторические данные</Radio.Button>
                </Radio.Group>

                {mode === 'historical' && (
                    <DateRangeSelector
                        startDate={startDate}
                        endDate={endDate}
                        onStartDateChange={setStartDate}
                        onEndDateChange={setEndDate}
                        onApply={handleCustomRangeApply}
                    />
                )}

                {mode === 'realtime' && (
                    <Tag color={isLiveUpdating ? 'green' : 'red'}>
                        {isLiveUpdating ? 'Обновление в реальном времени' : 'Режим реального времени остановлен'}
                    </Tag>
                )}
            </div>

            {device && <Tag color="geekblue">Устройство: {device}</Tag>}
            {source_id && <Tag color="purple">Модуль: {source_id.split('$')[1]}</Tag>}

            <Box position="relative">
                <MuiTooltip title={showLogs ? "Скрыть логи" : "Показать логи"}>
                    <IconButton
                        onClick={() => setShowLogs(!showLogs)}
                        sx={{
                            position: 'absolute',
                            right: 16,
                            top: 16,
                            zIndex: 1000,
                            bgcolor: 'background.paper',
                            boxShadow: 1
                        }}
                    >
                        <ListAlt />
                    </IconButton>
                </MuiTooltip>

                {isLoading ? (
                    <div style={{ height: chartHeight, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                        <Spin size="large" tip="Загрузка данных..." />
                    </div>
                ) : error ? (
                    <div style={{ color: 'red', padding: 20 }}>Ошибка: {error}</div>
                ) : rawData.length === 0 ? (
                    <div style={{ padding: 20 }}>Нет данных для метрики: {metricName}</div>
                ) : (
                    <>
                        <LineChartComponent
                            data={rawData}
                            title={title}
                            description={description}
                            multipleLines={multipleLines}
                            lineKey={lineKey}
                            metaInfo={metaInfo}
                            height={chartHeight}
                            ranges={ranges}
                        />
                        {showLogs && <StatusLogTable logs={statusLogs} />}
                    </>
                )}
            </Box>
        </div>
    );
};

export default SystemChart;