package com.casic.br.utils.retrofit

import com.casic.br.extensions.toChineseTypeName
import com.casic.br.model.UserDetailModel
import com.casic.br.utils.AuthenticationHelper
import com.casic.br.utils.LocaleConstant
import com.pengxh.kt.lite.extensions.timestampToCompleteDate
import com.pengxh.kt.lite.utils.RetrofitFactory.createRetrofit
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.tuya.smart.sdk.bean.DeviceBean
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.File


object RetrofitServiceManager {

    private val api by lazy {
        val httpConfig = SaveKeyValues.getValue(
            LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL
        ) as String
        createRetrofit<RetrofitService>(httpConfig)
    }

    /**
     * 验证PublicKey
     */
    suspend fun authenticate(): String {
        return api.obtainPublicKey()
    }

    /**
     * 注册
     */
    suspend fun register(
        account: String,
        password: String,
        positionLng: Double,
        positionLat: Double,
        clientId: String,
        syncName: String,
        syncDeptid: String
    ): String {
        val paramObject = JSONObject()
        paramObject.put("account", account)
        paramObject.put("password", password)
        paramObject.put("name", "")
        paramObject.put("birthday", "")
        paramObject.put("sex", "")
        paramObject.put("email", "")
        paramObject.put("phone", "")
        paramObject.put("roleId", "1578950702169141249")
        paramObject.put("deptId", "1578950562897276930")
        paramObject.put("avatar", "")
        paramObject.put("positionLng", positionLng)
        paramObject.put("positionLat", positionLat)
        paramObject.put("attr1", clientId)
        paramObject.put("syncName", syncName)
        paramObject.put("syncDeptid", syncDeptid)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.register(requestBody)
    }

    /**
     * 登录并获取Token
     */
    suspend fun login(sid: String, account: String, secretKey: String): String {
        val paramObject = JSONObject()
        paramObject.put("sid", sid)
        paramObject.put("username", account)
        paramObject.put("password", secretKey)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.login(requestBody)
    }

    /**
     * 退出登录
     */
    suspend fun loginOut(): String {
        return api.loginOut(AuthenticationHelper.token!!)
    }

    /**
     * 获取用户信息
     */
    suspend fun obtainUserDetail(account: String): String {
        return api.obtainUserDetail(AuthenticationHelper.token!!, account)
    }

    /**
     * 获取用户信息
     */
    suspend fun updateUserInfo(userData: UserDetailModel.DataModel): String {
        val paramObject = JSONObject()
        paramObject.put("id", userData.id)
        paramObject.put("name", userData.name)
        paramObject.put("birthday", userData.birthday)
        paramObject.put("sex", userData.sex)
        paramObject.put("email", userData.email)
        paramObject.put("phone", userData.phone)
        paramObject.put("avatar", userData.avatar)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.updateUserInfo(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 新增地址
     */
    suspend fun addAddress(
        account: String, province: String, city: String,
        area: String, street: String, detailAddress: String,
        postalCode: String
    ): String {
        val paramObject = JSONObject()
        paramObject.put("account", account)
        paramObject.put("province", province)
        paramObject.put("city", city)
        paramObject.put("area", area)
        paramObject.put("street", street)
        paramObject.put("detailAddress", detailAddress)
        paramObject.put("postalCode", postalCode)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.addAddress(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 地址列表
     */
    suspend fun obtainAddressListByPage(
        account: String, province: String, city: String, area: String, offset: Int
    ): String {
        val paramObject = JSONObject()
        paramObject.put("account", account)
        paramObject.put("province", province)
        paramObject.put("city", city)
        paramObject.put("area", area)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        val limitMap = HashMap<String, Int>()
        limitMap["limit"] = LocaleConstant.PAGE_LIMIT

        val offsetMap = HashMap<String, Int>()
        offsetMap["offset"] = offset
        return api.obtainAddressListByPage(
            AuthenticationHelper.token!!, requestBody, limitMap, offsetMap
        )
    }

    /**
     * 地址删除
     */
    suspend fun deleteAddressById(id: String): String {
        val paramObject = JSONObject()
        paramObject.put("id", id)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.deleteAddressById(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 修改地址
     */
    suspend fun updateAddressById(
        id: String, account: String, province: String, city: String,
        area: String, street: String, detailAddress: String,
        postalCode: String
    ): String {
        val paramObject = JSONObject()
        paramObject.put("id", id)
        paramObject.put("account", account)
        paramObject.put("province", province)
        paramObject.put("city", city)
        paramObject.put("area", area)
        paramObject.put("street", street)
        paramObject.put("detailAddress", detailAddress)
        paramObject.put("postalCode", postalCode)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.updateAddressById(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * Banner
     */
    suspend fun obtainBanner(bannerName: String, bannerModule: String): String {
        val paramObject = JSONObject()
        paramObject.put("bannerName", bannerName)
        paramObject.put("bannerModule", bannerModule)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )

        val limitMap = HashMap<String, Int>()
        limitMap["limit"] = 5

        val offsetMap = HashMap<String, Int>()
        offsetMap["offset"] = 1
        return api.obtainBanner(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap)
    }

    /**
     * 上传图片
     */
    suspend fun uploadImage(image: File): String {
        val requestBody = image.asRequestBody("image/jpeg".toMediaTypeOrNull())
        val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody)
        return api.uploadImage(AuthenticationHelper.token!!, imagePart)
    }

    /**
     * 添加设备到自己服务器
     */
    suspend fun addDevice(
        devResp: DeviceBean,
        userModel: UserDetailModel.DataModel,
        iotDevice: String, deviceAddress: String
    ): String {
        val paramObject = JSONObject()
        paramObject.put("deviceId", devResp.devId)
        paramObject.put("iotDevice", iotDevice)
        paramObject.put("deviceAddress", deviceAddress)
        paramObject.put("productCode", devResp.productId)
        paramObject.put("deviceStatus", 1)
        paramObject.put("deviceActive", 1)
        paramObject.put("deviceActiveTime", (devResp.time * 1000L).timestampToCompleteDate())
        paramObject.put("deviceBindUser", 1)
        paramObject.put("deviceBindUser", 1)
        paramObject.put("deviceName", devResp.toChineseTypeName())
        paramObject.put("deviceHardwareVersion", devResp.bv)
        paramObject.put("deviceSoftwareVersion", devResp.pv)
        paramObject.put("deviceMac", devResp.mac)
        paramObject.put("deviceIp", devResp.ip)
        paramObject.put("productCategory", devResp.category)
        paramObject.put("productCode", devResp.name)
        paramObject.put("productVersion", devResp.productBean.productVer)
        paramObject.put("userAccount", userModel.account)
        paramObject.put("userName", userModel.name)
        paramObject.put("userPhone", userModel.phone)
        paramObject.put("userBindDate", System.currentTimeMillis().timestampToCompleteDate())
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.addDevice(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 添加设备数据到自己服务器
     */
    suspend fun addDeviceData(deviceData: JSONObject): String {
        val requestBody = deviceData.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.addDeviceData(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 推送消息列表
     */
    suspend fun obtainMessageListByPage(
        messageCode: String, messageTitle: String, messageContent: String, offset: Int
    ): String {
        val paramObject = JSONObject()
        paramObject.put("messageCode", messageCode)
        paramObject.put("messageTitle", messageTitle)
        paramObject.put("messageContent", messageContent)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        val limitMap = HashMap<String, Int>()
        limitMap["limit"] = LocaleConstant.PAGE_LIMIT

        val offsetMap = HashMap<String, Int>()
        offsetMap["offset"] = offset
        return api.obtainMessageListByPage(
            AuthenticationHelper.token!!, requestBody, limitMap, offsetMap
        )
    }

    /**
     * 删除消息
     */
    suspend fun deleteMessageById(id: String): String {
        val paramObject = JSONObject()
        paramObject.put("id", id)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.deleteMessageById(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 更新消息
     */
    suspend fun updateMessageById(id: String, messageStatus: String): String {
        val paramObject = JSONObject()
        paramObject.put("id", id)
        paramObject.put("messageStatus", messageStatus)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.updateMessageById(AuthenticationHelper.token!!, requestBody)
    }

    /**
     * 汉威设备列表
     */
    suspend fun obtainOtherDeviceListByPage(): String {
        val paramObject = JSONObject()
        paramObject.put("brandName", "hanwei")
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        val limitMap = HashMap<String, Int>()
        limitMap["limit"] = LocaleConstant.PAGE_LIMIT

        val offsetMap = HashMap<String, Int>()
        offsetMap["offset"] = 1
        return api.obtainOtherDeviceListByPage(
            AuthenticationHelper.token!!, requestBody, limitMap, offsetMap
        )
    }

    /**
     * 汉威设备详情
     */
    suspend fun obtainDeviceDetail(id: String): String {
        val paramObject = JSONObject()
        paramObject.put("id", id)
        val requestBody = paramObject.toString().toRequestBody(
            "application/json;charset=UTF-8".toMediaType()
        )
        return api.obtainDeviceDetail(AuthenticationHelper.token!!, requestBody)
    }
}