package com.renrenliao.im.im

import android.os.Parcelable
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import com.renrenliao.im.bean.UserInfo
import com.renrenliao.im.config.Const
import com.renrenliao.im.model.repository.LocalDataSource
import com.renrenliao.im.utils.*
import kotlinx.android.parcel.Parcelize

/**
 **@ClassName ImDataBean
 **@Description
 **@Author gan
 **@Date 2022/5/31 19:39
 **/


@Entity(
    //表名
    tableName = "message",
    //索引
    indices = [Index("fp"), Index("account_uid"), Index("time"), Index(
        value = ["account_uid", "fp"],
        unique = true
    )]
)
data class ImMsgBean(
    /** 自动生成主键 */
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0,

    /** 用户id 写入数据库必须写入当前用户id  */
    var account_uid: String? = null,

    /** 发送者信息 start==========  */
    /** 发送者id，只需要在登陆的时候传入自己的id，其他的消息不需要传入自己的id  */
    var fid: String? = null,
    /** 发送这的设备类型，每一条消息都需要传入，为消息多端做同步，《不需要存表》  */
    @Ignore
    var device: String? = null,

    /** 发送者是不是机器人，目前保留不处理，《预留库表》  */
    var isBot: Boolean = false,

    /** 发送者的token，登陆的时候传入，其他的消息不需要传，《不需要存表》  */
    @Ignore
    var token: String? = null,

    /** 发送这的昵称，每条消息都传入，【此处后期需要做修改】  */
    var name: String? = null,

    /** 发送者的头像版本号，为了及时刷新群内发送者的头像  */
    var avatar: String? = null,
    /** 发送者信息 end==========  */
    /** 接收者信息 start==========  */

    /** 接收者id，单聊传入接收者的id，群聊需要传入群组id  */
    var tid: String? = null,

    /** 会话id  */
    var gId: String? = null,
    /** 接收者信息 end==========  */

    /** 消息路由，方便后端处理对应的消息，0-登陆，1-心跳，2-普通消息，3-退出登陆，4-qos应答消息  */
    @Ignore
    var route: String? = null,

    /** 聊天类型，0-单聊，1-临时聊天，2-群聊  */
    var type: Int = 0,

    /** 消息指纹码，消息的唯一id  */
    var fp: String = "",

    /** 消息类型，方便客户端展示判断使用什么控件  */
    var msgType: Int = 0,

    /** 消息时间戳，毫秒为单位  */
    var time: Long? = null,
    /** 具体的消息数据，不通的消息所有的字段不通，不通的消息返回的数据不一样，没有值的字段不传递  */
    /** 文本消息  */
    var txt: String? = null,

    /** @用户存入用户的id，此字段共用 -1代表全部
     */
    var remind: String? = null,

    /** 登陆成功/失败状态，返回ture，登陆成功，返回false，返回失败，《不需要存表》  现在 200为成功 */
    @Ignore
    var signIn: Int = 0,

    /** 上/下线的用户id  */
    var uid: String? = null,

    /** 收到消息确认应答指纹码  */
    var ack: String? = null,

    /** 消息尝试重复发送的次数  */
    @Ignore
    @Transient
    var retryCount: Int = 0,

    /** 是否展示时间 前面展示过继续展示  */
    var showtime: Boolean = false

) {


//    fun getRealMsgType(): Int {
//        var self = false
//        if (TextUtils.equals(fid, DataCacheUtils.getUid())) {
//            self = true
//        }
//        var result = 0
//        result = when (msgType) {
//            5 -> if (self) {
//                MsgType.toText
//            } else {
//                MsgType.comeText
//            }
//            else -> if (self) {
//                MsgType.toText
//            } else {
//                MsgType.comeText
//            }
//        }
//        return result
//    }

    fun copy(): ImMsgBean {
        val imMsgBean = ImMsgBean()
        imMsgBean.msgType = this.msgType
        imMsgBean.txt = this.txt
        imMsgBean.fid = this.fid
        imMsgBean.tid = this.tid
        imMsgBean.fp = this.fp
        imMsgBean.account_uid = this.account_uid
        return imMsgBean
    }

    /** 获取当前消息的json字符串  */
    fun toJSONString(): String {
        return GsonUtils.object2JsonStr(this)
    }

    fun increaseRetryCount() {
        ++retryCount
    }

    fun toBytes(): ByteArray {
        return CharsetUtils.getBytes(toJSONString())
    }

    /** 文字消息从网络发送的当前状态. 本字段仅针对发送的消息（而非收到的消息哦）  */
    private var sendStatus = SendStatus.sending
    fun getSendStatus(): Int {
        return sendStatus
    }

    fun setSendStatus(sendStatus: Int) {
        this.sendStatus = sendStatus
    }

    /**
     * 辅助处理状态. 本字段仅针对发送的消息（而非收到的消息哦）.
     *
     *
     * 此变量通常用于发送图片、语音留言场合，因为图片文件上传到服务端的过程是
     * 一个独立的处理过程，需要和文字消息分开处理.  */
    private var sendStatusSecondary = SendStatusSecondary.none

    fun getSendStatusSecondary(): Int {
        return sendStatusSecondary
    }

    fun setSendStatusSecondary(sendStatusSecondary: Int) {
        this.sendStatusSecondary = sendStatusSecondary
    }

    /**
     * 辅助处理状态下的进度值（0~100整数）. 本字段仅针对发送的消息（而非收到的消息哦）.
     *
     *
     * 本字段当前仅用于大文件消息的文件数据传输时（当然，你也可以用于其它消息类型，
     * 这样的值仅辅助UI显示，并非关键数据）。
     * @since 4.3
     */
    private var sendStatusSecondaryProgress = 0

    fun getSendStatusSecondaryProgress(): Int {
        return sendStatusSecondaryProgress
    }

    fun setSendStatusSecondaryProgress(sendStatusSecondaryProgress: Int) {
        this.sendStatusSecondaryProgress = sendStatusSecondaryProgress
    }

    /**
     * 辅助下载状态常量.
     *
     *
     * 此常量目前仅用于语音留言的声音文件下载时提示下载进度之用（当然以后也可用作它用）.  */
    //    private DownloadStatus downloadStatus = new DownloadStatus();
    private var downloadStatus = DownloadStatus.NONE

    fun getDownloadStatus(): Int {
        return downloadStatus
    }

    fun setDownloadStatus(downloadStatus: Int) {
        this.downloadStatus = downloadStatus
    }

    /**
     * 下载进度
     * 此常量目前仅用于语音留言的声音文件下载时提示下载进度之用（当然以后也可用作它用）.  */
    private var progress = 0

    fun getProgress(): Int {
        return progress
    }

    fun setProgress(progress: Int) {
        this.progress = progress
    }

    /**
     * 文字消息的发送状态常量.
     */
    interface SendStatus {
        companion object {
            /** 消息发送中  */
            const val sending = 0

            /** 消息已被对方收到（我方已收到应答包）  */
            const val beReceived = 1

            /** 消息发送失败（在超时重传的时间内未收到应答包）  */
            const val sendFaild = 2
        }
    }

    /**
     * 辅助发送状态常量.
     *
     *
     * 此常量通常用于发送图片、语音留言场合，因为图片文件上传到服务端的过程是
     * 一个独立的处理过程，需要和文字消息分开处理.
     */
    interface SendStatusSecondary {
        companion object {
            /** 无需处理  */
            const val none = 0

            /** 等待处理  */
            const val pending = 1

            /** 处理中  */
            const val processing = 2

            /** 成功处理完成  */
            const val processOk = 3

            /** 处理失败  */
            const val processFaild = 4
        }
    }

    /**
     * 辅助下载状态常量.
     *
     *
     * 此常量目前语音留言的声音文件下载时提示下载进度之用.
     */
    object DownloadStatus {
        /** 无需处理  */
        const val NONE = 0

        /** 处理中  */
        const val PROCESSING = 1

        /** 成功处理完成  */
        const val PROCESS_OK = 2

        /** 处理失败  */
        const val PROCESS_FAILD = 3
    }

    /**
     * 辅助发送状态的处理结果观察者统一接口.
     */
    interface SendStatusSecondaryResult {
        /** 状态变迁到“处理中”状态时要调用的方法  */
        fun processing()

        /** 状态变迁到“处理失败”时要调用的方法  */
        fun processFaild()

        /** 状态变迁到“处理成功”时要调用的方法  */
        fun processOk(uploadResult: UploadResult?)
    }


    fun isOutgoing(): Boolean {
        return fid == LocalDataSource.readOnlyUserFlow.value?.userUid.toString()
    }

    companion object {
        @Volatile
        var resetNum = 0

        @Synchronized
        fun genFingerPrint(): String {
            if (resetNum == 99) {
                resetNum = 0
            } else {
                resetNum += 1
            }
            val stringBuilder = StringBuilder()
            stringBuilder.append(MDateUtils.currentTimMillis()).append("-")
                .append(LocalDataSource.readOnlyUserFlow.value?.userUid).append("-").append("and")
                .append(resetNum)
            return stringBuilder.toString()
        }

        @Synchronized
        fun genFingerPrint(num: String?): String {
            val stringBuilder = StringBuilder()
            stringBuilder.append(MDateUtils.currentTimMillis()).append("-")
                .append(LocalDataSource.readOnlyUserFlow.value?.userUid).append("-").append("and")
                .append(num)
            return stringBuilder.toString()
        }
    }
}



/**
 * 首页消息通知表
 */
@Entity(
    tableName = "alarm",
    indices = [Index("gId"), Index("account_uid"), Index("time"), Index("isTop"), Index("msgType"), Index(
        value = ["account_uid", "gId", "msgType"],
        unique = true
    )]
)
@Parcelize
data class AlarmEntity(
    /** 自动生成主键 */
    @PrimaryKey(autoGenerate = true)
    var id: Long,

    /** 用户id 写入数据库必须写入当前用户id  */
    var account_uid: String? = null,

    /** 消息类型  */
    var msgType: Int = 0,

    /** 聊天类型，0-单聊，1-临时聊天，2-群聊  */
    var type: Int = 0,

    /** 会话id  */
    var gId: String? = null,

    /** 发送者信息 start==========  */
    /** 发送者id，只需要在登陆的时候传入自己的id，其他的消息不需要传入自己的id  */
    var fid: String? = null,

    /** 消息显示内容  */
    var msg: String? = null,

    /** 发送者昵称单聊对方昵称 群聊群名称  */
    var name: String? = null,

    /** 消息时间戳，毫秒为单位 从消息体取的 时间  */
    var time: Long? = null,

    /** 消息指纹码，消息的唯一id  */
    var fp: String? = null,

    /** 编辑的文本  */
    var edit: String? = null,

    /** 是否置顶  */
    var isTop: Boolean = false,

    /** 未读消息数量  */
    var num: Int = 0,

    /** 接收者信息 start==========  */
    /** 接收者id，单聊传入接收者的id，群聊需要传入群组id  */
    var tid: String? = null,
    /** 头像版本**/
    var avatarVersion: Long = 0
) : Parcelable{
    @Ignore
    constructor():this(id = 0)
    //设置单聊信息 为后面操作用
    fun setSingleChatInfo(userInfo: UserInfo) {
        name = userInfo.getRemark()
        gId = userInfo.gId
        type = ChatType.SINGLE.value
        fid = DataCacheUtils.getUid()
        tid = userInfo.userUid
     //   avatarVersion = StringUtils.getAvatarVersion(userInfo.userAvatarFileName)
    }
    fun getAvatarUrl():String{
        return when(type){
            ChatType.SINGLE.value -> Const.COMMON_IMG_USER_FILE + avatarVersion+"/"+avatarVersion+".png"
            ChatType.GROUP.value -> Const.COMMON_IMG_GROUP_FILE + avatarVersion+"/"+avatarVersion+".png"
            else -> ""
        }
    }
}


data class UploadResult(
    //文件在服务器的id
    var fileId: String,
    //文件的md5加密
    var fileMd5: String,
    //文件名
    var fileName: String,
    //上传时间
    var depositTime: String,
    //转后的文件地址
    var fileUrl: String,
    //源文件地址 因为ios不能放MP3 所以还是用这个字段发消息
    var sourceFile: String,
    //文件格式
    var pixFile: String,
    //文件封面图
    var thumbnail: String,
    //文件大小
    var fileSize: String
)

/**
 * {
"userSex":3,
"chatid":"test_UU9xSNT",
"nickname":"gz123456",
"buddyRemark":"",
"fn":"G",
"userAvatarFileName":"https://renrenim.oss-cn-beijing.aliyuncs.com/picture/headimg/adfSDFG465GSDF645fgdhDSFG465.jpg",
"userUid":10026291,
"unnotify":0,
"liveStatus":0
}

 */
//@Entity(
//    //表名
//    tableName = "friend",
//    //索引
//    indices = [Index(value = ["account_uid", "userUid"], unique = true)]
//)
//data class FriendEntity(
//    @PrimaryKey(autoGenerate = true)
//    val id: Int,
//    var account_uid: String? = "",  //自己的uid
//    val buddyRemark: String ="", //备注
//    val chatid: String ="",
//    val fn: String ="",
//    val liveStatus: Int =0, //0 表示不在线 1表示在线
//    val nickname: String ="",
//    val unnotify: Int =0,
//    val userAvatarFileName: String ="",
//    val userSex: Int =0,
//    val userUid: String ="",  //好友的uid
//    var ext1:Boolean = false  /** @see com.renrenliao.im.ui.adapter.GroupMemberAdapter 扩展字段*/
//
//)

/**
 * {
"gName":"群测试",
"groupAvatarImage":"https://renrenim.oss-cn-beijing.aliyuncs.com/picture/headimg/adfSDFG465GSDF645fgdhDSFG465.jpg",
"isInGroup":1,
"gId":"967402356427718656",
"createUserName":"小同学",
"gStatus":1,
"maxMemberCount":500,
"role":"2",
"gMemberCount":9,
"joinTime":1653123180000,
"nickname":"小同学",
"groupBannedState":"1",
"gOwnerUserUid":100003,
"unnotify":0,
"memberBannedState":"1",
"createTime":1650688295000
}
 */
@Entity(
    //表名
    tableName = "groups",
    //索引
    indices = [Index(value = ["account_uid", "gId"], unique = true)]
)
data class GroupEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    var account_uid: String? = "",  //自己的uid
    val createTime: String,  //创建时间
    var createUserName: String?,
    var createUserUid:String? = "",
    val gId: String,    //群组id
    val gMemberCount: Int,
    val gName: String?,  //群名
    val gOwnerUserUid: String?,  //群主uid
    val gStatus: Int,  //群组状态  -1已删除，0锁定，1正常
    val groupAvatarImage: String, //群头像
    val groupBannedState: String?,  // 该群组的禁言状态  0：禁言 1：未禁言
    var isInGroup: Int,   //我是否在此群中 1 代表 true
    var joinTime: String?,
    val maxMemberCount: Int,  //允许最大群成员数量
    val memberBannedState: String?, //我在该群的禁言状态 0：禁言 1：未禁言
    val nickname: String?,  //群主昵称
    val role: String?, //群组角色 0：群主 1：管理员 2：普通成员
    val unnotify: Int
)