import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../cubit/inspection_topology_state.dart';

class NetworkTopologyWidget extends StatelessWidget {
  final List<TopologyNode> topologyNodes;
  final int deviceCount;
  final int connectionCount;
  final Function(TopologyNode) onNodeTap;

  const NetworkTopologyWidget({
    super.key,
    required this.topologyNodes,
    required this.deviceCount,
    required this.connectionCount,
    required this.onNodeTap,
  });

  /// 找到最大深度，并返回每个深度的节点总数
  Map<int, int> _countByDepth(TopologyNode node, int depth) {
    final map = <int, int>{};
    _collectDepthCounts(node, depth, map);
    return map;
  }

  void _collectDepthCounts(TopologyNode node, int depth, Map<int, int> map) {
    map[depth] = (map[depth] ?? 0) + 1;
    for (var child in node.children) {
      _collectDepthCounts(child, depth + 1, map);
    }
  }

  @override
  Widget build(BuildContext context) {
    // 计算最大深度 & 每个深度有多少节点
    final depthCounts =
        topologyNodes.isNotEmpty ? _countByDepth(topologyNodes[0], 0) : <int, int>{};
    final maxDepth = depthCounts.keys.isEmpty ? 0 : depthCounts.keys.reduce((a, b) => a > b ? a : b);
    // 最后一层节点数 > 3 时，叶子节点用竖向容器
    final lastLevelCount = depthCounts[maxDepth] ?? 0;
    final useVerticalLeaf = lastLevelCount > 3;

    // 计算动态高度：竖向叶子节点文字越多，需要越高
    final maxVerticalChars = topologyNodes.isNotEmpty
        ? _maxVerticalChars(topologyNodes[0], 0, maxDepth, useVerticalLeaf)
        : 0;
    // 基础高度 800.h，每个超出4个字的多余字符增加 30.h
    final extraHeight = maxVerticalChars > 4 ? (maxVerticalChars - 4) * 30.h : 0.0;
    final topologyHeight = max(800.h, 800.h + extraHeight);

    return Container(
      padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 32.h),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(24.r),
          bottomRight: Radius.circular(24.r),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        spacing: 32.h,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                '网络拓扑',
                style: TextStyle(
                  fontSize: 28.sp,
                  fontWeight: FontWeight.w600,
                  color: const Color.fromRGBO(15, 23, 42, 1),
                ),
              ),
              Text(
                '共$deviceCount个设备,$connectionCount条连接',
                style: TextStyle(
                  fontSize: 24.sp,
                  color: const Color.fromRGBO(148, 163, 184, 1),
                ),
              ),
            ],
          ),
          SizedBox(
            width: double.infinity,
            height: topologyHeight,
            child: ClipRRect(
              borderRadius: BorderRadius.circular(32.r),
              child: Container(
                width: double.infinity,
                height: double.infinity,
                color: const Color.fromRGBO(241, 245, 249, 1),
                child: Padding(
                  padding: EdgeInsets.only(top: 32.h, bottom: 32.h),
                  child: Stack(
                    children: [
                      if (topologyNodes.isNotEmpty)
                        CustomPaint(
                          size: Size.infinite,
                          painter: TopologyPainter(nodes: topologyNodes),
                        ),
                      if (topologyNodes.isNotEmpty)
                        LayoutBuilder(
                          builder: (context, constraints) {
                            final List<Widget> clickableNodes = [];
                            _collectNodes(
                              topologyNodes[0],
                              clickableNodes,
                              constraints.maxWidth,
                              constraints.maxHeight,
                              0,
                              maxDepth,
                              useVerticalLeaf,
                            );
                            return Stack(children: clickableNodes);
                          },
                        ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  /// 找到竖向节点中最长的文字长度
  int _maxVerticalChars(TopologyNode node, int depth, int maxDepth, bool useVerticalLeaf) {
    int maxChars = 0;
    final isVirtualRoot = node.id == '0' && node.name == '根节点';
    final isVertical = depth >= 3 ||
        (depth == maxDepth && node.children.isEmpty && useVerticalLeaf);
    if (!isVirtualRoot && isVertical) {
      maxChars = node.name.length;
    }
    for (var child in node.children) {
      maxChars = max(maxChars, _maxVerticalChars(child, depth + 1, maxDepth, useVerticalLeaf));
    }
    return maxChars;
  }

  void _collectNodes(
    TopologyNode node,
    List<Widget> nodes,
    double maxWidth,
    double maxHeight,
    int depth,
    int maxDepth,
    bool useVerticalLeaf,
  ) {
    final centerX = maxWidth * node.x;
    final centerY = maxHeight * node.y;

    // 跳过虚拟根节点
    final isVirtualRoot = node.id == '0' && node.name == '根节点';

    // depth ≥ 3 全部竖向；否则只有最后一层且叶子多时竖向
    final isVerticalNode = depth >= 3 ||
        (depth == maxDepth && node.children.isEmpty && useVerticalLeaf);

    if (!isVirtualRoot) {
      if (isVerticalNode) {
        // 竖向椭圆容器
        nodes.add(
          Positioned(
            left: centerX,
            top: centerY - 30.h,
            child: FractionalTranslation(
              translation: const Offset(-0.5, 0),
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => onNodeTap(node),
                child: Container(
                  alignment: Alignment.center,
                  padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 12.h),
                  decoration: BoxDecoration(
                    color: const Color.fromRGBO(229, 241, 255, 1),
                    border: Border.all(
                      color: const Color.fromRGBO(80, 162, 255, 1),
                      width: 1.w,
                    ),
                    borderRadius: BorderRadius.circular(24.r),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: node.name
                        .split('')
                        .map((char) => Text(
                              char,
                              style: TextStyle(
                                color: const Color.fromRGBO(100, 116, 139, 1),
                                fontSize: 24.sp,
                                fontWeight: FontWeight.w500,
                              ),
                            ))
                        .toList(),
                  ),
                ),
              ),
            ),
          ),
        );
      } else {
        // 横向椭圆容器
        nodes.add(
          Positioned(
            left: centerX,
            top: centerY - 54.h / 2,
            child: FractionalTranslation(
              translation: const Offset(-0.5, 0),
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => onNodeTap(node),
                child: Container(
                  padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 12.h),
                  decoration: BoxDecoration(
                    color: const Color.fromRGBO(229, 241, 255, 1),
                    border: Border.all(
                      color: const Color.fromRGBO(80, 162, 255, 1),
                      width: 1.w,
                    ),
                    borderRadius: BorderRadius.circular(40.r),
                  ),
                  child: Text(
                    node.name,
                    style: TextStyle(
                      color: const Color.fromRGBO(100, 116, 139, 1),
                      fontSize: 24.sp,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }

    for (var child in node.children) {
      _collectNodes(child, nodes, maxWidth, maxHeight, depth + 1, maxDepth, useVerticalLeaf);
    }
  }
}

class TopologyPainter extends CustomPainter {
  final List<TopologyNode> nodes;

  TopologyPainter({required this.nodes});

  @override
  void paint(Canvas canvas, Size size) {
    if (nodes.isEmpty) return;

    final paint = Paint()
      ..color = const Color.fromRGBO(214, 217, 224, 1)
      ..strokeWidth = 2.w
      ..style = PaintingStyle.stroke;

    _drawConnections(canvas, size, nodes[0], paint);
  }

  void _drawConnections(Canvas canvas, Size size, TopologyNode node, Paint paint) {
    final isVirtualRoot = node.id == '0' && node.name == '根节点';
    if (isVirtualRoot) {
      for (var child in node.children) {
        _drawConnections(canvas, size, child, paint);
      }
      return;
    }

    final centerX = size.width * node.x;
    final centerY = size.height * node.y;

    for (var child in node.children) {
      final childCenterX = size.width * child.x;
      final childCenterY = size.height * child.y;

      canvas.drawLine(
        Offset(centerX, centerY),
        Offset(childCenterX, childCenterY),
        paint,
      );

      _drawConnections(canvas, size, child, paint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
