import 'dart:convert';

import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/services/device.m.dart';
import 'package:fis_jsonrpc/services/organization.m.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/entities/device_entities.dart';
import 'package:flyinsono/pages/organization/org_info/state.dart';
import 'package:flyinsono/pages/user/user_device/controller.dart';
import 'package:flyinsono/pages/user/user_device/state.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';

///用户设备控制器
class UserDeviceController {
  ///设备Controller
  late DeviceController controller;

  ///设备Controller状态
  late UserDeviceState state;

  UserDeviceController(DeviceController controller) {
    this.controller = controller;
    this.state = controller.state;
  }

  /// 绑定设备信息（添加设备）
  Future<void> bindDevice(FInteractiveContainer businessParent) async {
    try {
      if (!state.isCanShare) {
        PromptBox.toast(i18nBook.user.deviceUsed.t);
      } else {
        String shortCode = controller.shortCodeController.text;
        if (shortCode.length != 6) {
          PromptBox.toast(i18nBook.common.enterValidCode.t);
          return;
        }
        if (state.terminals.any((element) => element.shortCode == shortCode)) {
          FConfirmAlert.show(
              businessParent: businessParent,
              subTitle: i18nBook.common.deviceAdded.t,
              context: Get.context!,
              title: i18nBook.common.tip.t,
              confrimLabel: i18nBook.common.confirm.t,
              cancelLabel: i18nBook.common.cancel.t,
              onConfirm: () {
                router.back();
                controller.shortCodeController.text = '';
              });
          return;
        }
        String organizationCode = state.deviceInfo.organizationCode ?? '';
        String name = controller.nameEditingController.text;
        if (kIsMobile) {
          name = controller.deviceNameEditingController.text;
        }
        if (shortCode.isNullOrEmpty ||
            // organizationCode.isNullOrEmpty ||
            (state.isOrgDevice && name.isNullOrEmpty)) {
          PromptBox.toast(i18nBook.user.fullFillRequirements.t);
        } else {
          bool bindDeviceResult = false;
          if (state.isOrgDevice) {
            var orgCode = state.deviceInfo.organizationCode;
            bindDeviceResult = await rpc.device.bindDeviceAsync(
              BindDeviceRequest(
                  token: Store.user.token,
                  organizationCode: orgCode == VINNO_DEVICE_CODE
                      ? Store.user.rootOrganizationCode
                      : state.deviceInfo.organizationCode,
                  shortCode: shortCode,
                  name: name,
                  description: name,
                  headPicUrl: state.deviceInfo.coverImage,
                  isAutoShared: state.checked,
                  departmentCode: state.deviceInfo.departmentCode),
            );
          } else {
            bindDeviceResult =
                await rpc.device.scanBindDeviceAsync(ScanBindDeviceRequest(
              token: Store.user.token,
              shortCode: shortCode,
            ));
          }
          if (bindDeviceResult) {
            PromptBox.toast(i18nBook.user.addDeviceSuccess.t);
            await controller.initData();
            controller.closeBindDevice();
          }
        }
      }
    } catch (e) {
      logger.e("bindDeviceAsync terminal datas error:", e);
    }
  }

  /// 移除关联用户
  Future<void> deleteShareDeviceToUserAsync(
      FInteractiveContainer businessParent) async {
    try {
      if (state.selectList.isEmpty) {
        PromptBox.toast(i18nBook.user.selectUserTip.t);
        return;
      }
      FConfirmAlert.show(
        context: Get.context!,
        title: i18nBook.common.tip.t,
        subTitle: i18nBook.user.deleteUserConfirm.t,
        confrimLabel: i18nBook.common.confirm.t,
        cancelLabel: i18nBook.common.cancel.t,
        onConfirm: () async {
          await controller.busyHandle(
            () async {
              final deleteShareDeviceToUserAsync =
                  await rpc.device.deleteShareDeviceToUserAsync(
                DeleteShareDeviceToUserRequest(
                  token: Store.user.token,
                  userCodes: state.selectList,
                  deviceCode: state.selectedTerminal.deviceCode,
                ),
              );
              if (deleteShareDeviceToUserAsync) {
                PromptBox.toast(i18nBook.user.deleteUserSuccess.t);
                await controller.getShareDeviceUsers(
                  state.selectedTerminal.deviceCode!,
                );
                state.batchOperation = false;
              } else {
                PromptBox.toast(i18nBook.user.deleteFailed.t);
              }
            },
            text: i18nBook.user.deleting.t + "...",
          );
        },
        businessParent: businessParent,
      );
    } catch (e) {
      logger.e("bindDeviceAsync terminal datas error:", e);
    }
  }

  /// 获取该机构下面所有部门
  void getOrganization() async {
    List<OrgModel> models = [];
    final result = await rpc.organization.searchOrganizationsAsync(
      SearchOrganizationsRequest(
        organizationType: OrganizationTypeEnum.Department,
        parentCode: Store.user.rootOrganizationCode,
        token: Store.user.token,
      ),
    );
    result.forEach((element) {
      models.add(OrgModel(
          name: element.organizationName!, code: element.organizationCode!));
    });

    state.depOptions = models;
  }

  /// 获取当前机构的所在医院
  Future getOrganizationByCode() async {
    final org = await rpc.organization.getOrganizationByCodeAsync(
      GetOrganizationByCodeRequest(
        organizationCode: Store.user.rootOrganizationCode,
        token: Store.user.token,
      ),
    );
    state.deviceInfo.organizationName = org.organizationName;
    state.deviceInfo.organizationCode = org.organizationCode;
    controller.orgNameController.text = state.deviceInfo.organizationName ?? '';
  }

  ///查找设备类型所有字典项
  Future<void> initDeviceType() async {
    try {
      List<FSelectModel> types = [];
      types.add(FSelectModel(name: i18nBook.common.all.t, code: ""));
      var result = await rpc.device.findDeviceTypeItemsAsync(
        FindDeviceTypeItemsRequest(
          token: Store.user.token,
          dictionaryType: DictionaryTypeEnum.DeviceType,
        ),
      );

      result.forEach((element) {
        var languageConfigs = element.languageConfigs ?? [];
        var deviceType = element.value ?? '';
        var languageCode = i18nBook.locale.toCodeString('-');
        var currentDevice = languageConfigs
            .firstWhereOrNull((element) => element.language == languageCode);
        if (currentDevice != null) {
          deviceType = currentDevice.value ?? '';
        }
        types
            .add(FSelectModel(name: deviceType, code: element.dictionaryCode!));
      });
      state.deviceTypes = types;
      await _initDeviceModel();
    } catch (e) {
      logger.e("_initDeviceType ex", e);
    }
  }

  ///修改设备诊断状态
  Future<void> modifyDeviceDiagnosisModuleStateAsync(
      bool isEnabled, String diagnosisModule) async {
    try {
      var result = await rpc.device.modifyDeviceDiagnosisModuleStateAsync(
        ModifyDeviceDiagnosisModuleStateRequest(
          token: Store.user.token,
          deviceCode: state.selectedTerminal.deviceCode,
          diagnosisModule: diagnosisModule,
          enabled: isEnabled,
        ),
      );
      if (result) {
        controller.findDeviceDiagnosisModulesAsync();
      }
    } catch (e) {
      logger.e("modifyDeviceDiagnosisModuleStateAsync ex", e);
    }
  }

  ///个人设备移除
  Future<void> removePersonDevice() async {
    var request = DeleteShareDeviceToUserRequest(
      token: Store.user.token,
      userCodes: [Store.user.code],
      deviceCode: state.selectedTerminal.deviceCode,
    );

    final result = await rpc.device.deleteShareDeviceToUserAsync(request);
    if (result) {
      PromptBox.toast(i18nBook.user.deleteSuccess.t);
      state.pageIndex = 1;
      await controller.initData();
    } else {
      PromptBox.toast(i18nBook.user.deleteFailed.t);
    }
  }

  ///选中时同步设备信息
  void setDevice() {
    var selectedTerminal = state.selectedTerminal;
    var languageConfigs = selectedTerminal.languageConfigs ?? [];
    var deviceType = selectedTerminal.deviceType;
    var languageCode = i18nBook.locale.toCodeString('-');
    var currentDevice = languageConfigs
        .firstWhereOrNull((element) => element.language == languageCode);
    if (currentDevice != null) {
      deviceType = currentDevice.value;
    }
    // 描述为空，或 描述==name，则为新设备，可编辑备注和封面
    state.deviceInfo.isNewDevice = selectedTerminal.description == null ||
        selectedTerminal.description!.isEmpty ||
        selectedTerminal.description == selectedTerminal.name;
    state.deviceInfo.deviceModel = selectedTerminal.deviceModel;
    state.deviceInfo.shortCode = selectedTerminal.shortCode;
    state.deviceInfo.deviceType = deviceType;
    state.deviceInfo.description = selectedTerminal.displayName;
    state.deviceInfo.departmentCode = selectedTerminal.departmentCode;
    state.deviceInfo.coverImage = selectedTerminal.headPicUrl;
    state.checked = selectedTerminal.isAutoShared;
  }

  /// 手机端分享设备的提交
  Future<void> submitMobileUsers() async {
    try {
      controller.busy = true;
      List<String> addCodes = [];
      List<String> removeCodes = [];
      state.shareUserSelectList.forEach(
        (element) {
          final users = state.tableDataSource
              .firstWhereOrNull((s) => s.userCode == element);
          if (users == null) {
            addCodes.add(element);
          }
        },
      );
      state.tableDataSource.forEach(
        (element) {
          final user = state.shareUserSelectList
              .firstWhereOrNull((s) => s == element.userCode);
          if (user == null) {
            removeCodes.add(element.userCode!);
          }
        },
      );
      var addResult = false;
      if (addCodes.length > 0) {
        addResult = await rpc.device.createShareDeviceToUserAsync(
          CreateShareDeviceToUserRequest(
            token: Store.user.token,
            deviceCode: state.selectedTerminal.deviceCode,
            userCodes: addCodes,
          ),
        );
      } else {
        addResult = true;
      }
      var removeResult = false;
      if (removeCodes.length > 0) {
        removeResult = await rpc.device.deleteShareDeviceToUserAsync(
          DeleteShareDeviceToUserRequest(
            token: Store.user.token,
            deviceCode: state.selectedTerminal.deviceCode,
            userCodes: removeCodes,
          ),
        );
      } else {
        removeResult = true;
      }
      if (addResult && removeResult) {
        PromptBox.toast(i18nBook.user.operationSuccess.t);
        await controller
            .getShareDeviceUsers(state.selectedTerminal.deviceCode!);
        router.back();
      } else {
        PromptBox.toast(i18nBook.user.operationFailed.t);
      }
    } catch (e) {
      logger.e('submitUsers', e);
    }
    controller.busy = false;
  }

  ///分享设备提交
  Future<void> submitUsers() async {
    try {
      controller.busy = true;
      List<String> addCodes = [];
      List<String> removeCodes = [];
      state.selectedUsers.forEach(
        (element) {
          final users = controller.shareUsers
              .firstWhereOrNull((s) => s.userCode == element.userCode);
          if (users == null) {
            addCodes.add(element.userCode!);
          }
        },
      );

      controller.shareUsers.forEach(
        (element) {
          final users = state.selectedUsers
              .firstWhereOrNull((s) => s.userCode == element.userCode);
          if (users == null) {
            removeCodes.add(element.userCode!);
          }
        },
      );
      var addResult = false;
      if (addCodes.length > 0) {
        addResult = await rpc.device.createShareDeviceToUserAsync(
          CreateShareDeviceToUserRequest(
            token: Store.user.token,
            deviceCode: state.selectedTerminal.deviceCode,
            userCodes: addCodes,
          ),
        );
      } else {
        addResult = true;
      }
      var removeResult = false;
      if (removeCodes.length > 0) {
        removeResult = await rpc.device.deleteShareDeviceToUserAsync(
          DeleteShareDeviceToUserRequest(
            token: Store.user.token,
            deviceCode: state.selectedTerminal.deviceCode,
            userCodes: removeCodes,
          ),
        );
      } else {
        removeResult = true;
      }
      if (addResult && removeResult) {
        controller.busy = false;

        await controller
            .getShareDeviceUsers(state.selectedTerminal.deviceCode!);
        PromptBox.success(i18nBook.remedical.shareTerminalSuccess.t);
        router.back();
      } else {
        PromptBox.toast(i18nBook.user.operationFailed.t);
      }
    } catch (e) {
      logger.e('submitUsers', e);
    }
    controller.busy = false;
  }

  ///更新超声机信息
  Future<void> updateTerminalInfo() async {
    try {
      String description = state.deviceInfo.description ?? '';
      if (kIsMobile) {
        description = controller.deviceNameEditingController.text;
      }
      final image = state.deviceInfo.coverImage;
      final department = state.deviceInfo.departmentCode;
      final isAutoShare = state.checked;
      //final shortCode = controller.shortCodeController.text;
      final selectedTermianl = state.terminals[state.selectTerminalCardIndex];
      final termianlJson = jsonEncode(selectedTermianl.toJson());
      final termianlJsonMapCP = jsonDecode(termianlJson);
      // 深拷贝，才能更新Obx
      final termianl = DeviceExtendInfoDTO.fromJson(termianlJsonMapCP);
      logger.i(
          'update description:$description,imageUrl:$image,departmentCode:$department,Auto share:$isAutoShare,shortCode${termianl.shortCode}');
      final result = await rpc.device.modifyDeviceAsync(
        ModifyDeviceRequest(
          deviceCode: termianl.deviceCode,
          departmentCode: department ?? '',
          description: description,
          headPicUrl: image,
          token: Store.user.token,
          isAutoShared: state.checked,
        ),
      );
      if (result) {
        termianl.displayName = description;
        termianl.description = description;
        termianl.departmentCode = department;
        termianl.headPicUrl = image;
        //termianl.shortCode = shortCode;
        termianl.isAutoShared = isAutoShare;
        state.selectedTerminal = termianl;
        state.terminals[state.selectTerminalCardIndex] = termianl;
        PromptBox.toast(i18nBook.user.updateSuccess.t);
        router.back();
      } else {
        PromptBox.toast("i18nBook.user.updatefailed.t");
      }
    } catch (e) {
      logger.e('updateTerminalInfo ex:', e);
    }
  }

  ///查找设备型号所有字典项
  Future<void> _initDeviceModel() async {
    try {
      List<FSelectModel> models = [];
      models.add(FSelectModel(name: i18nBook.common.all.t, code: ""));
      var result = await rpc.device.findDeviceModelItemsAsync(
        FindDeviceModelItemsRequest(
            token: Store.user.token,
            dictionaryType: DictionaryTypeEnum.DeviceType,
            deviceTypeCode: ""),
      );
      result.forEach(
        (element) {
          models.add(
            FSelectModel(
              name: element.value!,
              code: element.dictionaryCode!,
            ),
          );
        },
      );
      state.deviceModels = models;
    } catch (e) {
      logger.e("_initDeviceModel ex:", e);
    }
  }
}
