package com.pan_american.android.base

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.CountDownTimer
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.DatePicker
import android.widget.PopupWindow
import android.widget.TextView
import android.widget.TimePicker
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.pan_american.android.OASystem
import com.pan_american.android.R
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import java.util.Calendar

abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {

    private lateinit var _binding: T
    protected val binding get() = _binding

    lateinit var popupWindow: PopupWindow

    private lateinit var selectorPopView: View

    //筛选列表组件
    lateinit var selector: RecyclerView

    lateinit var selectorContainer: SmartRefreshLayout

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

        val callBack = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                back()
            }
        }

        this.onBackPressedDispatcher.addCallback(this, callBack)

        _binding = getViewBinding()

        window.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN or
                    WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN
        )

        setContentView(_binding.root)

        OASystem.needRefresh = false

        disableRotateScreen()
    }

    override fun onResume() {
        super.onResume()

        //更新context，确保该参数永远是当前界面最新的context参数
        OASystem.context = binding.root.context
    }

    //针对底部存在导航栏的设备进行界面适配(解决控件与底部导航栏重叠的问题)
    fun screenAdaptation(binding: ViewBinding) {
        ViewCompat.setOnApplyWindowInsetsListener(
            binding.root
        ) { v, insets ->
            val systemWindow =
                insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
            v.setPadding(0, 0, 0, systemWindow.bottom)
            v.background = binding.root.background
            insets
        }
    }

    @SuppressLint("SourceLockedOrientationActivity")
    private fun disableRotateScreen() {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
    }

    protected abstract fun getViewBinding(): T

    open fun initTitle() {}

    open fun initViews() {}

    open fun initEvents() {}

    fun back() {

        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)

        object : CountDownTimer(100, 100) {
            override fun onTick(p0: Long) {

            }

            override fun onFinish() {
                if (supportFragmentManager.backStackEntryCount <= 1) {
                    finish()
                } else {
                    supportFragmentManager.popBackStack()
                }
            }
        }.start()
    }

    fun showMessage(str: String) {
        Toast.makeText(OASystem.context, str, Toast.LENGTH_SHORT).show()
    }

    /**
     * 弹出popWindow
     */
    fun showPopupWindow(block: () -> Unit) {

        //避免出现弹出PopupWindow时界面透明的问题
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)

        //点击隐藏软键盘
        val inputMethodManager =
            this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        if (inputMethodManager.isActive) {
            inputMethodManager.hideSoftInputFromWindow(this.window.decorView.windowToken, 0)
        }

        popupWindow.apply {
            //设置背景黑暗度
            val layoutParams: WindowManager.LayoutParams = window.attributes
            layoutParams.alpha = 0.4f
            window.attributes = layoutParams

            //手势提示条适配
            isClippingEnabled = false
            //设置动画效果
            animationStyle = R.style.AnimationBottomPopup
            //设置聚焦，点击外部可以取消
            isOutsideTouchable = true
            isFocusable = true

            setOnDismissListener {
                val layoutParamsDismiss = window.attributes
                layoutParamsDismiss.alpha = 1f
                window.attributes = layoutParamsDismiss
            }
        }

        block()
    }

    /**
     * 弹出底部selector
     */
    fun showSelector(block: () -> Unit) {
        selectorPopView = View.inflate(this, R.layout.popup_smart_refresh_selector, null)
        popupWindow = PopupWindow(
            selectorPopView,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        showPopupWindow {

            selector = selectorPopView.findViewById(R.id.selector_list)
            selectorContainer = selectorPopView.findViewById(R.id.selector_refresh_container)

            selectorContainer.setEnableRefresh(false)
            selectorContainer.setEnableLoadMore(false)

            val layoutManager = LinearLayoutManager(this)
            selector.layoutManager = layoutManager

            block()

            popupWindow.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0)
        }
    }

    /**
     * 弹出日期选择组件
     */
    fun showDatePicker(text: String, textView: TextView, block: () -> Unit = {}) {
        val calendar = Calendar.getInstance()
        val popView = View.inflate(OASystem.context, R.layout.popup_date_selector, null)
        popupWindow = PopupWindow(
            popView,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        showPopupWindow {

            val title = popView.findViewById<TextView>(R.id.date_selector_name)
            val datePicker = popView.findViewById<DatePicker>(R.id.date_selector)
            val commit = popView.findViewById<TextView>(R.id.commit)

            var date = String.format(
                resources.getString(R.string.date_format), calendar.get(
                    Calendar.YEAR
                ), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH)
            )

            title.text = text

            datePicker.init(
                calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(
                    Calendar.DAY_OF_MONTH
                )
            ) { _, year, month, day ->
                date =
                    String.format(resources.getString(R.string.date_format), year, month + 1, day)
            }

            commit.setOnClickListener {
                textView.text = date
                popupWindow.dismiss()
                block()
            }

            popupWindow.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0)
        }
    }

    /**
     * 弹出时间选择组件
     */
    fun showTimePicker(text: String, textView: TextView, block: () -> Unit = {}) {
        val popView = View.inflate(OASystem.context, R.layout.popup_time_selector, null)
        popupWindow = PopupWindow(
            popView,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        showPopupWindow {

            val title = popView.findViewById<TextView>(R.id.time_selector_name)
            val timePicker = popView.findViewById<TimePicker>(R.id.time_selector)
            val commit = popView.findViewById<TextView>(R.id.commit)

            var timeHour = timePicker.hour
            var timeMinute = timePicker.minute

            title.text = text

            timePicker.setOnTimeChangedListener { _, hour, minute ->
                timeHour = hour
                timeMinute = minute
            }

            commit.setOnClickListener {
                textView.text =
                    String.format(resources.getString(R.string.time_format), timeHour, timeMinute)
                popupWindow.dismiss()
                block()
            }

            popupWindow.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0)
        }
    }

    /**
     * 弹出日期 / 时间 选择组件
     */
    fun showDateAndTimePicker(text: String, textView: TextView, block: () -> Unit = {}) {
        val calendar = Calendar.getInstance()
        val popView = View.inflate(OASystem.context, R.layout.popup_time_and_date_selector, null)
        popupWindow = PopupWindow(
            popView,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        showPopupWindow {

            val title = popView.findViewById<TextView>(R.id.date_selector_name)
            val datePicker = popView.findViewById<DatePicker>(R.id.date_selector)
            val timePicker = popView.findViewById<TimePicker>(R.id.time_selector)
            val commit = popView.findViewById<TextView>(R.id.commit)

            var date = String.format(
                resources.getString(R.string.date_format), calendar.get(
                    Calendar.YEAR
                ), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH)
            )

            var timeHour = timePicker.hour
            var timeMinute = timePicker.minute

            title.text = text

            datePicker.init(
                calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(
                    Calendar.DAY_OF_MONTH
                )
            ) { _, year, month, day ->
                date =
                    String.format(resources.getString(R.string.date_format), year, month + 1, day)
            }

            timePicker.setOnTimeChangedListener { _, hour, minute ->
                timeHour = hour
                timeMinute = minute
            }

            commit.setOnClickListener {
                textView.text = String.format(
                    resources.getString(R.string.with_space_format),
                    date,
                    String.format(resources.getString(R.string.time_format), timeHour, timeMinute)
                )
                popupWindow.dismiss()
                block()
            }

            popupWindow.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0)
        }
    }

    /**
     * 错误信息提示
     */
    fun showErrorInfo(stringId: Int) {
        showMessage(
            String.format(
                resources.getString(R.string.network_error),
                resources.getString(stringId)
            )
        )
    }
}