import 'package:fis_jsonrpc/rpc.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:get/get.dart';

///会诊成员
class ConsultationMember {
  int? index;
  int sortLevel;
  String? id;
  String? name;
  LiveMemberEnum memberType = LiveMemberEnum.User;
  MemberRoleType roleType = MemberRoleType.Local;
  String? headImageToken;
  bool isOnline = false;
  bool mute = false;
  bool videoOpend = false;
  bool isInitiator = false;
  bool isBusy = false;
  MemberStatus status = MemberStatus.Default;
  LiveData? liveData;
  bool mergedChannel = false;
  int mergedVideoOutputWidth = 0;
  int mergedVideoOutputHeight = 0;
  List<VideoDeviceOutputInfo>? videoDeviceInfos;
  LiveConsultationJoinDeviceInfo? consultationDeviceInfo;
  bool isOldPlatform = false;
  bool supportRtc = false;

  ConsultationMember({
    this.id,
    this.name,
    this.memberType = LiveMemberEnum.User,
    this.roleType = MemberRoleType.Local,
    this.headImageToken,
    this.isOnline = false,
    this.mute = false,
    this.videoOpend = true,
    this.isInitiator = false,
    this.isBusy = false,
    this.status = MemberStatus.Default,
    this.liveData,
    this.mergedChannel = false,
    this.mergedVideoOutputWidth = 0,
    this.mergedVideoOutputHeight = 0,
    this.sortLevel = 0,
    this.videoDeviceInfos,
    this.index,
    this.isOldPlatform = false,
    this.supportRtc = false,
    this.consultationDeviceInfo,
  });

  factory ConsultationMember.fromDto(LiveConsultationMember m) {
    var roleType = MemberRoleType.Device;
    if (m.memberType == LiveMemberEnum.User) {
      roleType = Store.user.code == m.id
          ? MemberRoleType.Local
          : MemberRoleType.Remote;
    }

    return ConsultationMember(
      id: m.id,
      name: m.name,
      memberType: m.memberType,
      roleType: roleType,
      headImageToken: m.headImageToken,
      isOnline: m.isOnline,
      mute: m.mute,
      videoOpend: m.videoOpend,
      isInitiator: m.isInitiator,
      isBusy: m.isBusy,
      status: MemberStatus.values
              .firstWhereOrNull((element) => element.index == m.status.index) ??
          MemberStatus.Default,
      liveData: m.liveData,
      mergedChannel: m.mergedChannel,
      mergedVideoOutputHeight: m.mergedVideoOutputHeight,
      mergedVideoOutputWidth: m.mergedVideoOutputWidth,
      videoDeviceInfos: m.videoDeviceInfos,
      index: m.sortNumber,
      sortLevel: m.sortLevel,
      isOldPlatform: m.isOldPlatform,
      supportRtc: m.supportRtc,
    );
  }

  ConsultationMember fixMergedVideoOutputSize() {
    /// 修正老版本单图合流模式下的总尺寸
    if (isOldPlatform &&
        videoDeviceInfos != null &&
        videoDeviceInfos!.length == 1) {
      int width = videoDeviceInfos![0].outputWidth;
      int height = videoDeviceInfos![0].outputHeight;
      if (width <= 640 && height <= 480) {
        mergedVideoOutputWidth = 640;
        mergedVideoOutputHeight = 480;
      } else if (width <= 960 && height <= 544) {
        mergedVideoOutputWidth = 960;
        mergedVideoOutputHeight = 540;
      } else if (width <= 960 && height <= 720) {
        mergedVideoOutputWidth = 960;
        mergedVideoOutputHeight = 720;
      } else if (width <= 1280 && height <= 720) {
        mergedVideoOutputWidth = 1280;
        mergedVideoOutputHeight = 720;
      } else {
        mergedVideoOutputWidth = 1920;
        mergedVideoOutputHeight = 1080;
      }
    }

    /// 修正老版本双路合流模式下的总尺寸
    if (isOldPlatform &&
        videoDeviceInfos != null &&
        videoDeviceInfos!.length == 2) {
      if (videoDeviceInfos![0].videoDeviceSourceType ==
          VideoDeviceSourceTypeEnum.Desktop) {
        int width = videoDeviceInfos![0].outputWidth;
        int height = videoDeviceInfos![0].outputHeight;
        int subWidth = videoDeviceInfos![1].outputWidth;
        int subHeight = videoDeviceInfos![1].outputHeight;
        if (width <= 640 && height <= 480) {
          mergedVideoOutputWidth = 640;
          mergedVideoOutputHeight = 480;
        } else if (width <= 960 && height <= 544) {
          mergedVideoOutputWidth = 1280;
          mergedVideoOutputHeight = 720;
        } else if (width <= 960 && height <= 720) {
          mergedVideoOutputWidth = 1440;
          mergedVideoOutputHeight = 720;
        } else if (width <= 1280 && height <= 720) {
          mergedVideoOutputWidth = 1920;
          mergedVideoOutputHeight = 1080;
        } else {
          mergedVideoOutputWidth = 1920;
          mergedVideoOutputHeight = 1080;
        }

        /// 特殊情况：魔盒下无论画面为多大，总画面都是1920*1080
        /// 魔盒下的摄像头为 640*480
        if (subWidth == 640 && subHeight == 480) {
          mergedVideoOutputWidth = 1920;
          mergedVideoOutputHeight = 1080;
        }
      }
    }
    return this;
  }

  ConsultationMember fixOnlyCamera() {
    /// 修正仅存在摄像头时的画面，将摄像头作为主画面
    if (videoDeviceInfos != null && videoDeviceInfos!.length == 1) {
      if (videoDeviceInfos![0].videoDeviceSourceType ==
          VideoDeviceSourceTypeEnum.Camera) {
        videoDeviceInfos![0].videoDeviceSourceType =
            VideoDeviceSourceTypeEnum.Desktop;
        mergedChannel = false;
      }
    }
    return this;
  }

  Map<String, dynamic> toJson() {
    final map = Map<String, dynamic>();
    if (id != null) map['id'] = id;
    if (name != null) map['name'] = name;
    map['memberType'] = memberType.index;
    map['roleType'] = roleType.index;
    if (headImageToken != null) map['headImageToken'] = headImageToken;
    map['isOnline'] = isOnline;
    map['mute'] = mute;
    map['videoOpend'] = videoOpend;
    map['isInitiator'] = isInitiator;
    map['isBusy'] = isBusy;
    map['status'] = status.index;
    if (liveData != null) map['liveData'] = liveData;
    map['mergedChannel'] = mergedChannel;
    map['mergedVideoOutputWidth'] = mergedVideoOutputWidth;
    map['mergedVideoOutputHeight'] = mergedVideoOutputHeight;
    map['isOldPlatform'] = isOldPlatform;
    map['supportRtc'] = supportRtc;
    if (videoDeviceInfos != null) map['videoDeviceInfos'] = videoDeviceInfos;
    return map;
  }
}

enum MemberRoleType {
  Local,
  Remote,
  Device,
}

///会诊成员状态（从Server的枚举中增加了一些状态）
enum MemberStatus {
  Default, //初始状态
  Accepted, //接受
  Rejected, //拒绝
  Joined, //已经加入房间
  Left, //离开
  Calling, //呼叫中
  Busyline, //忙线
  Unanswered, //未接听
  Offline, //掉线
  Cancel, //取消呼叫
  NetError, //网络异常
}
