import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/views/service/index/cubit/service_index_state.dart';
import 'package:smart_hotel_app/services/room_service.dart';
import 'package:smart_hotel_app/repositories/room_repository.dart';
import 'package:smart_hotel_app/models/bo/room_bo.dart';
import 'package:smart_hotel_app/services/room_statistics_service.dart';
import 'package:smart_hotel_app/repositories/room_statistics_repository.dart';

class ServiceIndexCubit extends Cubit<ServiceIndexState> {
  final RoomService _roomService;
  final RoomStatisticsService _statisticsService;
  List<FloorAreaBO> _floorAreasCache = [];

  DateTime? _lastLoadTime;

  ServiceIndexCubit()
      : _roomService = RoomService(repository: RoomRepository()),
        _statisticsService = RoomStatisticsService(
          repository: RoomStatisticsRepository(),
        ),
        super(const ServiceIndexState());

  /// 切回页面时调用，距上次加载不足 30 秒则跳过
  void reloadDataIfStale() {
    if (_lastLoadTime != null &&
        DateTime.now().difference(_lastLoadTime!) < const Duration(seconds: 30)) {
      return;
    }
    _lastLoadTime = DateTime.now();
    loadData();
  }

  Future<void> loadData() async {
    emit(state.copyWith(isLoading: true, error: null));
    try {
      await Future.wait([
        loadStatistics(),
        loadFloorAndAreas(),
      ]);
      emit(state.copyWith(isLoading: false));
    } catch (e) {
      emit(state.copyWith(isLoading: false, error: e.toString()));
    }
  }

  /// 加载客房服务看板-统计数据（待响应、入住中、空闲可清洁）
  Future<void> loadStatistics() async {
    final stats = await _statisticsService.getStatistics();
    emit(state.copyWith(
      pendingCount: stats.pendingResponseCount,
      occupiedRooms: stats.occupiedCount,
      vacantRooms: stats.vacantCleanableCount,
    ));
  }

  /// 加载楼层和区域信息 + 合并房间数据
  Future<void> loadFloorAndAreas() async {
    final floorAreas = await _roomService.getFloorAreas();
    _floorAreasCache = floorAreas;

    final floors = floorAreas.map((f) => {f.floorId: f.floorName}).toList();

    emit(state.copyWith(floors: floors));

    // 默认选中第一个楼层，加载其全部房间数据，再默认选中第一个区域和房间
    if (floors.isNotEmpty) {
      final firstFloor = floors.first;
      final firstFloorId = firstFloor.keys.first;
      final firstFloorLabel = firstFloor.values.first;
      _updateAreasForFloor(firstFloorLabel);
      selectFloor(firstFloorLabel);

      await _loadAllRooms(floorId: firstFloorId);
      _selectFirstTypeAndRoom();
    }
  }

  /// 根据选中的楼层更新 areas
  void _updateAreasForFloor(String floorLabel) {
    final matched = _floorAreasCache.where(
      (f) => f.floorName == floorLabel,
    );
    final areas = matched.isNotEmpty ? matched.first.areas : <String>[];
    emit(state.copyWith(areas: areas));
  }

  /// 加载某楼层的全部房间状态，与 FloorAreaBO.rooms 合并
  Future<void> _loadAllRooms({required int floorId}) async {
    // 获取当前楼层的 FloorAreaBO
    final floorArea = _floorAreasCache.cast<FloorAreaBO?>().firstWhere(
          (f) => f?.floorId == floorId,
          orElse: () => null,
        );

    if (floorArea == null) {
      emit(state.copyWith(rooms: []));
      return;
    }

    // 拉取全楼层房间状态（不传 areaType）
    final roomStatuses = await _roomService.getRoomStatus(floorId: floorId);

    // 以 roomId 为 key 建立状态映射
    final roomIdMap = <int, RoomStatusBO>{};
    for (final rs in roomStatuses) {
      roomIdMap[rs.roomId] = rs;
    }

    // 合并：遍历 floorArea.rooms，匹配状态数据，推断 area
    final mergedRooms = <Map<String, dynamic>>[];
    for (final floorRoom in floorArea.rooms) {
      final status = roomIdMap[floorRoom.roomId];
      final area = _getAreaForRoom(floorRoom.roomName, floorArea.areas);
      mergedRooms.add(_buildRoomMap(
        roomId: floorRoom.roomId,
        roomName: floorRoom.roomName,
        areaType: area,
        status: status,
      ));
    }

    emit(state.copyWith(rooms: mergedRooms));
  }

  /// 根据 roomName 匹配所属区域类型（最长匹配优先）
  String _getAreaForRoom(String roomName, List<String> areas) {
    // 按长度降序排列，避免 "中餐厅" 被 "餐厅" 误匹配
    final sorted = List<String>.from(areas)
      ..sort((a, b) => b.length.compareTo(a.length));
    for (final area in sorted) {
      if (roomName.contains(area)) {
        return area;
      }
    }
    return '其他';
  }

  /// 构建单个房间的展示 Map
  Map<String, dynamic> _buildRoomMap({
    required int roomId,
    required String roomName,
    required String areaType,
    RoomStatusBO? status,
  }) {
    // 状态映射
    String displayStatus;
    String occupancyStatus;
    String roomStatus;
    String cleanStatus;
    String devicePowerStatus;
    String roomNumber;

    if (status != null) {
      roomNumber = status.roomNumber;
      occupancyStatus = status.occupancyStatus;
      roomStatus = status.roomStatus;
      cleanStatus = status.cleanStatus;
      devicePowerStatus = status.devicePowerStatus;

      if (status.occupancyStatus == '1') {
        displayStatus = '入住';
      } else if (status.cleanStatus == '0') {
        displayStatus = '待清洁';
      } else {
        displayStatus = '空闲';
      }
    } else {
      // 无状态数据时用兜底值
      roomNumber = roomName;
      occupancyStatus = '0';
      roomStatus = '0';
      cleanStatus = '0';
      devicePowerStatus = '0';
      displayStatus = '未知';
    }

    return {
      'roomId': roomId,
      'number': roomNumber,
      'roomName': roomName,
      'status': displayStatus,
      'type': areaType,
      'areaType': areaType,
      'occupancyStatus': occupancyStatus,
      'roomStatus': roomStatus,
      'cleanStatus': cleanStatus,
      'devicePowerStatus': devicePowerStatus,
    };
  }

  void selectFloor(String? floor) {
    emit(state.copyWith(selectedFloor: floor));
    if (floor != null) {
      _updateAreasForFloor(floor);
    }
  }

  /// UI 层切换楼层（选中后不能取消，切换时重置类型/房间/搜索，重新加载数据）
  Future<void> toggleFloor(String floorName, int floorId) async {
    if (state.selectedFloor == floorName) return;

    // 计算新楼层的 areas
    final matched = _floorAreasCache.where(
      (f) => f.floorName == floorName,
    );
    final areas = matched.isNotEmpty ? matched.first.areas : <String>[];

    emit(state.copyWith(
      selectedFloor: floorName,
      selectedType: null,
      selectedRoom: null,
      selectedRoomId: null,
      searchText: '',
      areas: areas,
    ));

    try {
      await _loadAllRooms(floorId: floorId);
      _selectFirstTypeAndRoom();
    } catch (e) {
      emit(state.copyWith(error: e.toString()));
    }
  }

  /// UI 层切换区域类型（点击切换，再点取消；切换后默认选中该类型第一个房间）
  void toggleType(String type) {
    final newType = state.selectedType != type ? type : null;
    String? newRoom;
    int? newRoomId;
    if (newType != null) {
      final matchedRoom = state.rooms.firstWhere(
        (r) => r['areaType'] == newType,
        orElse: () => <String, dynamic>{},
      );
      if (matchedRoom.isNotEmpty) {
        newRoom = matchedRoom['number'] as String;
        newRoomId = matchedRoom['roomId'] as int;
      }
    }
    emit(state.copyWith(
      selectedType: newType,
      selectedRoom: newRoom,
      selectedRoomId: newRoomId,
    ));
  }

  /// 获取当前筛选条件下的房间列表
  List<Map<String, dynamic>> getFilteredRooms() {
    List<Map<String, dynamic>> allRooms = state.rooms;

    if (state.selectedType != null) {
      allRooms = allRooms
          .where((room) => room['areaType'] == state.selectedType)
          .toList();
    }

    if (state.searchText.isEmpty) {
      return allRooms;
    }
    return allRooms
        .where((room) => (room['number'] as String)
            .toLowerCase()
            .contains(state.searchText.toLowerCase()))
        .toList();
  }

  /// 获取当前选中房间的完整数据
  Map<String, dynamic>? getSelectedRoomDetail() {
    if (state.selectedRoom == null) return null;
    return _findRoomByNumber(state.selectedRoom!);
  }

  /// 选择房间
  void selectRoom({String? room, int? roomId}) {
    emit(state.copyWith(selectedRoom: room, selectedRoomId: roomId));
  }

  void setSearchText(String text) {
    emit(state.copyWith(searchText: text));
  }

  Future<void> powerOnRoom(String roomNumber) async {
    if (state.isPoweringOn || state.isPoweringOff) return;
    emit(state.copyWith(isPoweringOn: true));
    try {
      final room = _findRoomByNumber(roomNumber);
      if (room == null) {
        throw Exception('未找到房间信息');
      }
      await _roomService.powerOn(roomId: room['roomId'] as int);
      emit(state.copyWith(isPoweringOn: false));
    } catch (e) {
      emit(state.copyWith(isPoweringOn: false));
      rethrow;
    }
  }

  Future<void> powerOffRoom(String roomNumber) async {
    if (state.isPoweringOff || state.isPoweringOn) return;
    emit(state.copyWith(isPoweringOff: true));
    try {
      final room = _findRoomByNumber(roomNumber);
      if (room == null) {
        throw Exception('未找到房间信息');
      }
      await _roomService.powerOff(roomId: room['roomId'] as int);
      emit(state.copyWith(isPoweringOff: false));
    } catch (e) {
      emit(state.copyWith(isPoweringOff: false));
      rethrow;
    }
  }

  /// 根据楼层标签获取楼层 ID
  int? getFloorIdByLabel(String floorLabel) {
    for (final floorMap in (state.floors ?? [])) {
      if (floorMap.values.first == floorLabel) {
        return floorMap.keys.first;
      }
    }
    return null;
  }

  /// 从当前 rooms 中根据房号查找房间数据
  Map<String, dynamic>? _findRoomByNumber(String roomNumber) {
    for (final room in state.rooms) {
      if (room['number'] == roomNumber) {
        return room;
      }
    }
    return null;
  }

  /// 默认选中第一个区域类型和该类型下的第一个房间
  void _selectFirstTypeAndRoom() {
    final areas = state.areas;
    final rooms = state.rooms;
    if (areas.isEmpty || rooms.isEmpty) return;

    final defaultType = areas.first;
    final defaultRoom = rooms.firstWhere(
      (r) => r['areaType'] == defaultType,
      orElse: () => rooms.first,
    );
    emit(state.copyWith(
      selectedType: defaultType,
      selectedRoom: defaultRoom['number'] as String,
      selectedRoomId: defaultRoom['roomId'] as int,
    ));
  }
}