package com.adealink.frame.imkit.utils.keyboard

import android.app.Activity
import android.content.Context
import android.graphics.PixelFormat
import android.os.Build
import android.view.Gravity
import android.view.View
import android.view.View.OnLayoutChangeListener
import android.view.ViewGroup
import android.view.WindowManager
import com.adealink.frame.imkit.model.TAG_IM_KEYBOARD
import com.adealink.frame.log.Log
import kotlin.math.abs

class KeyboardHeightFloatImpl
    (activity: Activity) : KeyboardHeightPresenter, OnLayoutChangeListener {
    private val windowManager: WindowManager
    private val view: View
    private val activity: Activity

    private var keyboardHeightObserver: KeyboardHeightObserver? = null

    init {
        Log.d(TAG_IM_KEYBOARD, "KeyboardHeightFloatImpl: ")
        this.activity = activity
        this.windowManager = activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        this.view = View(activity)
    }

    override fun start() {
        try {
            val parent = view.parent
            view.addOnLayoutChangeListener(this)
            if (parent is ViewGroup) {
                parent.removeView(view)
                windowManager.addView(view, createLayoutParams())
            } else if (parent == null) {
                windowManager.addView(view, createLayoutParams())
            }
        } catch (e: Exception) {
            Log.e(TAG_IM_KEYBOARD, "start", e)
            view.removeOnLayoutChangeListener(this)
        }
    }

    override fun stop() {
        try {
            view.removeOnLayoutChangeListener(this)
            if (view.isAttachedToWindow) {
                windowManager.removeViewImmediate(view)
            }
        } catch (e: Exception) {
            Log.e(TAG_IM_KEYBOARD, "stop" + e.message)
        }
    }

    override fun setKeyboardHeightObserver(observer: KeyboardHeightObserver?) {
        keyboardHeightObserver = observer
    }

    override fun onLayoutChange(
        v: View,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int,
        oldLeft: Int,
        oldTop: Int,
        oldRight: Int,
        oldBottom: Int
    ) {
        val orientation = screenOrientation
        val oldHeight = oldBottom - oldTop
        val height = bottom - top
        if (oldBottom == 0) {
            notifyKeyboardHeightChanged(0, orientation, false)
        } else {
            notifyKeyboardHeightChanged(
                abs((height - oldHeight).toDouble()).toInt(), orientation, bottom < oldBottom
            )
        }
    }

    private val screenOrientation: Int
        get() = activity.resources.configuration.orientation

    private fun notifyKeyboardHeightChanged(height: Int, orientation: Int, isOpen: Boolean) {
        val keyboardHeightObserver = this.keyboardHeightObserver
        keyboardHeightObserver?.onKeyboardHeightChanged(orientation, isOpen, height)
    }

    companion object {
        private fun createLayoutParams(): WindowManager.LayoutParams {
            val params = WindowManager.LayoutParams()
            val type = if (Build.VERSION.SDK_INT < 24) {
                WindowManager.LayoutParams.TYPE_TOAST
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                WindowManager.LayoutParams.TYPE_PHONE
            }
            params.type = type
            params.flags =
                (WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                        or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)

            params.format = PixelFormat.TRANSLUCENT
            params.width = 0
            params.height = ViewGroup.LayoutParams.MATCH_PARENT
            params.gravity = Gravity.START
            return params
        }
    }
}
