import 'dart:collection';

import 'package:fis_jsonrpc/rpc.dart';
import 'package:get/get.dart';
import 'package:vnoteapp/architecture/defines.dart';
import 'package:vnoteapp/managers/interfaces/label.dart';

/// 人群分类标签控制器
class CrowdLabelsController extends FControllerBase {
  final state = CrowdLablesState();

  final _manager = Get.find<ILabelManager>();

  @override
  void onReady() {
    super.onReady();
    _loadOptions();
  }

  void onNormalSelectedChanged(List<String> codes) {
    state.selectedNormalCodes = codes;
  }

  void onDiseaseSelectedChanged(List<String> codes) {
    state.selectedDiseaseCodes = codes;
  }

  void onSpecialCareSelectedChanged(List<String> codes) {
    state.selectedSpecialCareCodes = codes;
  }

  void onItemCheckChanged(String code, bool isChecked) {
    bool result = false;
    result = _updateNormalChecked(code, isChecked);
    if (result) return;
    result = _updateDiseaseChecked(code, isChecked);
    if (result) return;
    result = _updateSpecialCareChecked(code, isChecked);
  }

  bool _updateNormalChecked(code, bool isChecked) {
    final item = state.normalOptions.firstWhereOrNull((e) => e.code == code);
    if (item == null) return false;

    final arr = state.selectedNormalCodes;
    if (isChecked) {
      if (arr.contains(code) == false) {
        arr.add(code);
      }
    } else {
      arr.remove(code);
    }
    state.selectedNormalCodes = arr;
    return true;
  }

  bool _updateDiseaseChecked(code, bool isChecked) {
    final item = state.diseaseOptions.firstWhereOrNull((e) => e.code == code);
    if (item == null) return false;

    final arr = state.selectedDiseaseCodes;
    if (isChecked) {
      if (arr.contains(code) == false) {
        arr.add(code);
      }
    } else {
      arr.remove(code);
    }
    state.selectedDiseaseCodes = arr;
    return true;
  }

  bool _updateSpecialCareChecked(code, bool isChecked) {
    final item =
        state.specialCareOptions.firstWhereOrNull((e) => e.code == code);
    if (item == null) return false;

    final arr = state.selectedSpecialCareCodes;
    if (isChecked) {
      if (arr.contains(code) == false) {
        arr.add(code);
      }
    } else {
      arr.remove(code);
    }
    state.selectedSpecialCareCodes = arr;
    return true;
  }

  Future<void> _loadOptions() async {
    // TODO: Future.await()
    state.normalOptions = await _manager.getNormalCrowdLabels();
    // TODO:
    state.diseaseOptions = (await _manager.getDiseaseCrowdLabels())
      ..removeLast();
    // state.diseaseOptions = await _manager.getDiseaseCrowdLabels();
    state.specialCareOptions = await _manager.getSpecialCareCrowdLabels();
  }
}

/// 人群分类标签状态
class CrowdLablesState {
  final RxList<LabelDTO> _normalOptions = RxList<LabelDTO>();
  final RxList<LabelDTO> _diseaseOptions = RxList<LabelDTO>();
  final RxList<LabelDTO> _specialCareOptions = RxList<LabelDTO>();
  final RxList<String> _selectedNormalCodes = RxList<String>();
  final RxList<String> _selectedDiseaseCodes = RxList<String>();
  final RxList<String> _selectedSpecialCareCodes = RxList<String>();

  /// 一般人群分类选项集合
  List<LabelDTO> get normalOptions =>
      UnmodifiableListView(_normalOptions.toList());
  set normalOptions(List<LabelDTO> val) => _normalOptions.value = val;

  /// 疾病人群分类选项集合
  List<LabelDTO> get diseaseOptions =>
      UnmodifiableListView(_diseaseOptions.toList());
  set diseaseOptions(List<LabelDTO> val) => _diseaseOptions.value = val;

  /// 特殊照顾人群分类选项集合
  List<LabelDTO> get specialCareOptions =>
      UnmodifiableListView(_specialCareOptions.toList());
  set specialCareOptions(List<LabelDTO> val) => _specialCareOptions.value = val;

  /// 一般人群分类 已选择Code集合
  List<String> get selectedNormalCodes =>
      UnmodifiableListView(_selectedNormalCodes.toList());
  set selectedNormalCodes(List<String> val) => _selectedNormalCodes.value = val;

  /// 疾病人群分类 已选择Code集合
  List<String> get selectedDiseaseCodes =>
      UnmodifiableListView(_selectedDiseaseCodes.toList());
  set selectedDiseaseCodes(List<String> val) =>
      _selectedDiseaseCodes.value = val;

  /// 特殊照顾人群分类 已选择Code集合
  List<String> get selectedSpecialCareCodes =>
      UnmodifiableListView(_selectedSpecialCareCodes.toList());
  set selectedSpecialCareCodes(List<String> val) =>
      _selectedSpecialCareCodes.value = val;

  /// 所有 已选择Code集合
  List<String> get selectedCodes {
    final array = <String>[];
    array.addAll(_selectedNormalCodes);
    array.addAll(_selectedDiseaseCodes);
    array.addAll(_selectedSpecialCareCodes);
    return array;
  }

  /// 所有 已选择标签名称集合
  List<String> get selectedNames {
    final array = <String>[];
    for (var code in _selectedNormalCodes) {
      array.add(_getNameByCode(_normalOptions, code)!);
    }
    for (var code in _selectedDiseaseCodes) {
      array.add(_getNameByCode(_diseaseOptions, code)!);
    }
    for (var code in _selectedSpecialCareCodes) {
      array.add(_getNameByCode(_specialCareOptions, code)!);
    }
    return array;
  }

  static String? _getNameByCode(List<LabelDTO> source, String code) {
    final dto = source.firstWhereOrNull((e) => e.code == code);
    return dto?.labelName;
  }
}
