package com.pan_american.android.data.network

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.microsoft.signalr.HubConnection
import com.microsoft.signalr.HubConnectionBuilder
import com.pan_american.android.OASystem
import com.pan_american.android.data.model.message.entity.MessageGetter
import com.pan_american.android.data.model.message.network.MessageUnReadCountRequest
import com.pan_american.android.data.model.message.network.MessageUnReadTotalResponse
import org.greenrobot.eventbus.EventBus
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class TCPService: Service() {

    companion object {

        val TAG: String = TCPService::class.java.simpleName

        val apiService = ServiceCreator.create<APIService>()

        const val HEART_SPACE_TIME: Long = 1000

        //消息系统 MS HubConnection
        val hubConnection: HubConnection = HubConnectionBuilder.create("http://132.232.92.186:8888/chatHub")
            .withHeader("Authorization", OASystem.token)
            .build().apply {
                serverTimeout = 60 * HEART_SPACE_TIME
                keepAliveInterval = HEART_SPACE_TIME
            }
    }

    override fun onBind(p0: Intent?): ClientBinder {
        return ClientBinder()
    }

    class ClientBinder : Binder() {
        //心跳间隔时间

        private lateinit var readThread: ReadThread
        private val handler = Handler(Looper.getMainLooper())
        private lateinit var executorService: ExecutorService
        private var connectionTryCount = 0
        private var heartSpaceTryCount = 0

        fun startConnect() {
            //在子线程进行网络操作
            //Service 运行在主线程

            executorService = Executors.newCachedThreadPool()
            executorService.execute(connectRunnable)
        }

        private fun restartConnect() {
            executorService.execute(connectRunnable)
        }

        private val connectRunnable = Runnable {

            try {

                hubConnection.start().blockingAwait()

                //创建读取服务器心跳的线程
                readThread = ReadThread()
                readThread.start()

                //开启心跳,每隔30秒钟发送一次心跳
                handler.post(heartRunnable)

                connectionTryCount = 0

            } catch (e: Exception) {

                connectionTryCount ++

//                Log.e(TAG, e.stackTraceToString())

                Log.e(TAG, "Connection failed, try reconnect. Count: $connectionTryCount")

                handler.postDelayed({ restartConnect() }, HEART_SPACE_TIME)
            }
        }

        inner class ReadThread: Thread() {

            override fun run() {
                super.run()

                try {
                    hubConnection.on("ReceiveMessage", { message ->

//                        Log.e(TAG,"Get message from server. $message")

                        if (!message.contains("已上线")) {
                            when {
                                message.contains("操作") -> {
                                    val messageGetter = MessageGetter(message, 1)
                                    getUnReadTotalCount(messageGetter)
                                }
                                message.contains("任务") -> {
                                    val messageGetter = MessageGetter(message, 2)
                                    getUnReadTotalCount(messageGetter)
                                }
                            }

                        }

                    }, String::class.java)

                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        private val heartRunnable = Runnable {
            sendData()
        }

        private fun sendData() {

            executorService.execute {
                try {

                    hubConnection.send("SignalRLogin", OASystem.userInfo.userId)

                    //发送成功以后，重新建立一个心跳消息
                    handler.postDelayed(heartRunnable, HEART_SPACE_TIME * 30)

//                    Log.e(TAG, "Send message to server.")

                    heartSpaceTryCount = 0

                } catch (e: Exception) {

                    heartSpaceTryCount ++

//                    Log.e(TAG, e.stackTraceToString())

                    Log.e(TAG, "Get heartSpase failed，try to reconnect. Count: $heartSpaceTryCount")

                    executorService.execute(connectRunnable)
                }
            }
        }

        private fun getUnReadTotalCount(messageGetter: MessageGetter) {
            apiService.getMessageUnReadTotal(MessageUnReadCountRequest()).enqueue(object :
                Callback<MessageUnReadTotalResponse> {
                override fun onResponse(
                    call: Call<MessageUnReadTotalResponse>,
                    response: Response<MessageUnReadTotalResponse>
                ) {
                    val unreadCountResponse = response.body()

                    if (unreadCountResponse != null) {
                        if (unreadCountResponse.code == 200) {
                            OASystem.unReadCount = unreadCountResponse.data.messageUnReadCount - unreadCountResponse.data.announcementUnReadCount
                            OASystem.announcementUnReadCount = unreadCountResponse.data.announcementUnReadCount
                            EventBus.getDefault().post(messageGetter)
                        }
                    }
                }

                override fun onFailure(call: Call<MessageUnReadTotalResponse>, t: Throwable) {

                }
            })
        }

    }
}