package com.feasycom.feasybeacon.ui.about.suota.activities

import android.Manifest
import android.bluetooth.BluetoothDevice
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.dialog.suotalib.adapters.BluetoothScanAdapter
import com.dialog.suotalib.dialogs.DialogFragmentBuilder
import com.dialog.suotalib.dialogs.SupportCustomDialogFragment
import com.dialog.suotalib.global.SuotaLibConfig
import com.dialog.suotalib.global.SuotaProfile
import com.dialog.suotalib.interfaces.callbacks.ISuotaScanner
import com.dialog.suotalib.model.BluetoothDeviceScanned
import com.dialog.suotalib.model.ScanAdapterItem
import com.dialog.suotalib.scan.SuotaScanner
import com.dialog.suotalib.suota.SuotaFile
import com.dialog.suotalib.utils.RuntimePermissionChecker
import com.feasycom.feasybeacon.R
import com.feasycom.feasybeacon.databinding.ActivityScanBinding
import com.feasycom.feasybeacon.ui.about.suota.global.SharedPreferencesUtils.fileDirectoriesCreated
import com.feasycom.feasybeacon.ui.about.suota.global.SharedPreferencesUtils.setFileDirectoriesCreated
import com.feasycom.feasybeacon.ui.base.BaseActivity
import com.feasycom.util.ToastUtil

class ScanActivity : BaseActivity<ActivityScanBinding>(), ISuotaScanner,  BluetoothScanAdapter.ScanItemClickListener{

    private lateinit var suotaScanner: SuotaScanner
    private lateinit var scanAdapter: BluetoothScanAdapter
    private var dialogFragment: SupportCustomDialogFragment? = null
    private val scannedDevices: HashMap<String, BluetoothDevice> = HashMap() // 扫描到的设备
    private lateinit var runtimePermissionChecker: RuntimePermissionChecker

    override fun getViewBinding() = ActivityScanBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupPermissionChecker(savedInstanceState)
        setupScanner(savedInstanceState)
    }

    override fun initView() {
        initialize()
    }

    private fun initialize() {
        binding.header.headerLeft.text = getString(R.string.back)
        binding.header.headerLeft.setOnClickListener { finish() }
        binding.header.headerTitle.text = getString(R.string.suota_upgrade)
        binding.swipeToRefresh.setColorSchemeResources(R.color.purple_200)
        binding.swipeToRefresh.setOnRefreshListener {
            scan()
            binding.swipeToRefresh.isRefreshing = false
        }
        scanAdapter = BluetoothScanAdapter(-1, ArrayList(), ArrayList(), this)
        scanAdapter.createTouchDetector(binding.deviceList)
        binding.deviceList.adapter = scanAdapter
        binding.deviceList.layoutManager = LinearLayoutManager(this)
        binding.deviceList.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    }

    private fun setupPermissionChecker(savedInstanceState: Bundle?) {
        runtimePermissionChecker = RuntimePermissionChecker(this, savedInstanceState)
        runtimePermissionChecker.setRationaleIcon(R.drawable.suota_ic_info_outline_black_36dp)

        val isFirstTimePermission = getPreferences(MODE_PRIVATE).getBoolean("oneTimePermissionRationale", true)
        if (isFirstTimePermission) {
            getPreferences(MODE_PRIVATE).edit().putBoolean("oneTimePermissionRationale", false).apply()
            runtimePermissionChecker.setOneTimeRationale(getString(if (!SuotaLibConfig.SCOPED_STORAGE) R.string.permission_rationale_storage_location else R.string.permission_rationale_location))
        }

        if (!SuotaLibConfig.SCOPED_STORAGE) {
            runtimePermissionChecker.registerPermissionRequestCallback(STORAGE_PERMISSION_REQUEST_CODE) { _, _, denied ->
                if (denied == null) {
                    storagePermissionGranted()
                } else {
                    storagePermissionDenied()
                }
            }
        }
    }

    private fun storagePermissionGranted() {
        if (fileDirectoriesCreated(this)) {
            scan()
            return
        }

        if (SuotaFile.createDirectory()) {
            setFileDirectoriesCreated(this)
        }
        scan()
    }

    private fun storagePermissionDenied() {
        // 处理存储权限被拒绝的情况
        dialogFragment = DialogFragmentBuilder()
            .setTitle(getString(R.string.storage_permission_denied_title))
            .setIconResourceId(R.drawable.suota_ic_error_outline_black_36dp)
            .setMessage(getString(R.string.storage_permission_denied_msg))
            .buildV4()
        dialogFragment?.setOnDismissListener { finish() }
        dialogFragment?.showDialog(supportFragmentManager)
    }

    private fun setupScanner(savedInstanceState: Bundle?) {
        suotaScanner = SuotaScanner.Builder()
            .setLifecycle(lifecycle)
            .setActivity(this)
            .setSaveInstanceState(savedInstanceState)
            .setPermissionChecker(runtimePermissionChecker)
            .build()

        if (!SuotaLibConfig.SCOPED_STORAGE) {
            if (runtimePermissionChecker.checkPermissions(
                    arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE),
                    R.string.suota_storage_permission_rationale,
                    STORAGE_PERMISSION_REQUEST_CODE
            )) {
                storagePermissionGranted()
            }
        } else {
            scan()
        }
    }

    private fun scan() {
        reset()
        suotaScanner.scan(this)
    }

    private fun reset() {
        scannedDevices.clear()
        scanAdapter.clear()
        scanAdapter.notifyDataSetChanged()
    }

    override fun onScanItemClick(
        device: BluetoothDevice?,
        bluetoothDeviceScanned: ScanAdapterItem?,
        rssi: Int
    ) {
        val intent = Intent(this, SuotaActivity::class.java)
        intent.putExtra("BluetoothDevice", device)
        startActivity(intent)
    }

    override fun onFailure(failure: SuotaProfile.ScanFailure?) {
        when (failure) {
            SuotaProfile.ScanFailure.BLE_NOT_SUPPORTED -> {
                ToastUtil.show(this, getString(R.string.ble_not_supported))
            }
            SuotaProfile.ScanFailure.RESCANNING_TOO_SOON -> {
                ToastUtil.show(this, getString(R.string.constantly_scanning))
            }
            else -> suotaScanner.stopScan()
        }
    }

    override fun onDeviceScan(
        bluetoothDevice: BluetoothDevice?,
        rssi: Int,
        scanRecord: ByteArray?
    ) {
        scannedDevices[bluetoothDevice!!.address] = bluetoothDevice
        scanAdapter.insertItem(bluetoothDevice, BluetoothDeviceScanned(bluetoothDevice.name, bluetoothDevice.address, rssi, false))
    }

    override fun onScanStatusChange(newStatus: SuotaProfile.ScanStatus?) {
        if (newStatus == SuotaProfile.ScanStatus.STOPPED) {
            if (scanAdapter.itemCount == 0) {
                binding.deviceList.visibility = View.GONE
                binding.empty.visibility = View.VISIBLE
            }
            scanAdapter.updateOnce()
        } else {
            binding.deviceList.visibility = View.VISIBLE
            binding.empty.visibility = View.GONE
        }
        invalidateOptionsMenu()
    }

    companion object {
        private const val TAG = "ScanActivity"
        private const val STORAGE_PERMISSION_REQUEST_CODE = 1
    }

}