package com.gingersoft.gsa.other_order_mode.service

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.Handler
import android.os.IBinder
import android.util.Log
import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication
import com.google.gson.Gson
import okhttp3.*
import okio.ByteString
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit

class GetInfoUpdateService : Service() {

    private val TAG = "eee"
    /**
     * 心跳检测时间
     */
    private val HEART_BEAT_RATE = (15 * 1000).toLong()//每隔15秒进行一次对长连接的心跳检测
    private val WEBSOCKET_HOST_AND_PORT = "https://hktest.ricepon.com:64377/ricepon-websocket/js/webSocketServer"//可替换为自己的主机名和端口号
    private var mWebSocket: WebSocket? = null
    var postCallBack: PostCallBack? = null

    override fun onBind(intent: Intent?): IBinder? {
//        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        return MyBind()
    }

    interface PostCallBack {
        fun callBack(type: Int)
    }

    inner class MyBind : Binder() {
        fun getService(): GetInfoUpdateService {
            return this@GetInfoUpdateService
        }

        fun setOnPostCallBack(postCallBack: PostCallBack?) {
            this@GetInfoUpdateService.postCallBack = postCallBack
        }

    }


    override fun onCreate() {
        super.onCreate()
        InitSocketThread().start()
        isDestroy = false
    }

    internal inner class InitSocketThread : Thread() {
        override fun run() {
            super.run()
            initSocket()
        }
    }

    // 初始化socket
    private fun initSocket() {
        val client = OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build()
        val request = Request.Builder()
                .url(WEBSOCKET_HOST_AND_PORT)
                .build()
        client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket?, response: Response?) {//开启长连接成功的回调
                super.onOpen(webSocket, response)
                if (!this@GetInfoUpdateService.isDestroy) {
                    mWebSocket = webSocket
                    val token = "weixin_" + GsaCloudApplication.getRestaurantId(this@GetInfoUpdateService) + "_" + getRandomString(24)
                    Log.e(TAG, "token：$token")
                    webSocket!!.send(Gson().toJson(MsgBean(1, token)))
                }
            }

            override fun onMessage(webSocket: WebSocket?, text: String?) {//接收消息的回调
                super.onMessage(webSocket, text)
                val json = JSONObject(text)
                if (postCallBack != null) {
                    postCallBack!!.callBack(json.optInt("type"))
                }
                //收到服务器端传过来的消息text
                Log.e(TAG, "onMessage：" + text!!)
            }

            override fun onMessage(webSocket: WebSocket?, bytes: ByteString?) {
                super.onMessage(webSocket, bytes)
                val json = JSONObject(bytes.toString())
                if (postCallBack != null) {
                    postCallBack!!.callBack(json.optInt("type"))
                }
                Log.e(TAG, "onMessage222：" + bytes!!)
            }

            override fun onClosing(webSocket: WebSocket?, code: Int, reason: String?) {
                super.onClosing(webSocket, code, reason)
                //連接斷開，
                Log.e(TAG, "onClosing")
//                InitSocketThread().start()//创建一个新的连接
            }

            override fun onClosed(webSocket: WebSocket?, code: Int, reason: String?) {
                super.onClosed(webSocket, code, reason)
                Log.e(TAG, "onClosed")
                webSocket?.cancel()
            }

            override fun onFailure(webSocket: WebSocket?, t: Throwable?, response: Response?) {//长连接连接失败的回调
                super.onFailure(webSocket, t, response)
                Log.e(TAG, "onFailure" + t!!.message)
                if (!this@GetInfoUpdateService.isDestroy) {
                    Log.e(TAG, "沒銷毀")
                    initSocket()//创建一个新的连接
                } else {
                    webSocket?.cancel()
                    client.dispatcher().cancelAll()
                }
            }
        })
        client.dispatcher().executorService().shutdown()
//        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE)//开启心跳检测
    }

    /*获取一条随机字符串*/
    fun getRandomString(length: Int): String { //length表示生成字符串的长度
        val base = "abcdefghijklmnopqrstuvwxyz0123456789" + System.currentTimeMillis()
        val random = Random()
        val sb = StringBuffer()
        for (i in 0 until length) {
            val number = random.nextInt(base.length)
            sb.append(base[number])
        }
        return sb.toString()
    }


    private var sendTime = 0L
    // 发送心跳包
    private val mHandler = Handler()
    private val heartBeatRunnable = object : Runnable {
        override fun run() {
            if (!isDestroy) {
                if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                    val isSuccess = mWebSocket?.send("0")//发送一个空消息给服务器，通过发送消息的成功失败来判断长连接的连接状态
                    Log.e(TAG, "連接狀態：$isSuccess")
                    if (isSuccess != null && !isSuccess) {//长连接已断开
                        mHandler.removeCallbacks(this)
                        mWebSocket?.cancel()//取消掉以前的长连接
                        InitSocketThread().start()//创建一个新的连接
                    } else {//长连接处于连接状态

                    }
                    sendTime = System.currentTimeMillis()
                }
                mHandler.postDelayed(this, HEART_BEAT_RATE)//每隔一定的时间，对长连接进行一次心跳检测
            }
        }
    }

    private var isDestroy = false

    override fun onDestroy() {
        super.onDestroy()
        Log.e(TAG, "onDestroy")
        isDestroy = true
        if (mWebSocket != null) {
            mWebSocket!!.send("-1")
            mWebSocket!!.close(1000, null)
            mHandler.removeCallbacks(heartBeatRunnable)
        }
    }

    class MsgBean(var type: Int, var token: String)
}