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 int _deviceId;

  InspectionTopologyCubit({
    DeviceTopologyService? service,
    required int 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);

    // 计算连接数: 父节点到每个子节点一条连接
    int connectionCount = 0;
    for (final child in rootNode.children) {
      connectionCount++; // 根到子
      connectionCount += child.children.length; // 子到孙
    }

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

  /// 将 API 返回的扁平节点列表转换为树结构 + 自动计算位置
  TopologyNode _buildTopologyTree(List<TreeNodeBO> nodes) {
    if (nodes.isEmpty) {
      return TopologyNode(
        id: '0',
        name: '未知设备',
        status: 'offline',
        children: [],
        x: 0.5,
        y: 0.15,
      );
    }

    // 第一个节点作为根节点
    final root = nodes.first;
    final children = nodes.length > 1 ? nodes.sublist(1) : <TreeNodeBO>[];

    // 如果子节点 <= 6，平分到第二层；否则将前6个放第二层，其余作为叶子
    final int maxLevel2 = 6;
    final level2Nodes = children.take(maxLevel2).toList();
    final leafNodes = children.length > maxLevel2
        ? children.sublist(maxLevel2)
        : <TreeNodeBO>[];

    final rootNode = TopologyNode(
      id: root.deviceId.toString(),
      name: root.deviceName,
      status: root.status,
      x: 0.5,
      y: 0.15,
      children: level2Nodes.asMap().entries.map((entry) {
        final idx = entry.key;
        final node = entry.value;
        // 在第二层均匀分布
        final xPos = (level2Nodes.length == 1)
            ? 0.5
            : 0.15 + (0.7 * idx / (level2Nodes.length - 1));
        return TopologyNode(
          id: node.deviceId.toString(),
          name: node.deviceName,
          status: node.status,
          x: xPos,
          y: 0.45,
          children: [],
        );
      }).toList(),
    );

    // 补充叶子节点：附着到最近的第二层节点上
    if (leafNodes.isNotEmpty && rootNode.children.isNotEmpty) {
      final leafNode = leafNodes.first;
      final lastLevel2Idx = rootNode.children.length - 1;
      final lastLevel2 = rootNode.children[lastLevel2Idx];
      final updatedChildren = List<TopologyNode>.from(rootNode.children);
      updatedChildren[lastLevel2Idx] = TopologyNode(
        id: lastLevel2.id,
        name: lastLevel2.name,
        status: lastLevel2.status,
        x: lastLevel2.x,
        y: lastLevel2.y,
        children: leafNodes.asMap().entries.map((entry) {
          final idx = entry.key;
          final leaf = entry.value;
          final xPos = (leafNodes.length == 1)
              ? lastLevel2.x
              : lastLevel2.x -
                  0.1 +
                  (0.2 * idx / (leafNodes.length - 1));
          return TopologyNode(
            id: leaf.deviceId.toString(),
            name: leaf.deviceName,
            status: leaf.status,
            x: xPos,
            y: 0.75,
            children: [],
          );
        }).toList(),
      );
      return TopologyNode(
        id: rootNode.id,
        name: rootNode.name,
        status: rootNode.status,
        x: rootNode.x,
        y: rootNode.y,
        children: updatedChildren,
      );
    }

    return rootNode;
  }

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