import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/models/bo/inspection_room_bo.dart';
import 'package:smart_hotel_app/repositories/inspection_device_repository.dart';
import 'package:smart_hotel_app/repositories/inspection_room_repository.dart';
import 'package:smart_hotel_app/services/inspection_device_service.dart';
import 'package:smart_hotel_app/services/inspection_room_service.dart';
import 'package:smart_hotel_app/views/home/inspection/cubit/inspection_state.dart';

class InspectionCubit extends Cubit<InspectionState> {
  final InspectionRoomService _roomService;
  final InspectionDeviceService _deviceService;

  static const int pageSize = 20;

  /// 完整房间列表缓存，用于在切换 Tab 时按 runStatus 重新过滤
  List<InspectionRoomBO> _allRoomsRaw = const [];

  InspectionCubit({
    InspectionRoomService? roomService,
    InspectionDeviceService? deviceService,
  })  : _roomService = roomService ??
            InspectionRoomService(repository: InspectionRoomRepository()),
        _deviceService = deviceService ??
            InspectionDeviceService(
                repository: InspectionDeviceRepository()),
        super(const InspectionState(isLoading: true)) {
    initData();
  }

  Future<void> initData() async {
    try {
      final rooms = await _roomService.getRooms();
      _allRoomsRaw = rooms;

      final tabCounts = _computeTabCounts(rooms);
      final filteredRooms = _filterRooms(rooms, state.selectedTab);

      // 仅当首次进入（之前没有选过房间）时，默认选中过滤后的第一个房间
      final initialRoomIds = filteredRooms.isNotEmpty
          ? [filteredRooms.entries.first.key]
          : <int>[];

      emit(state.copyWith(
        isLoading: false,
        error: null,
        allRooms: filteredRooms,
        selectedRoomIds: initialRoomIds,
        tabCounts: tabCounts,
      ));
    } catch (e) {
      emit(state.copyWith(
        isLoading: false,
        error: e.toString(),
      ));
    }
  }

  /// 供 PagingController.fetchPage 回调使用
  Future<List<InspectionDevice>> fetchPage(int pageKey) async {
    final roomId = state.selectedRoomIds.length == 1
        ? state.selectedRoomIds.first
        : null;

    final result = await _deviceService.getList(
      pageSize: pageSize,
      pageNum: pageKey,
      roomId: roomId,
      runStatus: state.selectedTab.runStatus,
    );

    // 首页时记录总数，供翻页判断是否到底
    if (pageKey == 1) {
      emit(state.copyWith(totalCount: result.total));
    }

    return result.data
        .map((e) => InspectionDevice.fromInspectionDeviceBO(e))
        .toList();
  }

  Map<DeviceStatusTab, int> _computeTabCounts(List<InspectionRoomBO> rooms) {
    int normal = 0;
    int warning = 0;
    int offline = 0;
    int fault = 0;

    for (final room in rooms) {
      normal += room.runStatus.normal;
      warning += room.runStatus.warning;
      offline += room.runStatus.offline;
      fault += room.runStatus.fault;
    }

    return {
      DeviceStatusTab.total: normal + warning + offline + fault,
      DeviceStatusTab.on: normal,
      DeviceStatusTab.off: 0,
      DeviceStatusTab.offline: offline,
      DeviceStatusTab.alarm: warning,
      DeviceStatusTab.fault: fault,
    };
  }

  /// 根据 Tab 的 runStatus 过滤房间：
  /// - total / runStatus 为 null → 返回全部
  /// - 其他 → 仅保留对应状态计数 > 0 的房间
  Map<int, String> _filterRooms(
      List<InspectionRoomBO> rooms, DeviceStatusTab tab) {
    final result = <int, String>{};
    for (final room in rooms) {
      if (_roomMatchesTab(room, tab)) {
        result[room.roomId] = room.roomNumber;
      }
    }
    return result;
  }

  bool _roomMatchesTab(InspectionRoomBO room, DeviceStatusTab tab) {
    switch (tab) {
      case DeviceStatusTab.total:
        return true;
      case DeviceStatusTab.on:
        return room.runStatus.normal > 0;
      case DeviceStatusTab.off:
      case DeviceStatusTab.offline:
        return room.runStatus.offline > 0;
      case DeviceStatusTab.alarm:
        return room.runStatus.warning > 0;
      case DeviceStatusTab.fault:
        return room.runStatus.fault > 0;
    }
  }

  void selectTab(DeviceStatusTab tab) {
    final filteredRooms = _filterRooms(_allRoomsRaw, tab);

    // 过滤后剔除已不存在的已选房间；若全被剔除则默认选第一个
    final keptSelection = state.selectedRoomIds
        .where(filteredRooms.containsKey)
        .toList();
    final newSelectedRoomIds = keptSelection.isNotEmpty
        ? keptSelection
        : (filteredRooms.isNotEmpty
            ? [filteredRooms.entries.first.key]
            : <int>[]);

    emit(state.copyWith(
      selectedTab: tab,
      allRooms: filteredRooms,
      selectedRoomIds: newSelectedRoomIds,
    ));
  }

  void toggleRoom(int roomId) {
    final List<int> newSelected = List.from(state.selectedRoomIds);
    if (newSelected.contains(roomId)) {
      newSelected.remove(roomId);
    } else {
      newSelected.clear();
      newSelected.add(roomId);
    }
    emit(state.copyWith(selectedRoomIds: newSelected));
  }
}