package com.ray650128.floatingwindow.utils

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.provider.MediaStore
import android.view.Gravity
import android.view.MotionEvent
import android.view.WindowManager
import com.hjq.window.EasyWindow
import com.ray650128.floatingwindow.MyApp
import com.ray650128.floatingwindow.R
import java.io.File

object FloatingWindowHelperUtils {

    private var _isShowing: Boolean = false
    val isShowing: Boolean
        get() = _isShowing

    private var xOffset = PreferenceUtil.xOffset
    private var yOffset = PreferenceUtil.yOffset

    private var windowGravity = GravityType.fromInt(PreferenceUtil.gravity)
    private var windowIcon = IconType.fromInt(PreferenceUtil.icon)

    private val window by lazy {
        EasyWindow<EasyWindow<*>>(MyApp.instance).apply {
            setContentView(R.layout.window_hint)
            setGravity(when (windowGravity) {
                GravityType.TOP_LEFT -> Gravity.TOP or Gravity.START
                GravityType.BOTTOM_LEFT -> Gravity.BOTTOM or Gravity.START
                GravityType.TOP_RIGHT -> Gravity.TOP or Gravity.END
                GravityType.BOTTOM_RIGHT -> Gravity.BOTTOM or Gravity.END
            })
            setXOffset(xOffset)
            setYOffset(yOffset)
            if (windowIcon == IconType.CUSTOM) {
                if (PreferenceUtil.iconPath.isNullOrEmpty()) {
                    setImageDrawable(android.R.id.icon, windowIcon.value)
                } else {
                    val iconPath = PreferenceUtil.iconPath
                    if (iconPath?.contains("/data/user/0/com.ray650128.floatingwindow/cache/") == true) {
                        val bitmap = BitmapFactory.decodeFile(iconPath)
                        val drawable = BitmapDrawable(MyApp.appContext.resources, bitmap)
                        setImageDrawable(android.R.id.icon, drawable)
                    } else {
                        val uri = Uri.parse(PreferenceUtil.iconPath)
                        val bitmap = BitmapFactory.decodeStream(MyApp.appContext.contentResolver.openInputStream(uri))
                        val drawable = BitmapDrawable(MyApp.appContext.resources, bitmap)
                        setImageDrawable(android.R.id.icon, drawable)
                    }
                }
            } else {
                setImageDrawable(android.R.id.icon, windowIcon.value)
            }
            setOnTouchListener { window, view, event ->
                var touch = false
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        window.setWindowFlags(
                            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        )
                        window.update()
                        touch = true
                    }

                    MotionEvent.ACTION_OUTSIDE -> {
                        window.setWindowFlags(
                            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        )
                        window.update()
                        touch = false
                    }

                    else -> {}
                }
                touch
            }
        }
    }

    fun show() {
        _isShowing = true
        window.show()
    }

    fun hide() {
        _isShowing = false
        window.cancel()
    }

    fun setXOffset(value: Int) {
        window.setXOffset(value)
        window.update()
    }

    fun setYOffset(value: Int) {
        window.setYOffset(value)
        window.update()
    }

    fun setGravity(value: GravityType) {
        when (value) {
            GravityType.TOP_LEFT -> {
                window.setGravity(Gravity.TOP or Gravity.START)
            }
            GravityType.BOTTOM_LEFT -> {
                window.setGravity(Gravity.BOTTOM or Gravity.START)
            }
            GravityType.TOP_RIGHT -> {
                window.setGravity(Gravity.TOP or Gravity.END)
            }
            GravityType.BOTTOM_RIGHT -> {
                window.setGravity(Gravity.BOTTOM or Gravity.END)
            }
        }
        window.update()
    }

    fun setIcon(value: IconType, inputUri: Uri? = null) {
        if (value == IconType.CUSTOM) {
            if (inputUri == null) {
                window.setImageDrawable(android.R.id.icon, value.value)
            } else {
                val bitmap = BitmapFactory.decodeStream(MyApp.appContext.contentResolver.openInputStream(inputUri))
                val drawable = BitmapDrawable(MyApp.appContext.resources, bitmap)
                window.setImageDrawable(android.R.id.icon, drawable)
            }
        } else {
            window.setImageDrawable(android.R.id.icon, value.value)
        }
        window.update()
    }

    fun setIcon(value: IconType, inputUri: String? = null) {
        if (value == IconType.CUSTOM) {
            if (inputUri == null) {
                window.setImageDrawable(android.R.id.icon, value.value)
            } else {
                val bitmap = BitmapFactory.decodeFile(inputUri)
                val drawable = BitmapDrawable(MyApp.appContext.resources, bitmap)
                window.setImageDrawable(android.R.id.icon, drawable)
            }
        } else {
            window.setImageDrawable(android.R.id.icon, value.value)
        }
        window.update()
    }

    enum class GravityType(val type: Int) {
        TOP_LEFT(0),
        BOTTOM_LEFT(1),
        TOP_RIGHT(2),
        BOTTOM_RIGHT(3);

        companion object {
            fun fromInt(value: Int) = GravityType.values().first { it.type == value }
        }
    }

    enum class IconType(val value: Int, val index: Int) {
        CHICKEN(R.drawable.ic_chicken, 0),
        PEPE(R.drawable.ic_pepe, 1),
        WEED(R.drawable.ic_weed, 2),
        RUSHIA(R.drawable.ic_uruha_rushia, 3),
        ISSHIKI_IROHA(R.drawable.ic_isshiki_iroha, 4),
        AYAME(R.drawable.ic_nakiri_ayame, 5),
        AQUA(R.drawable.ic_minato_aqua, 6),
        GURA(R.drawable.ic_gura, 7),
        RUSHIA2(R.drawable.ic_uruha_rushia2, 8),
        RUSHIA3(R.drawable.ic_uruha_rushia3, 9),
        HOSHIMACHI_SUISEI(R.drawable.ic_hoshimachii_suisei, 10),
        CUSTOM(R.mipmap.ic_launcher, 11);

        companion object {
            fun fromInt(value: Int) = IconType.values().first { it.value == value }

            fun fromIndex(value: Int) = IconType.values().first { it.index == value }

            fun getIndex(value: Int) = IconType.values().indexOf(
                IconType.values().first { it.value == value }
            )
        }
    }
}