package com.hmg.hmgDr.Service

import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.graphics.PixelFormat
import android.graphics.Point
import android.os.Build
import android.os.CountDownTimer
import android.util.Log
import android.view.*
import androidx.core.view.GestureDetectorCompat
import com.hmg.hmgDr.R
import com.hmg.hmgDr.util.ViewsUtil

abstract class BaseMovingFloatingWidget : Service() {

    val szWindow = Point()
    lateinit var windowManagerParams: WindowManager.LayoutParams
    var mWindowManager: WindowManager? = null
    var floatingWidgetView: View? = null
    lateinit var floatingViewContainer: View

    lateinit var mDetector: GestureDetectorCompat

    private var xInitCord = 0
    private var yInitCord: Int = 0
    private var xInitMargin: Int = 0
    private var yInitMargin: Int = 0

    /*  Add Floating Widget View to Window Manager  */
    open fun addFloatingWidgetView() {
        mWindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager

        //Init LayoutInflater
        val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
        //Inflate the removing view layout we created
        floatingWidgetView = inflater.inflate(R.layout.activity_video_call, null)

        //Add the view to the window.
        windowManagerParams =
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT
                )
            } else {
                WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT
                )
            }

        //Specify the view position
        windowManagerParams.gravity = Gravity.TOP or Gravity.START
    }

    @SuppressLint("ClickableViewAccessibility")
    val dragListener: View.OnTouchListener = View.OnTouchListener { _, event ->
        mDetector.onTouchEvent(event)

        //Get Floating widget view params
        val layoutParams: WindowManager.LayoutParams =
            floatingWidgetView!!.layoutParams as WindowManager.LayoutParams
        //get the touch location coordinates
        val x_cord = event.rawX.toInt()
        val y_cord = event.rawY.toInt()
        val x_cord_Destination: Int
        var y_cord_Destination: Int

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                xInitCord = x_cord
                yInitCord = y_cord

                //remember the initial position.
                xInitMargin = layoutParams.x
                yInitMargin = layoutParams.y
            }
            MotionEvent.ACTION_UP -> {
                //Get the difference between initial coordinate and current coordinate
                val x_diff: Int = x_cord - xInitCord
                val y_diff: Int = y_cord - yInitCord

                y_cord_Destination = yInitMargin + y_diff
                val barHeight: Int = ViewsUtil.getStatusBarHeight(applicationContext)
                if (y_cord_Destination < 0) {
                    y_cord_Destination = 0
//                    y_cord_Destination =
//                            -(szWindow.y - (videoCallContainer.height /*+ barHeight*/))
//                    y_cord_Destination = -(szWindow.y / 2)
                } else if (y_cord_Destination + (floatingViewContainer.height + barHeight) > szWindow.y) {
                    y_cord_Destination = szWindow.y - (floatingViewContainer.height + barHeight)
//                    y_cord_Destination = (szWindow.y / 2)
                }
                layoutParams.y = y_cord_Destination

                //reset position if user drags the floating view
                resetPosition(x_cord)
            }
            MotionEvent.ACTION_MOVE -> {
                val x_diff_move: Int = x_cord - xInitCord
                val y_diff_move: Int = y_cord - yInitCord
                x_cord_Destination = xInitMargin + x_diff_move
                y_cord_Destination = yInitMargin + y_diff_move

                layoutParams.x = x_cord_Destination
                layoutParams.y = y_cord_Destination

                //Update the layout with new X & Y coordinate
                mWindowManager?.updateViewLayout(floatingWidgetView, layoutParams)
            }
        }
        true
    }

    /**
     * OnTouch actions
     */
    class MyGestureListener(
        val onTabCall: () -> Unit,
        val miniCircleDoubleTap: () -> Unit
    ) : GestureDetector.SimpleOnGestureListener() {

        override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
//            onTabCall()
            return true
        }

//        override fun onDoubleTap(e: MotionEvent?): Boolean {
//            miniCircleDoubleTap()
//            return super.onDoubleTap(e)
//        }

    }

    /*  Reset position of Floating Widget view on dragging  */
    fun resetPosition(x_cord_now: Int) {
        if (x_cord_now <= szWindow.x / 2) {
            moveToLeft(x_cord_now)
        } else {
            moveToRight(x_cord_now)
        }
    }

    /*  Method to move the Floating widget view to Left  */
    private fun moveToLeft(current_x_cord: Int) {

        val mParams: WindowManager.LayoutParams =
            floatingWidgetView!!.layoutParams as WindowManager.LayoutParams

        mParams.x =
            (szWindow.x - current_x_cord * current_x_cord - floatingViewContainer.width).toInt()

        try {
            mWindowManager?.updateViewLayout(floatingWidgetView, mParams)
        } catch (e: Exception) {
            Log.e("windowManagerUpdate", "${e.localizedMessage}.")
        }
        val x = szWindow.x - current_x_cord
        object : CountDownTimer(500, 5) {
            //get params of Floating Widget view
            val mParams: WindowManager.LayoutParams =
                floatingWidgetView!!.layoutParams as WindowManager.LayoutParams

            override fun onTick(t: Long) {
                val step = (500 - t) / 5
                //   mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt()
                mParams.x =
                    (szWindow.x - current_x_cord * current_x_cord * step - floatingViewContainer.width).toInt()

                try {
                    mWindowManager?.updateViewLayout(floatingWidgetView, mParams)
                } catch (e: Exception) {
                    Log.e("windowManagerUpdate", "${e.localizedMessage}.")
                }
            }

            override fun onFinish() {
                mParams.x = -(szWindow.x - floatingViewContainer.width)

                try {
                    mWindowManager?.updateViewLayout(floatingWidgetView, mParams)
                } catch (e: Exception) {
                    Log.e("windowManagerUpdate", "${e.localizedMessage}.")
                }
            }
        }.start()
    }

    /*  Method to move the Floating widget view to Right  */
    private fun moveToRight(current_x_cord: Int) {
        object : CountDownTimer(500, 5) {
            //get params of Floating Widget view
            val mParams: WindowManager.LayoutParams =
                floatingWidgetView!!.layoutParams as WindowManager.LayoutParams

            override fun onTick(t: Long) {
                val step = (500 - t) / 5
                mParams.x =
                    (szWindow.x + current_x_cord * current_x_cord * step - floatingViewContainer.width).toInt()

                try {
                    mWindowManager?.updateViewLayout(floatingWidgetView, mParams)
                } catch (e: Exception) {
                    Log.e("windowManagerUpdate", "${e.localizedMessage}.")
                }

            }

            override fun onFinish() {
                mParams.x = szWindow.x - floatingViewContainer.width

                mWindowManager?.updateViewLayout(floatingWidgetView, mParams)
            }
        }.start()
    }

    /***
     * Utils
     */

    fun getWindowManagerDefaultDisplay() {
        val w = mWindowManager!!.defaultDisplay.width
        val h = mWindowManager!!.defaultDisplay.height
        szWindow[w] = h
    }
}