package com.pan_american.android.ui.workspace

import android.Manifest.permission.POST_NOTIFICATIONS
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.PowerManager
import android.os.Process
import android.provider.Settings
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.pan_american.android.OASystem
import com.pan_american.android.R
import com.pan_american.android.base.BaseActivity
import com.pan_american.android.base.CustomAlertDialog
import com.pan_american.android.data.model.common.adapter.ViewPager2Adapter
import com.pan_american.android.data.model.common.entity.RequestCodeBean
import com.pan_american.android.data.model.message.entity.MessageGetter
import com.pan_american.android.data.network.TCPService
import com.pan_american.android.databinding.ActivityWorkspaceBinding
import com.pan_american.android.ui.announcement.AnnouncementFragment
import com.pan_american.android.ui.document.DocumentFragment
import com.pan_american.android.ui.message.MessageFragment
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class WorkspaceActivity : BaseActivity<ActivityWorkspaceBinding>() {

    private var exitTime: Long = 0

    private var isActive = true

    private lateinit var manager: NotificationManager

    private var operationNotification = false

    private var announcementNotification = false

    //监听通知事件回调
    private lateinit var result: ActivityResultLauncher<Intent>

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val clientBinder = service as TCPService.ClientBinder
            clientBinder.startConnect()
        }

        override fun onServiceDisconnected(p0: ComponentName?) {
//            Log.e("TCPService", "disconnected")
        }
    }

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

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

        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (System.currentTimeMillis() - exitTime > 2000) {
                    showMessage(resources.getString(R.string.press_back_again_exit))
                    exitTime = System.currentTimeMillis()
                } else {
                    finish()
                    Process.killProcess(Process.myPid())
                }
            }
        }

        onBackPressedDispatcher.addCallback(this, callback)

        result = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (NotificationManagerCompat.from(this).areNotificationsEnabled()) {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)

                showIgnoreBatteryDialog()
            }
        }

        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }

        initBottomNavigation()
    }

    override fun onStart() {
        super.onStart()

        isActive = true

        operationNotification = intent.getBooleanExtra("operation_notification", false)
        announcementNotification = intent.getBooleanExtra("announcement_notification", false)

        if (operationNotification) {
            if (binding.navViewpage2.currentItem != 0) {
                binding.navViewpage2.currentItem = 0
                binding.navView.selectedItemId = R.id.navigation_message
                intent.removeExtra("operation_notification")
            }
        }

        if (announcementNotification) {
            if (binding.navViewpage2.currentItem != 0) {
                binding.navViewpage2.currentItem = 0
                binding.navView.selectedItemId = R.id.navigation_announcement
                intent.removeExtra("announcement_notification")
            }
        }
    }

    override fun onResume() {
        super.onResume()

        //通知权限判断，如果在没杀app的情况下重新打开通知权限，则开启TCPService
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ActivityCompat.checkSelfPermission(
                    this, POST_NOTIFICATIONS
                ) == PackageManager.PERMISSION_DENIED
            ) {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(
                        this, POST_NOTIFICATIONS
                    )
                ) {
                    showNotificationPermissionDialog()
                } else {
                    val intent = Intent(OASystem.context, TCPService::class.java)
                    bindService(intent, connection, BIND_AUTO_CREATE)
                }
            } else {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)
            }
        } else {
            if (!NotificationManagerCompat.from(this).areNotificationsEnabled()) {
                showNotificationPermissionDialog()
            } else {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)
            }
        }

        initViews()
    }

    override fun onPause() {
        super.onPause()

        isActive = false
    }

    override fun initViews() {
        initUnReadCount()
    }

    private fun initUnReadCount() {
        OASystem.unReadCount.apply {
            if (this > 0) {
                val bride = binding.navView.getOrCreateBadge(R.id.navigation_message)

                bride.backgroundColor =
                    ResourcesCompat.getColor(resources, R.color.color_caution, null)

                bride.number = this

                bride.maxCharacterCount = 3

                bride.verticalOffset = 20
            } else {
                binding.navView.removeBadge(R.id.navigation_message)
            }
        }

        OASystem.announcementUnReadCount.apply {
            if (this > 0) {
                val bride = binding.navView.getOrCreateBadge(R.id.navigation_announcement)

                bride.backgroundColor =
                    ResourcesCompat.getColor(resources, R.color.color_caution, null)

                bride.number = this

                bride.maxCharacterCount = 3

                bride.verticalOffset = 20

            } else {
                binding.navView.removeBadge(R.id.navigation_announcement)
            }
        }
    }

    private fun initBottomNavigation() {
        binding.navView.itemIconTintList = null
        binding.navView.removeBadge(R.id.navigation_document)
        //将所有的fragment添加到viewpager2中
        val fragmentList: MutableList<Fragment> = ArrayList()
        fragmentList.add(MessageFragment())
        fragmentList.add(WorkspaceFragment())
        fragmentList.add(AnnouncementFragment())
        fragmentList.add(DocumentFragment())
        //绑定适配器
        binding.navViewpage2.adapter = ViewPager2Adapter(this, fragmentList)
        //ViewPager2不拦截任何事件
        binding.navViewpage2.isUserInputEnabled = false
        //设置默认页面为工作台，并让bottomNavigationView默认选中对应选项
        binding.navViewpage2.currentItem = 1
        binding.navView.selectedItemId = R.id.navigation_workspace
        //当viewpage2页面切换时，导航图标也跟着切换
        binding.navViewpage2.registerOnPageChangeCallback(object :
            ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                binding.navView.menu.getItem(position).isChecked = true
            }
        })
        //当导航点击切换时，viewpager2也跟着切换界面
        binding.navView.setOnItemSelectedListener { item ->
            when (item.itemId) {
                R.id.navigation_message -> {
                    binding.navViewpage2.currentItem = 0
                    return@setOnItemSelectedListener true
                }

                R.id.navigation_workspace -> {
                    binding.navViewpage2.currentItem = 1
                    return@setOnItemSelectedListener true
                }

                R.id.navigation_announcement -> {
                    binding.navViewpage2.currentItem = 2
                    return@setOnItemSelectedListener true
                }

                R.id.navigation_document -> {
                    binding.navViewpage2.currentItem = 3
                    return@setOnItemSelectedListener true
//                    showMessage(resources.getString(R.string.permission_denied))
                }
            }
            false
        }
    }

    private fun showNotificationPermissionDialog() {

        CustomAlertDialog.Builder(this).apply {
            setTitle(resources.getString(R.string.alert))
            setMessage(resources.getString(R.string.notification_permission_denied_hint))
            setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                dialog.dismiss()
            }
            setPositiveButtonAndListener(resources.getString(R.string.go_to_open)) { dialog, _ ->
                dialog.dismiss()
                openNotificationSettingsForApp()
            }
        }.show()
    }

    private fun openNotificationSettingsForApp() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ActivityCompat.checkSelfPermission(
                    this, POST_NOTIFICATIONS
                ) == PackageManager.PERMISSION_DENIED
            ) {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(
                        this, POST_NOTIFICATIONS
                    )
                ) {
                    ActivityCompat.requestPermissions(
                        this, arrayOf(POST_NOTIFICATIONS), OASystem.NOTIFICATION_REQUEST_CODE
                    )
                } else {
                    val intent = Intent(OASystem.context, TCPService::class.java)
                    bindService(intent, connection, BIND_AUTO_CREATE)
                }
            } else {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)
            }
        } else {
            if (!NotificationManagerCompat.from(this).areNotificationsEnabled()) {
                val intent = Intent()
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                    intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                } else {
                    intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
                    intent.putExtra("app_package", packageName)
                    intent.putExtra("app_uid", applicationInfo.uid)
                }
                result.launch(intent)
            } else {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == OASystem.NOTIFICATION_REQUEST_CODE) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                val intent = Intent(OASystem.context, TCPService::class.java)
                bindService(intent, connection, BIND_AUTO_CREATE)

                showIgnoreBatteryDialog()

            } else {
                showMessage(resources.getString(R.string.notification_permission_denied_hint))
            }
        }
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "PanAmerica_Notification_Channel"
            val descriptionText = "PanAmerica_Notification"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel =
                NotificationChannel("PanAmerica_Notification_Channel", name, importance).apply {
                    description = descriptionText
                }
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun showNotification(messageGetter: MessageGetter) {
        val builder = NotificationCompat.Builder(this, "PanAmerica_Notification_Channel").apply {
            setSmallIcon(R.mipmap.ic_launcher)
            setLargeIcon(
                BitmapFactory.decodeResource(
                    OASystem.context.resources, R.mipmap.ic_launcher
                )
            )
            setContentTitle(resources.getString(R.string.app_name))
//            setContentText(resources.getString(R.string.you_have_a_new_message))
            setContentText(messageGetter.message)
            setCategory(NotificationCompat.CATEGORY_MESSAGE)
            setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
            priority = NotificationCompat.PRIORITY_HIGH
            val intent = Intent(OASystem.context, WorkspaceActivity::class.java).apply {
                when (messageGetter.messageType) {
                    1 -> {
                        putExtra("operation_notification", true)
                        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                    }

                    2 -> {
                        putExtra("announcement_notification", true)
                        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                    }
                }
            }
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                OASystem.context,
                0,
                intent,
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
            )
            setContentIntent(pendingIntent)
            setAutoCancel(true)
        }

        manager.notify(OASystem.notificationCount, builder.build())

        OASystem.notificationCount += 1

        wakeUpScreen()
    }

    private fun wakeUpScreen() {
        val powerManager = OASystem.context.getSystemService(Context.POWER_SERVICE) as PowerManager
        val isScreenOn = powerManager.isInteractive

        if (!isScreenOn) {
            // 获取PowerManager.WakeLock对象,后面的参数表示同时传入两个值,最后的是LogCat里用的Tag
            val wakeLock = powerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, "${application.packageName}:bright"
            )
            wakeLock.acquire(1000L) // 点亮屏幕
            wakeLock.release() // 释放
        }

        playNotificationSounds()
    }

    private fun playNotificationSounds() {
        val notificationUrl = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val ringtone = RingtoneManager.getRingtone(OASystem.context, notificationUrl)
        ringtone.play()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun showNotificationInService(messageGetter: MessageGetter) {

        if (messageGetter.message.isNotBlank()) {
            manager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager

            if (isActive) {
                initUnReadCount()
            }

            createNotificationChannel()
            showNotification(messageGetter)
        }
    }

    private fun isIgnoringBatteryOptimizations(): Boolean {
        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        return powerManager.isIgnoringBatteryOptimizations(packageName)
    }

    @SuppressLint("BatteryLife")
    private fun showIgnoreBatteryDialog() {
        if (!isIgnoringBatteryOptimizations()) {

            CustomAlertDialog.Builder().apply {
                setTitle(resources.getString(R.string.alert))
                setMessage(resources.getString(R.string.background_execute_alert_message))
                setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
                    dialog.dismiss()
                }
                setPositiveButtonAndListener(resources.getString(R.string.go_to_open)) { dialog, _ ->

                    val ignoreBatteryIntent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
                    ignoreBatteryIntent.data = Uri.parse("package:$packageName")
                    startActivity(ignoreBatteryIntent)

                    dialog.dismiss()
                }
            }.show()
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun refreshNavigationBride(requestCodeBean: RequestCodeBean) {
        if (requestCodeBean.code == OASystem.REFRESH_NAVIGATION) {
            if (isActive) {
                initUnReadCount()
            }
        }
    }
}