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 apkPackageInfo: List<ApkPackageInfo>? = null

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

        init()
    }

    private fun init() {
        getLocalAppList()

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

        listView.setOnItemClickListener { _, _, position, _ ->
            val itemData = this.appInfoAdapter.getItem(position) as ApkInfo
            AdbUtil.launchApp("${itemData.packageName}/${itemData.launcher}")
        }

        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.isEnabled = !TaskManager.instance.isRunning
        startBtn.setOnClickListener{
            start()
        }
        startBtn.requestFocus()

        stopBtn.isEnabled = TaskManager.instance.isRunning
        stopBtn.setOnClickListener{
            stop()
        }

        requestAppList()

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

        clearBtn.setOnClickListener {
            clearCache()
        }
    }

    private fun start() {
        startBtn.isEnabled = false
        startBtn.isFocusable = false
        stopBtn.isEnabled = true
        stopBtn.isFocusable = true
        if (TaskManager.instance.tasks.size > 0) {
            startRobot()
        }
        else {
            startSet = true
            requestAppList()
        }
    }

    private fun stop() {
        Toast.makeText(this, "正在停止任务，请稍候...", Toast.LENGTH_SHORT).show()
        stopRobot()
        stopBtn.isEnabled = false
        stopBtn.isFocusable = false
        startBtn.isEnabled = true
        startBtn.isFocusable = true
    }

    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 clearCache() {
        clearBtn.isEnabled = false
        ThreadProxy.getInstance().execute {
            AppUtil.clearCache()
            runOnUiThread {
                clearBtn.isEnabled = true
            }
        }
    }

    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)
        sendBroadcast(intent)

        Toast.makeText(this, "开始执行监播任务，本应用转至后台", Toast.LENGTH_SHORT).show()
        finish()
    }

    private fun stopRobot() {
        val intent = Intent(Constants.ACTION_LOCAL_SERVICE)
        intent.putExtra(Constants.KEY_CMD,  Constants.CMD_STOP)
        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
                }
                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

            val itemData = dataList[position]
            itemView.setData(dataList[position])
            val drawable = getAppIcon(itemData.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
        }

    }
}
