import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/Interfaces/user_info.dart';
import 'package:flyinsono/managers/interfaces/entities/device_entities.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/muti_select.dart';
import 'package:flyinsono/pages/user/user_device/controller.dart';
import 'package:flyinsono/pages/user/user_device/entrtys/device_info.dart';
import 'package:flyinsono/pages/user/user_device/state.dart';
import 'package:flyinsono/pages/user/user_device/widgets/add_or_edit_terminal.dart';
import 'package:flyinsono/pages/user/user_device/widgets/find_terminal.dart';
import 'package:flyinsono/pages/user/user_device/widgets/share_terminal_page.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';

///组织设备控制器
class OrgDeviceController {
  ///设备Controller
  late DeviceController controller;
  late UserDeviceState state;
  OrgDeviceController(DeviceController controller) {
    this.controller = controller;
    this.state = controller.state;
  }

  ///添加设备
  void addTerminalDevice() {
    // var device = state.deviceInfo;
    // device.deviceModel = '';
    // device.shortCode = '';
    // device.deviceType = '';
    // device.name = '';
    // device.description = '';
    // device.departmentCode = null;
    // device.coverImage = '';
    state.deviceInfo = DeviceInfo();
    controller.nameEditingController.text = '';
    controller.deviceTypeController.text = '';
    controller.deviceModelController.text = '';
    state.checked = true;
    controller.orgNameController.text = '';
    router.dialog(
      () => AddorEditTerminalPage(),
    );
  }

  ///筛选超声机
  Future<void> findTerminalByParameters() async {
    try {
      final deviceModeCode = state.deviceModel;
      final deviceTypeCode = state.deviceType;
      final status = state.deviceStatus;
      var getPersonDeviceRequest = GetPersonDeviceRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 20,
        keyWord: '',
        organizationCodes: state.selectedOrganizationLocated,
      );
      if (status == OnlineStatus.Online) {
        getPersonDeviceRequest.isOnline = true;
      } else if (status == OnlineStatus.OffLine) {
        getPersonDeviceRequest.isOnline = false;
      }
      if (deviceModeCode.isNotEmpty) {
        getPersonDeviceRequest.deviceModel = state.deviceModel;
      }
      if (deviceTypeCode.isNotEmpty) {
        getPersonDeviceRequest.deviceType = deviceTypeCode;
      }
      PageCollection<DeviceExtendInfoDTO> result;

      /// 机构管理员查询
      if (state.isOrgDevice) {
        result = await rpc.device
            .getOrganizationDeviceListAsync(getPersonDeviceRequest);
      } else {
        /// 非机构管理员查询
        result =
            await rpc.device.getPersonDeviceListAsync(getPersonDeviceRequest);
      }
      state.terminals = result.pageData ?? [];
      if (state.terminals.length > 0) {
        state.selectedTerminal = state.terminals[0];
        controller.deviceCodeController.text =
            state.selectedTerminal.shortCode!;
        getShareDeviceUsers(state.selectedTerminal.deviceCode ?? '');
        if (state.isOrgDevice) {
          controller.findDeviceDiagnosisModulesAsync();
        }
      }
    } catch (e) {
      logger.e('findTerminalByParameters ex:', e);
    }
    router.back();
  }

  ///打开筛选超声机页面
  void findTerminals() {
    router.dialog(
      () => FindTerminalPage(),
    );
  }

  /// 通过deviceCode来获取设备信息 自动回填
  Future<void> getDeviceInfo(String value, {bool isFromParam = false}) async {
    controller.busy = true;
    try {
      final deviceInfo = await rpc.device.getDeviceByShortCodeAsync(
        GetDeviceByShortCodeRequest(
          token: Store.user.token,
          shortCode: value,
        ),
      );
      var languageConfigs = deviceInfo.languageConfigs ?? [];
      var deviceType = deviceInfo.deviceType;
      var languageCode = i18nBook.locale.toCodeString('-');
      var currentDevice = languageConfigs
          .firstWhereOrNull((element) => element.language == languageCode);
      if (currentDevice != null) {
        deviceType = currentDevice.value;
      }
      final deviceModel = deviceInfo.deviceModel;
      final deviceName = deviceInfo.displayName ?? '';
      final deviceDescription = deviceInfo.description ?? '';
      state.deviceInfo.deviceModel = deviceModel;
      state.deviceInfo.deviceType = deviceType;
      // 描述为空，或 描述==name，则为新设备，可编辑备注和封面
      state.deviceInfo.isNewDevice = deviceInfo.description == null ||
          deviceInfo.description!.isEmpty ||
          deviceInfo.description == deviceInfo.name;
      controller.deviceTypeController.text = deviceType ?? '';
      controller.deviceModelController.text = deviceModel ?? '';
      state.deviceInfo.description = deviceDescription;
      if (deviceName.isNotNullOrEmpty) {
        if (kIsMobile) {
          controller.deviceNameEditingController.text =
              deviceInfo.description ?? '';
        }
        controller.nameEditingController.text = deviceName;
      }
      if (deviceInfo.departmentCode != null &&
          deviceInfo.departmentCode!.isNotEmpty) {
        if (state.depOptions
            .any((element) => element.code == deviceInfo.departmentCode)) {
          state.deviceInfo.departmentCode = deviceInfo.departmentCode;
        }
      } else {
        state.deviceInfo.departmentCode = '';
      }
      if (deviceInfo.organizationName.isNotNullOrEmpty) {
        state.deviceInfo.organizationName =
            (deviceInfo.organizationCode == VINNO_DEVICE_CODE &&
                    state.isOrgDevice &&
                    Store.user.isPrincipal)
                ? Store.user.rootOrganizationName
                : deviceInfo.organizationName;
        print(state.deviceInfo.organizationName);
        state.deviceInfo.organizationCode = deviceInfo.organizationCode;
        controller.orgNameController.text =
            state.deviceInfo.organizationName ?? '';
      }
      state.deviceInfo.coverImage = deviceInfo.headPicUrl;
      state.checked = deviceInfo.isAutoShared;

      /// 机构设备页面判断该设备是否绑过机构
      if ((deviceInfo.organizationCode.isNotNullOrEmpty &&
              deviceInfo.organizationCode != VINNO_DEVICE_CODE) &&
          deviceInfo.organizationCode != Store.user.rootOrganizationCode &&
          controller.state.isOrgDevice) {
        state.isCanShare = false;
        PromptBox.toast(i18nBook.user.deviceUsed.t);
      } else {
        state.isCanShare = true;
      }

      if (!isFromParam) {
        // 不是从传参来的，手动填的，需要验证
        final userInfo = await rpc.user.getUserInfoAsync(
          GetUserInfoRequest(token: Store.user.token),
        );
        if (userInfo.bindDevices?.contains(deviceInfo.deviceCode) == true) {
          PromptBox.toast(i18nBook.user.deviceAlreadyAdded.t);
        }
      }

      controller.busy = false;
    } catch (e) {
      controller.busy = false;
      logger.e("getDeviceInfoAsync terminal datas error:", e);
    }
  }

  /// 获取选择的关联的用户
  void getSelectedIdxs(List selectIndexList) {
    List<String> selectList = [];
    selectIndexList.forEach((element) {
      selectList.add(state.tableDataSource[element].userCode!);
    });
    state.selectList = selectList;
  }

  /// 获取分享设备用户集合
  Future<void> getShareDeviceUsers(String deviceCode) async {
    controller.busy = true;
    final getShareDeviceUsersList = await rpc.user.getShareDeviceUsersAsync(
      GetShareDeviceUsersPageRequest(
        deviceCode: deviceCode,
        pageIndex: 1,
        pageSize: 100,
        token: Store.user.token,
      ),
    );
    state.tableDataSource =
        _convertShareUsers(getShareDeviceUsersList.pageData ?? []);
    controller.busy = false;
  }

  /// 初始化分享用户所需数据
  Future<void> initOrgUsers({String keyword = ''}) async {
    try {
      controller.busy = true;
      state.users.clear();
      state.selectedUsers.clear();
      state.deps.clear();
      final orgInfo = await rpc.organization.getOrganizationByCodeAsync(
        GetOrganizationByCodeRequest(
          token: Store.user.token,
          organizationCode: Store.user.rootOrganizationCode,
        ),
      );
      Store.user.rootOrganizationName = orgInfo.organizationName ?? '';
      var request = GetUserListRequest(
        token: Store.user.token,
        language: i18nBook.locale.toCodeString('-'),
        organizationQueryType: OrganizationQueryTypeEnum.All,
        organizationCode: Store.user.rootOrganizationCode,
        exceptSelf: true,
        keyword: keyword,
      );

      state.allUsers.clear();
      var users = await rpc.user.getUserListAsync(request);
      var convertUsers = _convertUsers(users);
      state.users = convertUsers;
      state.allUsers.addAll(convertUsers);
      final deps = await rpc.organization.searchOrganizationsAsync(
        SearchOrganizationsRequest(
          token: Store.user.token,
          parentCode: Store.user.rootOrganizationCode,
          organizationType: OrganizationTypeEnum.Department,
        ),
      );
      state.deps = deps;
      final getShareDeviceUsersList = await rpc.user.getShareDeviceUsersAsync(
        GetShareDeviceUsersPageRequest(
          deviceCode: state.selectedTerminal.deviceCode,
          pageIndex: 1,
          pageSize: 10000,
          token: Store.user.token,
        ),
      );
      if (getShareDeviceUsersList.pageData != null) {
        controller.shareUsers =
            _convertShareUsers(getShareDeviceUsersList.pageData ?? []);
        getShareDeviceUsersList.pageData!.forEach(
          (element) {
            final shareUser = users
                .firstWhereOrNull((user) => user.userCode == element.userCode);
            if (shareUser != null) {
              state.selectedUsers.add(shareUser);
            }
          },
        );
      }

      controller.busy = false;
    } catch (e) {
      logger.e('_initOrgUsers ex:', e);
    }
  }

  ///树形结构点击事件
  bool onNodeTap(String v) {
    final user =
        state.users.firstWhereOrNull((element) => element.userCode == v);
    if (user == null) {
      return false;
    } else {
      if (state.selectedUsers.any((element) => element.userCode == v)) {
        state.selectedUsers.remove(user);
      } else {
        state.selectedUsers.add(user);
      }
      return true;
    }
  }

  ///移除组织超声机
  Future<void> removeOrgTerminal(FInteractiveContainer businessParent) async {
    try {
      final count = state.tableDataSource.length;
      var alertMessage = '';
      if (count > 0) {
        alertMessage = i18nBook.user.deviceShared.translate([count]);
      } else {
        alertMessage = i18nBook.user.deleteDeviceConfirm.t;
      }
      FConfirmAlert.show(
        businessParent: businessParent,
        context: Get.context!,
        title: count > 0 ? i18nBook.user.deleteDevice.t : i18nBook.common.tip.t,
        subTitle: alertMessage,
        confrimLabel: i18nBook.user.deleteDevice.t,
        cancelLabel:
            count > 0 ? i18nBook.user.roger.t : i18nBook.common.cancel.t,
        onConfirm: () async {
          await controller.busyHandle(
            () async {
              await _removeOrgDevice();
            },
            text: i18nBook.user.deleting.t + "...",
          );
        },
        isCancelPrimary: count > 0,
        isConfirmReadonly: count > 0,
      );
    } catch (e) {
      logger.e("removeTerminal ex", e);
      PromptBox.toast(i18nBook.user.deleteFailed.t);
    }
  }

  ///移除超声机
  Future<void> removeTerminal(FInteractiveContainer businessParent) async {
    try {
      if (state.isOrgDevice) {
        await removeOrgTerminal(businessParent);
      } else {
        FConfirmAlert.show(
          context: Get.context!,
          title: i18nBook.common.tip.t,
          subTitle: i18nBook.user.deleteDeviceConfirm.t,
          confrimLabel: i18nBook.common.confirm.t,
          cancelLabel: i18nBook.common.cancel.t,
          onConfirm: () async {
            await controller.busyHandle(
              () async {
                await controller.removePersonDevice();
              },
              text: i18nBook.user.deleting.t + "...",
            );
          },
          businessParent: businessParent,
        );
      }
    } catch (e) {
      logger.e("removeTerminal ex", e);
      PromptBox.toast(i18nBook.user.deleteFailed.t);
    }
  }

  /// 分享设备
  Future<void> shareTerminal() async {
    await initOrgUsers();
    router.dialog(
      () => ShareTerminalPage(),
    );
  }

  ///修改设备信息
  void updateTerminal() {
    controller.setDevice();
    controller.resetDeviceName();
    router.dialog(
      () => AddorEditTerminalPage(
        isEdit: true,
      ),
    );
  }

  /// 所属机构
  Future<void> getOrganizationByUserAndDevicesAsync() async {
    try {
      final result =
          await rpc.organization.getOrganizationByUserAndDevicesAsync(
        GetOrganizationByUserAndDevicesRequest(
          token: Store.user.token,
          pageIndex: 1,
          pageSize: 100,
          onlyOrganization: state.isOrgDevice,
        ),
      );
      List<FMutiSelectModel> _organizationLocatedList = [];
      for (OrganizationSimplifyDTO i in result.pageData ?? []) {
        _organizationLocatedList.add(
          FMutiSelectModel(
            code: i.organizationCode!,
            name: i.organizationName!,
          ),
        );
      }
      state.organizationLocatedList = _organizationLocatedList;
    } catch (e) {
      printError(
          info:
              "getOrganizationByUserAndDevicesAsync exception:" + e.toString());
      logger.e("getOrganizationByUserAndDevicesAsync exception:", e);
    }
  }

  List<ShareDeviceUserDTO> _convertShareUsers(List<ShareDeviceUserDTO> list) {
    List<ShareDeviceUserDTO> result = [];
    for (var user in list) {
      user.fullName = user.fullName ?? '';
      user.phone = user.phone ?? '';
      result.add(user);
    }
    return result;
  }

  List<UserExtendDTO> _convertUsers(List<UserExtendDTO> users) {
    List<UserExtendDTO> result = [];
    for (var user in users) {
      user.fullName = user.fullName ?? '';
      user.phone = user.phone ?? '';
      result.add(user);
    }
    return result;
  }

  ///移除组织设备
  Future<void> _removeOrgDevice() async {
    final result = await rpc.device.removeDeviceRelevancyAsync(
      RemoveDeviceRelevancyRequest(
        token: Store.user.token,
        organizationCode: state.selectedTerminal.organizationCode,
        departmentCode: state.selectedTerminal.departmentCode,
        deviceCode: state.selectedTerminal.deviceCode,
      ),
    );
    if (result) {
      PromptBox.toast(i18nBook.user.deleteSuccess.t);
      state.pageIndex = 1;
      await controller.initData();
    } else {
      PromptBox.toast(i18nBook.user.deleteFailed.t);
    }
  }
}
