package com.rdiot.yx485.main

import android.os.Build
import android.text.TextUtils
import android.util.Base64
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.king.zxing.util.LogUtils
import com.rdiot.yx485.BuildConfig
import com.rdiot.yx485.UpdateBean
import com.rdiot.yx485.UpdateRequestBean
import com.rdiot.yx485.base.BaseViewModel
import com.rdiot.yx485.bean.BannerListBean
import com.rdiot.yx485.bean.BannerListBean.DataBean.BannerBean
import com.rdiot.yx485.bean.GoodListBean
import com.rdiot.yx485.bean.GoodListBean.DataBean.GoodBean
import com.rdiot.yx485.bean.HomeBase
import com.rdiot.yx485.bean.HomeDefBean
import com.rdiot.yx485.bean.HomeListBean
import com.rdiot.yx485.bean.InitAppParamsBean
import com.rdiot.yx485.bean.ModelRepleBean
import com.rdiot.yx485.bean.PersonBean
import com.rdiot.yx485.bean.PowerBean
import com.rdiot.yx485.bean.UploadFile
import com.rdiot.yx485.bean.WeatherBean
import com.rdiot.yx485.http.Url
import com.rdiot.yx485.http.Url.UPLOAD_FILE
import com.rdiot.yx485.http.entity.BaseReplyBean
import com.rdiot.yx485.login.LoginReplyBean
import com.rdiot.yx485.util.LocalCache
import com.zcolin.frame.http.ZHttp
import com.zcolin.frame.http.response.ZResponse
import com.zcolin.frame.util.SpUtil
import okhttp3.Response
import java.io.File
import java.util.*

class MainViewModel : BaseViewModel() {

    private var mGoodList = MutableLiveData<List<GoodBean>?>()
    val goodList: LiveData<List<GoodBean>?>
        get() = mGoodList

    /**
     * 获取推荐列表
     */
    fun loadRecommendGoodList() {
        LogUtils.d("loadRecommendGoodList start")
        val map = HashMap<String?, String?>()
        map.put("q", "recommend")
        val headers = LinkedHashMap<String?, String?>()
        headers.put("Authorization", LocalCache.getToken())
        ZHttp.getWithHeader<GoodListBean?>(
            Url.GOODSlIST,
            headers,
            map,
            object : ZResponse<GoodListBean?>() {
                override fun onSuccess(response: Response?, resObj: GoodListBean?) {
                    LogUtils.d("loadRecommendGoodList success: $resObj")
                    resObj?.let {
                        if (!it.isSuccess) {
                            mErrorMessage.value = it.message
                            return
                        }

                        mGoodList.value = it.data.list
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadRecommendGoodList error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    private var mBannerList = MutableLiveData<List<BannerBean>?>()
    val bannerList: LiveData<List<BannerBean>?>
        get() = mBannerList

    /**
     * 获取banner
     */
    fun loadBannerList() {
        LogUtils.d("loadBannerList start")
        val map: MutableMap<String?, String?> = HashMap<String?, String?>()
        map.put("q", "list")
        map.put("type", "1")
        val headers = LinkedHashMap<String?, String?>()
        headers.put("Authorization", LocalCache.getToken())
        ZHttp.getWithHeader<BannerListBean?>(
            Url.BANNERS,
            headers,
            map,
            object : ZResponse<BannerListBean?>() {
                override fun onSuccess(response: Response?, resObj: BannerListBean?) {
                    LogUtils.d("loadBannerList success: $resObj")
                    resObj?.let {
                        if (!it.isSuccess) {
                            mErrorMessage.value = it.message
                            return
                        }

                        mBannerList.value = it.data.list
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadBannerList error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    private var mUploadInfo = MutableLiveData<UploadFile.UploadInfo?>()
    val uploadInfo: LiveData<UploadFile.UploadInfo?>
        get() = mUploadInfo

    fun uploadFile(filePath: String) {
        LogUtils.d("uploadFile start: $filePath")
        if (TextUtils.isEmpty(filePath)) {
            mErrorMessage.value = "文件路径不能为空"
            return
        }
        val file = File(filePath)
        if (!file.isFile || !file.exists()) {
            mErrorMessage.value = "文件不存在"
            return
        }

        val map = HashMap<String?, File?>()
        map.put("file", file)
        ZHttp.uploadFile<UploadFile?>(UPLOAD_FILE, map, object : ZResponse<UploadFile?>() {
            override fun onSuccess(
                response: Response?,
                resObj: UploadFile?
            ) {
                LogUtils.d("uploadFile success: $resObj")
                resObj?.let {
                    if (it.isSuccess) {
                        mUploadInfo.value = it.data
                        return
                    }

                    mErrorMessage.value = it.message
                }
            }

            override fun onError(code: Int, error: String?) {
                LogUtils.d("uploadFile error: $code, $error")
                super.onError(code, error)
                mErrorMessage.value = error
            }
        })
    }

    private var mUpdateState = MutableLiveData<Boolean>()
    val updateState: LiveData<Boolean>
        get() = mUpdateState

    /**
     * 更新用户信息
     */
    fun updateUserInfo(userInfo: PersonBean.UserInfo) {
        LogUtils.d("updateUserInfo start: $userInfo")
        val url = Url.USEREDIT.replace("{id}", userInfo.record_id)
        ZHttp.putJsonWithHeader<BaseReplyBean?>(
            url,
            getHeaders(),
            userInfo,
            object : ZResponse<BaseReplyBean?>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("updateUserInfo success: $resObj")
                    resObj?.let {
                        mUpdateState.value = it.isSuccess
                        if (it.isSuccess) {
                            LocalCache.saveUserInfo(userInfo)
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("updateUserInfo error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    private var _userInfo = MutableLiveData<PersonBean.UserInfo?>()
    val userInfo: LiveData<PersonBean.UserInfo?> = _userInfo

    fun loadUserInfo() {
        LogUtils.d("loadUserInfo start")
        ZHttp.getWithHeader<PersonBean?>(
            Url.CURRENT,
            getHeaders(),
            object : ZResponse<PersonBean?>() {
                override fun onSuccess(response: Response?, resObj: PersonBean?) {
                    LogUtils.d("loadUserInfo success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _userInfo.value = it.data
                            LocalCache.saveUserInfo(it.data)
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadUserInfo error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error;
                }
            })
    }

    private var mDeleteAccountState = MutableLiveData<Boolean>()
    val deleteAccountState: LiveData<Boolean>
        get() = mDeleteAccountState

    /**
     * 注销账号
     */
    fun deleteAccount() {
        LogUtils.d("deleteAccount start")
        ZHttp.patchJsonWithHeader<BaseReplyBean?>(
            Url.EXIT,
            getHeaders(),
            Gson().toJson(HashMap<String, String>()),
            object : ZResponse<BaseReplyBean?>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("deleteAccount success: $resObj")
                    resObj?.let {
                        mDeleteAccountState.value = it.isSuccess
                        if (it.isSuccess) {
                            // 清除本地缓存
                            LocalCache.logout()
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("deleteAccount error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    // Home related LiveData
    private val _homeList = MutableLiveData<List<HomeBase>?>()
    val homeList: LiveData<List<HomeBase>?> = _homeList

    private val _selectedHome = MutableLiveData<HomeBase>()
    val selectedHome: LiveData<HomeBase> = _selectedHome

    private val _homeDef = MutableLiveData<HomeDefBean.DataBean?>()
    val homeDef: LiveData<HomeDefBean.DataBean?> = _homeDef

    private val _weatherInfo = MutableLiveData<WeatherBean.DataBean?>()
    val weatherInfo: LiveData<WeatherBean.DataBean?> = _weatherInfo

    private val _modelList = MutableLiveData<List<ModelRepleBean.DataBean>?>()
    val modelList: LiveData<List<ModelRepleBean.DataBean>?> = _modelList

    private val _deviceControlResult = MutableLiveData<Boolean>()
    val deviceControlResult: LiveData<Boolean> = _deviceControlResult

    /**
     * 获取家列表
     */
    fun loadHomeList() {
        LogUtils.d("loadHomeList start")
        val map = HashMap<String, String>()
        map["q"] = "list"
        map["is_admin"] = "0"
        val headers = LinkedHashMap<String, String>()
        headers["Authorization"] = LocalCache.getToken()
        ZHttp.getWithHeader<HomeListBean>(
            Url.HOMES,
            headers,
            map,
            object : ZResponse<HomeListBean>() {
                override fun onSuccess(response: Response?, resObj: HomeListBean?) {
                    LogUtils.d("loadHomeList success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            //将家庭信息的基本信息（ID、name）保存到本地
                            val list = it.data.map { homeInfo ->
                                HomeBase(
                                    homeInfo.record_id,
                                    homeInfo.name
                                )
                            }.toList()
                            _homeList.value = list
                            LocalCache.saveHomeList(list)
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadHomeList error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 获取默认家庭
     */
    fun loadDefaultHome() {
        LogUtils.d("loadDefaultHome start")
        val headers = LinkedHashMap<String, String>()
        headers["Authorization"] = LocalCache.getToken()
        ZHttp.getWithHeader<HomeDefBean>(
            Url.HOMEDEFAULT,
            headers,
            object : ZResponse<HomeDefBean>() {
                override fun onSuccess(response: Response?, resObj: HomeDefBean?) {
                    LogUtils.d("loadDefaultHome success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            if (it.data == null) {
                                return
                            }

                            _selectedHome.value?.let { home ->
                                if (home.id.equals(it.data.record_id) && home.name.equals(it.data.name)) {
                                    _homeDef.value = it.data
                                    return
                                }
                            }

                            //保存默认家庭基础信息到本地
                            _selectedHome.value = HomeBase(it.data.record_id, it.data.name)
                            LocalCache.saveDefaultHome(_selectedHome.value)
                            _homeDef.value = it.data
                            return
                        }

                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadDefaultHome error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 更新默认家庭
     */
    fun updateDefaultHome(info: HomeBase?) {
        LogUtils.d("updateDefaultHome start: $info")
        if (info == null || TextUtils.isEmpty(info.id)) {
            return
        }

        ZHttp.putWithHeader<BaseReplyBean?>(
            Url.FAMILYMEMBERDELETE + info.id,
            getHeaders(),
            object : ZResponse<BaseReplyBean?>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("updateDefaultHome success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            loadDefaultHome()
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("updateDefaultHome error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 获取天气
     */
    fun loadWeather(homeId: String?, cityName: String) {
        LogUtils.d("loadWeather start")
        val map = HashMap<String, String>()
        map["city_name"] = cityName
        map["home_id"] = homeId ?: LocalCache.getDefaultHomeId()

        val headers = LinkedHashMap<String, String>()
        headers["Authorization"] = LocalCache.getToken()
        ZHttp.getWithHeader<WeatherBean>(
            Url.WEATHER,
            headers,
            map,
            object : ZResponse<WeatherBean>() {
                override fun onSuccess(response: Response?, resObj: WeatherBean?) {
                    LogUtils.d("loadWeather success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _weatherInfo.value = it.data
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadWeather error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 获取场景
     */
    fun loadScenes(homeId: String?) {
        LogUtils.d("loadScenes start")
        val map = HashMap<String, String>()
        map["q"] = "list"
        map["homepage"] = "1"
        map["home_id"] = homeId ?: LocalCache.getDefaultHomeId()
        ZHttp.getWithHeader<ModelRepleBean>(
            Url.SCENES,
            getHeaders(),
            map,
            object : ZResponse<ModelRepleBean>() {
                override fun onSuccess(response: Response?, resObj: ModelRepleBean?) {
                    LogUtils.d("loadScenes success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _modelList.value = it.data
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadScenes error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 执行场景
     */
    fun doScene(sceneId: String) {
        LogUtils.d("doScene start: $sceneId")
        ZHttp.putWithHeader<BaseReplyBean>(
            Url.SCENESDO + sceneId + "/do",
            getHeaders(),
            object : ZResponse<BaseReplyBean>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("doScene success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _deviceControlResult.value = true
                            return
                        }

                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("doScene error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    /**
     * 控制设备
     */
    fun loadDeviceControl(deviceCode: String, isPower: Boolean, subCode: String? = null) {
        LogUtils.d("loadDeviceControl start: deviceCode=$deviceCode, isPower=$isPower subCode=$subCode")
        val bean = PowerBean()
        bean.device_code = deviceCode
        bean.power = isPower
        subCode?.let {
            bean.sub_code = it
        }

        val headers = LinkedHashMap<String, String>()
        headers["Authorization"] = LocalCache.getToken()
        ZHttp.postJsonWithHeader<BaseReplyBean>(
            Url.POWER,
            headers,
            bean,
            object : ZResponse<BaseReplyBean>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("loadDeviceControl success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _deviceControlResult.value = true
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadDeviceControl error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            })
    }

    private val _initResult = MutableLiveData<Boolean>()
    val initResult: LiveData<Boolean> = _initResult

    /**
     * 初始化接口调用
     */
    fun initializeApp(deviceId: String, cid: String, loginType: Int) {
        LogUtils.d("loginType: $loginType")
        val appParams = InitAppParamsBean(
            channel = "android",
            device_id = deviceId,
            device_type = "Android",
            os = "Android",
            os_version = Build.VERSION.RELEASE,
            phone_brand = Build.BRAND,
            phone_model = Build.MODEL,
            version = BuildConfig.VERSION_NAME,
            uuid = UUID.randomUUID().toString(),
            login_type = loginType,
            cid = cid
        )

        val appParamsJson = Gson().toJson(appParams)
        LogUtils.d(appParamsJson)
        val appParamsBase64 = Base64.encodeToString(appParamsJson.toByteArray(), Base64.NO_WRAP)

        val headers = getHeaders().apply {
            put("X-YX-APP", appParamsBase64)
        }
        LogUtils.d(headers.toString())

        ZHttp.postWithHeader<BaseReplyBean>(
            Url.INIT,
            headers,
            HashMap<String, String>(),
            object : ZResponse<BaseReplyBean>() {
                override fun onSuccess(response: Response?, resObj: BaseReplyBean?) {
                    LogUtils.d("initializeApp success: $resObj")
                    resObj?.let {
                        _initResult.value = it.isSuccess
                        if (!it.isSuccess) {
                            mErrorMessage.value = it.message
                        }
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("initializeApp error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            }
        )
    }

    private val _updateInfo = MutableLiveData<UpdateBean.DataBean.UpdateInfo?>()
    val updateInfo: LiveData<UpdateBean.DataBean.UpdateInfo?> = _updateInfo

    private val _needUpdate = MutableLiveData<Boolean>()
    val needUpdate: LiveData<Boolean> = _needUpdate

    /**
     * 检查更新
     */
    fun checkUpdate() {
        LogUtils.d("checkUpdate start")
        val bean = UpdateRequestBean().apply {
            this.version = BuildConfig.VERSION_NAME
            this.platform = "ANDROID"
        }

        ZHttp.postWithHeader(
            Url.CHECKVERSION,
            getHeaders(),
            bean,
            object : ZResponse<UpdateBean>() {
                override fun onSuccess(response: Response?, resObj: UpdateBean?) {
                    LogUtils.d("checkUpdate success: $resObj")
                    resObj?.let {
                        if (it.code == 0) {
                            it.data?.let { data ->
                                _needUpdate.value = data.need_update
                                _updateInfo.value = data.update_info
                            }
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("checkUpdate error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            }
        )
    }

    fun refreshToken() {
        LogUtils.d("refreshToken start")
        ZHttp.putWithHeader(
            Url.REFRESH_TOKEN,
            getHeaders(),
            object : ZResponse<LoginReplyBean>() {
                override fun onSuccess(response: Response?, resObj: LoginReplyBean?) {
                    LogUtils.d("refreshToken success: ${resObj.toString()}")
                    resObj?.let {
                        if (it.code == 0) {
                            LocalCache.saveLoginInfo(it.data)
                            SpUtil.putString("access_token", it.data.access_token)
                            SpUtil.putString("token_type", it.data.token_type)
                            SpUtil.putBoolean("app_first_login", it.data.app_first_login)
                            SpUtil.putInt("expires_at", it.data.expires_at)
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("refreshToken error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            }
        )
    }

    private val _sceneList = MutableLiveData<List<ModelRepleBean.DataBean>?>()
    val sceneList: LiveData<List<ModelRepleBean.DataBean>?> = _sceneList

    /**
     * 加载场景列表
     * @param homeId 家庭ID
     * @param type 场景类型 (automation/oneKey)
     */
    fun loadSceneList(homeId: String, type: String) {
        LogUtils.d("loadSceneList start: homeId=$homeId, type=$type")
        val map = HashMap<String, String>()
        map["q"] = "list"
        map["homepage"] = "0"
        map["home_id"] = homeId
        map["type"] = type

        ZHttp.getWithHeader<ModelRepleBean>(
            Url.SCENES,
            getHeaders(),
            map,
            object : ZResponse<ModelRepleBean>() {
                override fun onSuccess(response: Response?, resObj: ModelRepleBean?) {
                    LogUtils.d("loadSceneList success: $resObj")
                    resObj?.let {
                        if (it.isSuccess) {
                            _sceneList.value = it.data
                            return
                        }
                        mErrorMessage.value = it.message
                    }
                }

                override fun onError(code: Int, error: String?) {
                    LogUtils.d("loadSceneList error: $code, $error")
                    super.onError(code, error)
                    mErrorMessage.value = error
                }
            }
        )
    }
}