import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/models/bo/device_topology_bo.dart';
import 'package:smart_hotel_app/repositories/device_topology_repository.dart';
import 'package:smart_hotel_app/services/device_topology_service.dart';
import 'inspection_topology_state.dart';

class InspectionTopologyCubit extends Cubit<InspectionTopologyState> {
  final DeviceTopologyService _service;
  final String _deviceId;

  InspectionTopologyCubit({
    DeviceTopologyService? service,
    required String deviceId,
  })  : _service = service ??
            DeviceTopologyService(
              repository: DeviceTopologyRepository(),
            ),
        _deviceId = deviceId,
        super(const InspectionTopologyState()) {
    loadTopology();
  }

  void selectNode(TopologyNode? node) {
    emit(state.copyWith(selectedNode: node));
  }

  Future<void> loadTopology() async {
    emit(const InspectionTopologyState(isLoading: true));
    try {
      final topology = await _service.getTopology(deviceId: _deviceId);
      _emitFromTopology(topology);
    } catch (e) {
      emit(InspectionTopologyState(error: e.toString()));
    }
  }

  void _emitFromTopology(DeviceTopologyBO topology) {
    final info = topology.deviceInfo;
    final nodes = topology.treeNodes;

    final rootNode = _buildTopologyTree(nodes);

    emit(InspectionTopologyState(
      deviceName: info.deviceName,
      deviceModel: '${info.deviceCode}·${info.deviceLocation}',
      topologyNodes: [rootNode],
      deviceCount: _countAllNodes(rootNode),
      connectionCount: _countConnections(rootNode),
      // statusText:
    ));
  }

  /// 根据 gatewayId 将扁平节点列表构建为树结构，并自动计算布局位置
  TopologyNode _buildTopologyTree(List<TreeNodeBO> nodes) {
    if (nodes.isEmpty) {
      return const TopologyNode(
        id: '0',
        name: '未知设备',
        status: 'offline',
        children: [],
        x: 0.5,
        y: 0.08,
      );
    }

    // 构建子节点映射表：parent deviceId -> [child TreeNodeBO]
    final childrenMap = <int, List<TreeNodeBO>>{};
    final nodeMap = <int, TreeNodeBO>{};
    for (final node in nodes) {
      nodeMap[node.deviceId] = node;
      final parentId = node.gatewayId ?? 0;
      childrenMap.putIfAbsent(parentId, () => []).add(node);
    }

    // 查找根节点：gatewayId 为 null/0，或引用的父节点不存在于列表中
    final nodeIds = nodeMap.keys.toSet();
    final roots = nodes.where((n) =>
      n.gatewayId == null ||
      n.gatewayId == 0 ||
      !nodeIds.contains(n.gatewayId),
    ).toList();

    if (roots.isEmpty) {
      // fallback：取第一个节点作为根
      roots.add(nodes.first);
    }

    // 递归构建节点并计算布局位置
    TopologyNode buildNode(TreeNodeBO node, int depth, double xCenter, double xSpan) {
      final children = childrenMap[node.deviceId] ?? [];
      final childNodes = <TopologyNode>[];

      if (children.isNotEmpty) {
        for (int i = 0; i < children.length; i++) {
          final childX = children.length == 1
              ? xCenter
              : xCenter - xSpan / 2 + (xSpan * i / (children.length - 1));
          childNodes.add(buildNode(children[i], depth + 1, childX, xSpan * 0.55));
        }
      }

      return TopologyNode(
        id: node.deviceId.toString(),
        name: node.deviceName,
        status: node.status,
        statusText: node.statusText,
        gatewayId: node.gatewayId?.toString(),
        x: xCenter.clamp(0.05, 0.95),
        y: (0.08 + depth * 0.17).clamp(0.02, 0.98),
        children: childNodes,
      );
    }

    if (roots.length == 1) {
      return buildNode(roots.first, 0, 0.5, 0.7);
    } else {
      // 多个根节点：创建一个虚拟根，将所有根均匀分布在第二层
      final virtualChildren = <TopologyNode>[];
      for (int i = 0; i < roots.length; i++) {
        final xPos = 0.1 + (0.8 * i / (roots.length - 1));
        virtualChildren.add(buildNode(roots[i], 1, xPos, 0.35));
      }
      return TopologyNode(
        id: '0',
        name: '根节点',
        status: 'online',
        x: 0.5,
        y: 0.08,
        children: virtualChildren,
      );
    }
  }

  /// 递归计算连接数
  int _countConnections(TopologyNode node) {
    int count = 0;
    for (final child in node.children) {
      count += 1 + _countConnections(child);
    }
    return count;
  }

  int _countAllNodes(TopologyNode node) {
    int count = 1;
    for (final child in node.children) {
      count += _countAllNodes(child);
    }
    return count;
  }
}