package com.duolebo.blyrobot

import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Toast
import com.duolebo.appbase.AppBaseHandler
import com.duolebo.appbase.IAppBaseCallback
import com.duolebo.appbase.IProtocol
import com.duolebo.blyrobot.data.ApkInfo
import com.duolebo.blyrobot.data.ApkPackageInfo
import com.duolebo.blyrobot.data.AppInfoData
import com.duolebo.blyrobot.data.Task
import com.duolebo.blyrobot.protocol.GetAppInfoProtocol
import com.duolebo.blyrobot.service.BylRobotService
import com.duolebo.blyrobot.tools.TaskManager
import com.duolebo.blyrobot.ui.AppConfigListItem
import com.duolebo.blyrobot.util.AdbUtil
import com.duolebo.blyrobot.util.AppUtil
import com.duolebo.blyrobot.util.Config
import com.duolebo.blyrobot.util.Constants
import com.minhui.vpn.utils.ThreadProxy
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*


class MainActivity : AppCompatActivity(), IAppBaseCallback {

    private val TAG = "MainActivity"
    private lateinit var apkInfoProtocol: GetAppInfoProtocol
    private lateinit var dataHandler: AppBaseHandler
    private lateinit var appInfoAdapter: AppConfigAdapter
    private lateinit var refreshTimer: Timer
    private lateinit var appInfoData: AppInfoData
    private var startSet = false
    private var isStart = false

    private var apkPackageInfo: List<ApkPackageInfo>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.i(TAG, "onCreate....")
        setContentView(R.layout.activity_main)

        getLocalAppList()

        this.appInfoAdapter = AppConfigAdapter()
        listView.adapter = this.appInfoAdapter

        initRefreshTimer()

        val hasRoot = AdbUtil.checkRootPermission()
        if (hasRoot) {
            Log.i(TAG, "rooted...")
            textView.setText(R.string.tips_device_rooted)
        }
        else {
            textView.setText(R.string.tips_device_not_root)
        }

        AdbUtil.exeCmdEcho("ls", true)

        startRobotService()

        startBtn.setOnClickListener{
            if (isStart) {
                stop()
            }
            else {
                start()
            }

            isStart = !isStart
        }
        startBtn.requestFocus()

        requestAppList()

        refreshBtn.isEnabled = true
        refreshBtn.setOnClickListener{
            this.appInfoAdapter.clear()
            requestAppList()
        }

    }

    private fun start() {
        startBtn.isEnabled = false
        if (TaskManager.instance.tasks.size > 0) {
            startRobot()

            startBtn.postDelayed({
                startBtn.isEnabled = true
                startBtn.text = "停止"
                refreshBtn.isEnabled = false
            }, 2000)
        }
        else {
            startSet = true
            requestAppList()
        }
    }

    private fun stop() {
        if (TaskManager.instance.isRunning) {
            stopRobot()
            startBtn.isEnabled = false
            startBtn.postDelayed({
                startBtn.isEnabled = true
                startBtn.text = "启动"
                refreshBtn.isEnabled = true
            }, 3000)
        }
    }

    private fun resetStartBtn() {
        startBtn.isEnabled = true
        startBtn.text = "开始"
        refreshBtn.isEnabled = true
    }

    private fun requestAppList() {
        apkInfoProtocol = GetAppInfoProtocol(this, Config.instance)
        this.dataHandler = AppBaseHandler(this)
        apkInfoProtocol.execute(this.dataHandler)
    }

    private fun getLocalAppList() {
        ThreadProxy.getInstance().execute {
            apkPackageInfo = ApkPackageInfo.getAppInfos(applicationContext)
            runOnUiThread {
                appInfoAdapter.notifyDataSetChanged()
            }
        }
    }

    private fun initRefreshTimer() {
        refreshTimer = Timer()

        refreshTimer.schedule(object: TimerTask() {
            override fun run() {
                runOnUiThread {
                    updateListStatus()
                }
            }
        },2000, 2*60*1000)
    }

    private fun updateListStatus() {

    }

    private fun startRobotService() {
        startService(Intent(this, BylRobotService::class.java))
    }

    private fun startRobot() {
        Log.i(TAG, "startRobot...")
        val intent = Intent(Constants.ACTION_LOCAL_SERVICE)
        intent.putExtra(Constants.KEY_CMD, Constants.CMD_START)
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    private fun stopRobot() {
        val intent = Intent(Constants.ACTION_LOCAL_SERVICE)
        intent.putExtra(Constants.KEY_CMD,  Constants.CMD_STOP)
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    override fun onProtocolFailed(protocol: IProtocol?) {
        Toast.makeText(this, "获取应用列表信息出错", Toast.LENGTH_SHORT).show()
        if (startSet) {
            resetStartBtn()
            startSet = false
        }
    }

    override fun onHttpFailed(protocol: IProtocol?) {
        Toast.makeText(this, "网络错误", Toast.LENGTH_SHORT).show()
        if (startSet) {
            resetStartBtn()
            startSet = false
        }
    }

    override fun onProtocolSucceed(protocol: IProtocol?) {
        if (protocol is GetAppInfoProtocol) {
            this.appInfoData =  protocol.data as AppInfoData
            this.appInfoAdapter.setData(appInfoData.apkInfos)
            this.appInfoAdapter.notifyDataSetChanged()

            if (!TaskManager.instance.isRunning) {
                for (apkInfo in appInfoData.apkInfos) {
                    if (apkInfo.monitoring && AppUtil.isAppInstalled(this, apkInfo.packageName)) {
                        val task = Task(this.applicationContext)
                        task.from(apkInfo)
                        TaskManager.instance.add(task)
                    }
                }
            }

            if (startSet) {
                startBtn.isEnabled = true
                if (TaskManager.instance.tasks.size > 0) {
                    startRobot()
                    startSet = false
                    startBtn.text = "停止"
                    refreshBtn.isEnabled = false
                }
                else {
                    Toast.makeText(this, "没有任务可以执行", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    fun getAppIcon(packageName: String): Drawable? {
        var drawable:Drawable ?= null
        apkPackageInfo?.run {
            val targetPackage = this.find {
                it.packageName == packageName
            }

            if (targetPackage != null) {
                drawable = targetPackage.applicationInfo.loadIcon(packageManager)
            }
        }

        return drawable
    }

    inner class AppConfigAdapter: BaseAdapter() {

        private val dataList = ArrayList<ApkInfo>()

        fun setData(dataList: ArrayList<ApkInfo>) {
            this.dataList.clear()
            this.dataList.addAll(dataList)
        }

        fun clear() {
            this.dataList.clear()
            notifyDataSetChanged()
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            var itemView: AppConfigListItem
            if (convertView == null) {
                itemView = AppConfigListItem(parent.context)
            }
            else
                itemView = convertView as AppConfigListItem

            itemView.setData(dataList[position])
            val drawable = getAppIcon(dataList[position].packageName)
            drawable?.run {
                itemView.setIcon(this)
            }

            return itemView
        }

        override fun getItem(position: Int): Any {
            return dataList[position]
        }

        override fun getItemId(position: Int): Long {
            return 0
        }

        override fun getCount(): Int {
            return dataList.size
        }

    }
}
