package com.useasy.callsdk.demo

import android.Manifest
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.FileProvider
import android.util.Log
import android.view.LayoutInflater
import android.widget.Button
import com.useasy.callsdk.CallSDK
import com.useasy.callsdk.bean.AgentConfig
import com.useasy.callsdk.bean.CallDirection
import com.useasy.callsdk.listener.AgentConfigListener
import com.useasy.callsdk.utils.Loger
import com.useasy.callsdk.utils.PermissionHelper
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

/**
 * 拨号盘 Activity
 */
class DialActivity : BaseActivity() {

    companion object {
        const val EXTRA_PHONE_NUMBER = "extra_phone_number"
        private const val PERMISSION_REQUEST_CODE = 1001
    }

    private lateinit var etPhoneNumber: EditText
    private lateinit var kvContainer: LinearLayout
    private var agentConfig: AgentConfig? = null
    private var showSettingsMenu = false
    private var pendingPhoneNumber: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.callsdk_activity_dial)

        initViews()
        setupToolbar()
        bindEvents()

        // 查询坐席配置信息
        queryAgentConfig()

        // 处理传入的电话号码
        intent.getStringExtra(EXTRA_PHONE_NUMBER)?.let { phone ->
            etPhoneNumber.setText(phone)
            etPhoneNumber.setSelection(phone.length)
        }

        setServerCallListener()
    }

    private fun setServerCallListener() {
        // 设置服务端通话监听器：收到服务端发起的通话时，打开通话界面
        CallSDK.setOnServerCallListener { callInfo ->
            Loger.iTag("DialActivity", "收到服务端发起的通话: ${callInfo.callId}")
            val intent = Intent(this@DialActivity, CallActivity::class.java)
            intent.putExtra("callId", callInfo.callId)
            intent.putExtra("phoneNumber", callInfo.phoneNumber)
            intent.putExtra("direction", callInfo.direction.name)
            startActivity(intent)
        }
    }

    private fun setupToolbar() {
        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.setDisplayShowHomeEnabled(true)
        toolbar.setNavigationOnClickListener {
            finish()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        if (showSettingsMenu) {
            menuInflater.inflate(R.menu.menu_dial_settings, menu)
        }
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_settings -> {
                openSettingsPage()
                return true
            }
            R.id.menu_export_log -> {
                exportLogs()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onResume() {
        super.onResume()
        queryAgentConfig()
    }

    /**
     * 查询坐席配置信息
     */
    private fun queryAgentConfig() {
        val loginInfo = CallSDK.getLoginInfo()
        val agentId = loginInfo?.agent?._id

        if (agentId.isNullOrEmpty()) {
            Loger.wTag("DialActivity", "无法获取 agentId，跳过查询坐席配置")
            return
        }

        CallSDK.getAgentConfig(object : AgentConfigListener {
            override fun onSuccess(agentConfig: AgentConfig?) {
                agentConfig?.let { config ->
                    Loger.dTag("DialActivity", "查询坐席配置成功")
                    // 处理配置信息
                    handleAgentConfig(config)
                }
            }

            override fun onFailed(errorMsg: String?) {
                Loger.eTag("DialActivity", "查询坐席配置失败: $errorMsg")
            }
        })
    }

    /**
     * 处理坐席配置信息
     */
    private fun handleAgentConfig(config: AgentConfig) {
        this.agentConfig = config
        val callConfig = config.agentCallConfig
        if (callConfig == null) {
            Loger.wTag("DialActivity", "坐席配置中没有通话配置信息")
            return
        }

        val callerStrategy = callConfig.callerStrategy
        if (callerStrategy != null && callerStrategy.isNotEmpty()) {
            // 判断外显号码配置类型
            val shouldShowSettings = when {
                callerStrategy.contains("enterprise") -> {
                    // 配置的是外显号码
                    val selectNumber = callConfig.selectNumber
                    Loger.dTag("DialActivity", "配置的是外显号码: $selectNumber")
                    true
                }

                callerStrategy.contains("enterpriseGroup") -> {
                    // 配置的是外显号码组
                    val numberGroup = callConfig.numberGroup
                    Loger.dTag("DialActivity", "配置的是外显号码组: $numberGroup")
                    true
                }

                else -> false
            }

            // 显示/隐藏设置菜单
            showSettingsMenu = true
            invalidateOptionsMenu()
        } else {
            showSettingsMenu = true
            invalidateOptionsMenu()
        }
    }

    private fun initViews() {
        etPhoneNumber = findViewById(R.id.call_dialplate_edittext_phonenum)
        kvContainer = findViewById(R.id.ll_kv_container)

        // 添加参数按钮
        findViewById<Button>(R.id.btn_add_param)?.setOnClickListener {
            addKvRow()
        }

        // 退出登录按钮
        findViewById<Button>(R.id.btn_logout)?.setOnClickListener {
            CallSDK.logout()
            Toast.makeText(this, "已退出登录", Toast.LENGTH_SHORT).show()
            finish()
        }

        // 隐藏软键盘
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
        try {
            val cls = EditText::class.java
            val method = cls.getMethod("setShowSoftInputOnFocus", Boolean::class.javaPrimitiveType)
            method.isAccessible = true
            method.invoke(etPhoneNumber, false)
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    private fun bindEvents() {
        val numViewList: List<View> = listOf(
            findViewById(R.id.call_dialNum1),
            findViewById(R.id.call_dialNum2),
            findViewById(R.id.call_dialNum3),
            findViewById(R.id.call_dialNum4),
            findViewById(R.id.call_dialNum5),
            findViewById(R.id.call_dialNum6),
            findViewById(R.id.call_dialNum7),
            findViewById(R.id.call_dialNum8),
            findViewById(R.id.call_dialNum9),
            findViewById(R.id.call_dial_call),
            findViewById(R.id.call_dialNum0),
            findViewById(R.id.call_dial_delete_btn),
            findViewById(R.id.call_dialNum_star),
            findViewById(R.id.call_dialNum_jing),
            findViewById(R.id.keyboard_fold_btn),
            findViewById(R.id.iv_keyboard_expand)
        )

        for (v in numViewList) {
            v?.setOnClickListener { onViewClicked(it) }
        }

        // 长按删除键清空
        findViewById<View>(R.id.call_dial_delete_btn)?.setOnLongClickListener {
            etPhoneNumber.setText("")
            false
        }
    }

    /**
     * 打开设置页面
     */
    private fun openSettingsPage() {
        val intent = Intent(this, CallSettingsActivity::class.java)
        agentConfig?.let { config ->
            intent.putExtra(CallSettingsActivity.EXTRA_AGENT_CONFIG, config)
        }
        startActivity(intent)
    }

    private fun onViewClicked(view: View) {
        val sb = StringBuilder(etPhoneNumber.text.toString())
        when (view.id) {
            R.id.call_dialNum1 -> sb.append("1")
            R.id.call_dialNum2 -> sb.append("2")
            R.id.call_dialNum3 -> sb.append("3")
            R.id.call_dialNum4 -> sb.append("4")
            R.id.call_dialNum5 -> sb.append("5")
            R.id.call_dialNum6 -> sb.append("6")
            R.id.call_dialNum7 -> sb.append("7")
            R.id.call_dialNum8 -> sb.append("8")
            R.id.call_dialNum9 -> sb.append("9")
            R.id.call_dialNum_star -> sb.append("*")
            R.id.call_dialNum_jing -> sb.append("#")
            R.id.call_dialNum0 -> sb.append("0")
            R.id.call_dial_delete_btn -> {
                val index = etPhoneNumber.selectionStart
                if (index > 0) {
                    sb.deleteCharAt(index - 1)
                }
            }

            R.id.call_dial_call -> {
                val phone = etPhoneNumber.text.toString().trim()
                if (phone.isNotEmpty()) {
                    makeAppCall(phone)
                } else {
                    Toast.makeText(this, "请输入电话号码", Toast.LENGTH_SHORT).show()
                }
                return
            }

            R.id.keyboard_fold_btn -> {
                toggleKeyboard(false)
                return
            }

            R.id.iv_keyboard_expand -> {
                toggleKeyboard(true)
                return
            }
        }

        if (sb.length < 18) {
            etPhoneNumber.setText(sb.toString())
            etPhoneNumber.setSelection(sb.length)
        }
    }

    /**
     * 网络电话（App拨打）
     */
    private fun makeAppCall(phone: String) {
        if (phone.isEmpty()) {
            Toast.makeText(this, "请输入电话号码", Toast.LENGTH_SHORT).show()
            return
        }

        // 检查录音权限
        if (!PermissionHelper.hasRecordAudioPermission(this)) {
            // 保存待拨打的电话号码
            pendingPhoneNumber = phone
            // 申请权限
            requestRecordAudioPermission()
            return
        }

        // 有权限，直接拨打电话
        doMakeCall(phone)
    }

    /**
     * 申请录音权限
     */
    private fun requestRecordAudioPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(
                this, arrayOf(Manifest.permission.RECORD_AUDIO), PERMISSION_REQUEST_CODE
            )
        }
    }

    /**
     * 处理权限申请结果
     */
    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (PermissionHelper.isPermissionGranted(grantResults)) {
                // 权限申请成功，继续拨打电话
                pendingPhoneNumber?.let { phone ->
                    pendingPhoneNumber = null
                    doMakeCall(phone)
                }
            } else {
                // 权限申请失败
                pendingPhoneNumber = null
                Toast.makeText(this, "需要录音权限才能拨打电话", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * 执行拨打电话
     */
    private fun doMakeCall(phone: String) {
        val intent = Intent(this@DialActivity, CallActivity::class.java)
        intent.putExtra("phoneNumber", phone)
        intent.putExtra("direction", CallDirection.APP.name)
        val userData = collectUserData()
        if (userData.isNotEmpty()) {
            intent.putExtra("userData", userData)
        }
        startActivity(intent)
    }

    /**
     * 添加一行 key-value 输入
     */
    private fun addKvRow() {
        val row = LayoutInflater.from(this)
            .inflate(R.layout.callsdk_item_kv_param, kvContainer, false)
        row.findViewById<ImageView>(R.id.iv_remove_param)?.setOnClickListener {
            kvContainer.removeView(row)
        }
        kvContainer.addView(row)
    }

    /**
     * 收集所有 key-value 参数，组装为 JSON 字符串
     */
    private fun collectUserData(): String {
        val json = org.json.JSONObject()
        for (i in 0 until kvContainer.childCount) {
            val row = kvContainer.getChildAt(i)
            val key = row.findViewById<EditText>(R.id.et_param_key)?.text?.toString()?.trim() ?: ""
            val value = row.findViewById<EditText>(R.id.et_param_value)?.text?.toString()?.trim() ?: ""
            if (key.isNotEmpty()) {
                json.put(key, value)
            }
        }
        return if (json.length() > 0) json.toString() else ""
    }


    private fun toggleKeyboard(expand: Boolean) {
        val keyboardLayout = findViewById<View>(R.id.keyboard_layout)
        val expandBtn = findViewById<ImageView>(R.id.iv_keyboard_expand)

        keyboardLayout?.visibility = if (expand) View.VISIBLE else View.GONE
        expandBtn?.visibility = if (expand) View.GONE else View.VISIBLE
    }

    /**
     * 导出日志：将 logs 目录下的日志文件打包为 zip，通过系统分享发送
     */
    private fun exportLogs() {
        try {
            val logDir = File(filesDir, "logs")
            if (!logDir.exists() || logDir.listFiles().isNullOrEmpty()) {
                Toast.makeText(this, "暂无日志文件", Toast.LENGTH_SHORT).show()
                return
            }

            val logFiles = logDir.listFiles { file -> file.isFile && file.length() > 0 }
            if (logFiles.isNullOrEmpty()) {
                Toast.makeText(this, "暂无日志文件", Toast.LENGTH_SHORT).show()
                return
            }

            // 打包为 zip
            val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
            val zipFile = File(cacheDir, "callsdk-logs-$timestamp.zip")
            ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile))).use { zos ->
                for (file in logFiles) {
                    BufferedInputStream(FileInputStream(file)).use { bis ->
                        zos.putNextEntry(ZipEntry(file.name))
                        bis.copyTo(zos)
                        zos.closeEntry()
                    }
                }
            }

            // 通过 FileProvider 分享
            val uri = FileProvider.getUriForFile(this, "$packageName.fileprovider", zipFile)
            val shareIntent = Intent(Intent.ACTION_SEND).apply {
                type = "application/zip"
                putExtra(Intent.EXTRA_STREAM, uri)
                putExtra(Intent.EXTRA_SUBJECT, "CallSDK 日志 $timestamp")
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            startActivity(Intent.createChooser(shareIntent, "发送日志"))
        } catch (e: Exception) {
            Toast.makeText(this, "导出日志失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

}
