package com.example.defenseapplication.home

import android.Manifest
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.ScanResult
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.defenseapplication.R
import com.example.defenseapplication.adapter.WifiListAdapter
import com.example.defenseapplication.databinding.AddFamilyActivityBinding
import com.example.defenseapplication.databinding.DialogWifiListBinding
import com.gyf.immersionbar.ImmersionBar

//选择wifi页面
class AddFamilyActivity : AppCompatActivity() {

    private lateinit var binding: AddFamilyActivityBinding
    private lateinit var wifiManager: WifiManager
    private lateinit var connectivityManager: ConnectivityManager
    private lateinit var wifiScanReceiver: BroadcastReceiver
    private var popupWindow: PopupWindow? = null
    private val handler = Handler(Looper.getMainLooper())
    private var isConnecting = false
    private var targetWifiName: String = ""
    private var networkCallback: ConnectivityManager.NetworkCallback? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = AddFamilyActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ImmersionBar.with(this)
            .statusBarDarkFont(true)
            .titleBar(binding.topBar)
            .init()
        binding.ivBack.setOnClickListener {
            finish()
        }

        binding.btnSelectWifi.setOnClickListener {
            showWifiListDialog()
        }

        binding.etWifiName.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

            override fun afterTextChanged(s: Editable?) {
                updateBottomButtonVisibility()
            }
        })
        wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        wifiScanReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
                if (success) {
                    updateWifiList()
                }
            }
        }
        binding.btnConfirm.setOnClickListener {
            //startActivity(Intent(this, ConnectDeviceActivity::class.java))
            if (isConnecting) {
                return@setOnClickListener
            }

            val wifiName = binding.etWifiName.text.toString().trim()
            val wifiPassword = binding.etWifiPassword.text.toString()

            if (wifiName.isEmpty()) {
                Toast.makeText(this, R.string.enter_wifi_name, Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            if (wifiPassword.isEmpty()) {
                Toast.makeText(this, R.string.enter_wifi_password, Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            isConnecting = true
            binding.btnConfirm.isEnabled = false

            verifyWifiPassword(wifiName, wifiPassword)
        }
    }

    private fun verifyWifiPassword(wifiName: String, wifiPassword: String) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) 
            != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) 
            != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, 
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, 
                        Manifest.permission.CHANGE_WIFI_STATE,
                        Manifest.permission.ACCESS_NETWORK_STATE), 
                1002)
            return
        }

        targetWifiName = wifiName

        if (!wifiManager.isWifiEnabled) {
            wifiManager.isWifiEnabled = true
        }

        val existingConfig = findExistingWifiConfig(wifiName)
        var netId: Int

        if (existingConfig != null) {
            netId = existingConfig.networkId
            existingConfig.preSharedKey = "\"$wifiPassword\""
            wifiManager.updateNetwork(existingConfig)
        } else {
            val wifiConfig = createWifiConfig(wifiName, wifiPassword)
            netId = wifiManager.addNetwork(wifiConfig)
        }

        if (netId == -1) {
            isConnecting = false
            binding.btnConfirm.isEnabled = true
            ToastUtils.showError(this, getString(R.string.wifi_connection_failed))
            return
        }

        networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                checkWifiConnected()
            }

            override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
                super.onCapabilitiesChanged(network, capabilities)
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    checkWifiConnected()
                }
            }
        }

        val request = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .build()

        connectivityManager.registerNetworkCallback(request, networkCallback!!)

        wifiManager.enableNetwork(netId, true)
        wifiManager.saveConfiguration()

        handler.postDelayed({
            if (isConnecting) {
                isConnecting = false
                binding.btnConfirm.isEnabled = true
                networkCallback?.let {
                    try {
                        connectivityManager.unregisterNetworkCallback(it)
                    } catch (e: Exception) {
                    }
                }
                networkCallback = null
                ToastUtils.showError(this, getString(R.string.wifi_connection_failed))
            }
        }, 15000)
    }

    private fun findExistingWifiConfig(wifiName: String): WifiConfiguration? {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED) {
            return null
        }
        val configuredNetworks = wifiManager.configuredNetworks
        configuredNetworks?.forEach { config ->
            if (config.SSID == "\"$wifiName\"") {
                return config
            }
        }
        return null
    }

    private fun checkWifiConnected() {
        if (!isConnecting) return

        val info = wifiManager.connectionInfo
        if (info.ssid == "\"$targetWifiName\"" && info.networkId != -1) {
            isConnecting = false
            binding.btnConfirm.isEnabled = true
            networkCallback?.let {
                try {
                    connectivityManager.unregisterNetworkCallback(it)
                } catch (e: Exception) {
                }
            }
            networkCallback = null
            runOnUiThread {
                ToastUtils.showSuccess(this@AddFamilyActivity, getString(R.string.wifi_connection_success))
                val intent = Intent(this@AddFamilyActivity, ConnectDeviceActivity::class.java)
                intent.putExtra("wifi_name", targetWifiName)
                startActivity(intent)
            }
        }
    }

    private fun createWifiConfig(ssid: String, password: String): WifiConfiguration {
        val config = WifiConfiguration()
        config.SSID = "\"$ssid\""
        config.preSharedKey = "\"$password\""
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
        return config
    }

    private fun showWifiListDialog() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) 
            != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, 
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE), 
                1001)
            return
        }

        if (!wifiManager.isWifiEnabled) {
            wifiManager.isWifiEnabled = true
        }

        wifiManager.startScan()

        val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this))
        popupWindow = PopupWindow(
            dialogBinding.root,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        ).apply {
            isFocusable = true
            setBackgroundDrawable(null)
            setOnDismissListener {
                binding.maskView.visibility = android.view.View.GONE
            }
            showAtLocation(window.decorView, Gravity.BOTTOM, 0, 0)
        }

        binding.maskView.visibility = android.view.View.VISIBLE

        dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@AddFamilyActivity)
        
        val wifiList = getWifiList()
        dialogBinding.rvWifiList.adapter = WifiListAdapter(wifiList) { wifiName ->
            binding.etWifiName.setText(wifiName)
            popupWindow?.dismiss()
        }
    }

    private fun updateBottomButtonVisibility() {
        val wifiName = binding.etWifiName.text.toString().trim()
        binding.bottomButtonLayout.visibility = 
            if (wifiName.isNotEmpty()) android.view.View.VISIBLE else android.view.View.GONE
    }

    private fun getWifiList(): List<String> {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED) {
            return emptyList()
        }
        val results: List<ScanResult> = wifiManager.scanResults
        return results.map { it.SSID }.distinct()
    }

    private fun updateWifiList() {
        popupWindow?.contentView?.findViewById<androidx.recyclerview.widget.RecyclerView>(R.id.rvWifiList)?.let { recyclerView ->
            val wifiList = getWifiList()
            recyclerView.adapter = WifiListAdapter(wifiList) { wifiName ->
                binding.etWifiName.setText(wifiName)
                popupWindow?.dismiss()
            }
        }
    }

    override fun onStart() {
        super.onStart()
        val intentFilter = IntentFilter()
        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
        registerReceiver(wifiScanReceiver, intentFilter)
    }

    override fun onStop() {
        super.onStop()
        unregisterReceiver(wifiScanReceiver)
        popupWindow?.dismiss()
        networkCallback?.let {
            try {
                connectivityManager.unregisterNetworkCallback(it)
            } catch (e: Exception) {
            }
        }
        networkCallback = null
        handler.removeCallbacksAndMessages(null)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            1002 -> {
                if (grantResults.isNotEmpty() && 
                    grantResults.size >= 3 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[2] == PackageManager.PERMISSION_GRANTED) {
                    val wifiName = binding.etWifiName.text.toString().trim()
                    val wifiPassword = binding.etWifiPassword.text.toString()
                    verifyWifiPassword(wifiName, wifiPassword)
                } else {
                    isConnecting = false
                    binding.btnConfirm.isEnabled = true
                    Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}