package com.dano.test1.utils

import android.content.Context
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.AbsListView
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView
import androidx.core.widget.TextViewCompat
import com.dano.test1.R
import kotlin.math.roundToInt

object ViewUtils {

    /**
     * Sets the text size of a TextView to a percentage of the screen height (in sp).
     * Disables auto-sizing to prevent conflicts.
     */
    fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
        val dm = view.context.resources.displayMetrics
        val sp = (dm.heightPixels * percentOfHeight) / dm.scaledDensity
        TextViewCompat.setAutoSizeTextTypeWithDefaults(view, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
        view.setTextSize(TypedValue.COMPLEX_UNIT_SP, sp)
    }

    /**
     * Sets up a Spinner with a responsive, styled adapter.
     * Font size and row height are derived from screen height to prevent clipping.
     */
    fun <T> setupResponsiveSpinner(context: Context, spinner: Spinner, items: List<T>, selectedItem: T?) {
        val dm = context.resources.displayMetrics

        fun spFromScreenHeight(percent: Float): Float = (dm.heightPixels * percent) / dm.scaledDensity
        fun pxFromSp(sp: Float): Int = (sp * dm.scaledDensity).toInt()

        val textSp    = spFromScreenHeight(0.0275f)
        val textPx    = pxFromSp(textSp)
        val vPadPx    = (textPx * 0.50f).toInt()
        val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt()

        val adapter = object : ArrayAdapter<T>(context, android.R.layout.simple_spinner_item, items) {
            private fun styleRow(tv: TextView, forceHeight: Boolean) {
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSp)
                tv.includeFontPadding = true
                tv.setLineSpacing(0f, 1.2f)
                tv.gravity = (tv.gravity and Gravity.HORIZONTAL_GRAVITY_MASK) or Gravity.CENTER_VERTICAL
                tv.setPadding(tv.paddingLeft, vPadPx, tv.paddingRight, vPadPx)
                tv.minHeight = rowHeight
                tv.isSingleLine = true
                if (forceHeight) {
                    val lp = tv.layoutParams
                    if (lp == null || lp.height <= 0) {
                        tv.layoutParams = AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, rowHeight)
                    } else {
                        lp.height = rowHeight
                    }
                }
            }

            override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
                val v = super.getView(position, convertView, parent) as TextView
                styleRow(v, forceHeight = false)
                return v
            }

            override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
                val v = super.getDropDownView(position, convertView, parent) as TextView
                styleRow(v, forceHeight = true)
                return v
            }
        }

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        spinner.adapter = adapter
        spinner.setPadding(spinner.paddingLeft, vPadPx, spinner.paddingRight, vPadPx)
        spinner.minimumHeight = rowHeight
        spinner.requestLayout()

        selectedItem?.let {
            val index = items.indexOf(it)
            if (index >= 0) spinner.setSelection(index)
        }
    }

    /**
     * Locks an EditText field visually and functionally (e.g. for coach code fields).
     */
    fun lockEditField(field: EditText, dpPadding: Int = 8) {
        field.isFocusable = false
        field.isFocusableInTouchMode = false
        field.isCursorVisible = false
        field.keyListener = null
        field.isLongClickable = false
        field.isClickable = false
        field.setBackgroundResource(R.drawable.bg_field_locked)
        field.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
        field.compoundDrawablePadding = dp(field.context, dpPadding)
        field.alpha = 0.95f
    }

    /**
     * Converts dp to pixels using the given context.
     */
    fun dp(context: Context, value: Int): Int =
        (value * context.resources.displayMetrics.density).roundToInt()
}
