import React, { useEffect, useMemo, useState } from 'react';
import { Card, Col, Row, Select, Table, Tabs } from 'antd';
import dayjs from 'dayjs';
import { useMetricsStore, NodeMetric } from '../../store/metricsStore';
import { monitoringApi } from '../../api/monitoringApi';
import AreaTrendChart from '../../components/AreaTrendChart';

const NODE_COLORS = ['#1677ff', '#52c41a', '#fa8c16', '#eb2f96', '#722ed1', '#13c2c2'];
const TIME_RANGES = [
    { label: '5 мин', value: 5 },
    { label: '15 мин', value: 15 },
    { label: '30 мин', value: 30 },
    { label: '1 час', value: 60 },
];

const bytesToMb = (value?: number) => (value ?? 0) / 1048576;

const formatTime = (ts: string) => dayjs(ts).format('HH:mm:ss');

const buildChartData = (metrics: NodeMetric[]) =>
    metrics.map((m) => ({
        time: formatTime(m.timestamp),
        cpu: m.cpu_utilization ?? 0,
        memoryMb: bytesToMb(m.memory_total),
        memoryProcessesMb: bytesToMb(m.memory_processes),
        memoryAtomMb: bytesToMb(m.memory_atom),
        memoryBinaryMb: bytesToMb(m.memory_binary),
        memoryEtsMb: bytesToMb(m.memory_ets),
        memoryAvailableMb: bytesToMb(m.memory_available),
        ws: m.ws_connections ?? 0,
        runQueue: m.run_queue ?? 0,
        processCount: m.process_count ?? 0,
        activeSessions: m.active_sessions ?? 0,
        ioIn: m.io_in ?? 0,
        ioOut: m.io_out ?? 0,
        mnesiaCommits: m.mnesia_commits ?? 0,
        mnesiaFailures: m.mnesia_failures ?? 0,
        tableSizes: m.table_sizes ?? {},
    }));

const MetricChart: React.FC<{
    data: ReturnType<typeof buildChartData>;
    lines: Array<{ key: string; color: string; name: string }>;
}> = ({ data, lines }) => (
    <AreaTrendChart data={data} xKey="time" series={lines} />
);

const MonitoringPage: React.FC = () => {
    const allHistory = useMetricsStore((s) => s.allHistory);
    const current = useMetricsStore((s) => s.current);
    const setAllHistory = useMetricsStore((s) => s.setAllHistory);
    const filterVisibleHistory = useMetricsStore((s) => s.filterVisibleHistory);
    const visibleHistory = useMetricsStore((s) => s.visibleHistory);
    const [minutes, setMinutes] = useState(15);
    const [loadingHistory, setLoadingHistory] = useState(false);

    useEffect(() => {
        let cancelled = false;

        const loadHistory = async () => {
            setLoadingHistory(true);
            try {
                const to = dayjs().toISOString();
                const from = dayjs().subtract(minutes, 'minute').toISOString();
                const metrics = await monitoringApi.getNodeMetrics(from, to);
                if (!cancelled && metrics.length > 0) {
                    setAllHistory(metrics);
                }
            } catch {
                // live WS дополняет историю; REST недоступен — не блокируем страницу
            } finally {
                if (!cancelled) {
                    setLoadingHistory(false);
                }
            }
        };

        loadHistory();
        return () => {
            cancelled = true;
        };
    }, [minutes, setAllHistory]);

    useEffect(() => {
        filterVisibleHistory(minutes);
    }, [minutes, allHistory.length, filterVisibleHistory]);

    const allNodes = useMemo(() => {
        const nodes = new Set<string>();
        [...allHistory, ...(current ? [current] : [])].forEach((m) => nodes.add(m.node));
        return Array.from(nodes).sort();
    }, [allHistory, current]);

    const metricsByNode = useMemo(() => {
        const source = visibleHistory.length > 0 ? visibleHistory : allHistory;
        const map = new Map<string, NodeMetric[]>();
        source.forEach((m) => {
            const list = map.get(m.node) || [];
            list.push(m);
            map.set(m.node, list);
        });
        return map;
    }, [visibleHistory, allHistory]);

    const tabItems = allNodes.map((node, idx) => {
        const nodeMetrics = metricsByNode.get(node) || [];
        const chartData = buildChartData(nodeMetrics);
        const latestTableSizes = chartData.at(-1)?.tableSizes ?? {};
        const color = NODE_COLORS[idx % NODE_COLORS.length];

        return {
            key: node,
            label: <span style={{ color }}>{node}</span>,
            children: (
                <Row gutter={[16, 16]}>
                    <Col span={24}>
                        <Card title="CPU и память (МБ)">
                            <MetricChart
                                data={chartData}
                                lines={[
                                    { key: 'cpu', color, name: 'CPU %' },
                                    { key: 'memoryMb', color: '#1890ff', name: 'Память всего' },
                                    { key: 'memoryAvailableMb', color: '#13c2c2', name: 'Память доступно' },
                                ]}
                            />
                        </Card>
                    </Col>
                    <Col span={24}>
                        <Card title="Память по типам (МБ)">
                            <MetricChart
                                data={chartData}
                                lines={[
                                    { key: 'memoryProcessesMb', color: '#1677ff', name: 'Processes' },
                                    { key: 'memoryAtomMb', color: '#52c41a', name: 'Atom' },
                                    { key: 'memoryBinaryMb', color: '#fa8c16', name: 'Binary' },
                                    { key: 'memoryEtsMb', color: '#eb2f96', name: 'ETS' },
                                ]}
                            />
                        </Card>
                    </Col>
                    <Col xs={24} lg={12}>
                        <Card title="WebSocket и очередь">
                            <MetricChart
                                data={chartData}
                                lines={[
                                    { key: 'ws', color: '#52c41a', name: 'WS' },
                                    { key: 'runQueue', color: '#fa8c16', name: 'Run queue' },
                                    { key: 'processCount', color: '#722ed1', name: 'Processes' },
                                    { key: 'activeSessions', color: '#1677ff', name: 'Sessions' },
                                ]}
                            />
                        </Card>
                    </Col>
                    <Col xs={24} lg={12}>
                        <Card title="Mnesia">
                            <MetricChart
                                data={chartData}
                                lines={[
                                    { key: 'mnesiaCommits', color: '#722ed1', name: 'Commits' },
                                    { key: 'mnesiaFailures', color: '#ff4d4f', name: 'Failures' },
                                ]}
                            />
                        </Card>
                    </Col>
                    <Col span={24}>
                        <Card title="I/O">
                            <MetricChart
                                data={chartData}
                                lines={[
                                    { key: 'ioIn', color: '#1677ff', name: 'IO in' },
                                    { key: 'ioOut', color: '#52c41a', name: 'IO out' },
                                ]}
                            />
                        </Card>
                    </Col>
                    <Col span={24}>
                        <Card title="Размеры таблиц Mnesia (последняя точка)">
                            <Table
                                size="small"
                                pagination={false}
                                rowKey="table"
                                dataSource={Object.entries(latestTableSizes).map(([table, size]) => ({
                                    table,
                                    size,
                                }))}
                                columns={[
                                    { title: 'Таблица', dataIndex: 'table', key: 'table' },
                                    { title: 'Записей', dataIndex: 'size', key: 'size' },
                                ]}
                            />
                        </Card>
                    </Col>
                </Row>
            ),
        };
    });

    return (
        <div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
                <h2 style={{ margin: 0 }}>Мониторинг нод</h2>
                <Select
                    value={minutes}
                    onChange={setMinutes}
                    options={TIME_RANGES}
                    style={{ width: 120 }}
                />
            </div>

            {allNodes.length === 0 ? (
                <Card loading={loadingHistory}>
                    {loadingHistory ? 'Загрузка метрик…' : 'Ожидание метрик по WebSocket…'}
                </Card>
            ) : (
                <Tabs items={tabItems} />
            )}
        </div>
    );
};

export default MonitoringPage;
