package app.closer.ui.messages.components

import android.net.Uri
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import androidx.appcompat.widget.AppCompatEditText
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.OnReceiveContentListener
import androidx.core.view.ViewCompat
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.inputmethod.InputConnectionCompat

private val RICH_MIME_TYPES = arrayOf("image/*")

/**
 * A text field that advertises rich-content (image) support to the keyboard, so Gboard's GIF,
 * sticker, and Bitmoji tabs can insert straight into the chat. Compose's value-based text fields
 * don't reliably set the IME content MIME types, so this wraps an AppCompatEditText and uses the
 * canonical AndroidX rich-content APIs — the exact mechanism the keyboard checks before offering
 * image insertion.
 */
@Composable
fun RichContentTextField(
    value: String,
    onValueChange: (String) -> Unit,
    onImageReceived: (Uri) -> Unit,
    modifier: Modifier = Modifier,
    hint: String = "Message…"
) {
    val onValueChangeState = rememberUpdatedState(onValueChange)
    val onImageState = rememberUpdatedState(onImageReceived)
    val textColor = MaterialTheme.colorScheme.onSurface.toArgb()
    val hintColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.45f).toArgb()

    AndroidView(
        modifier = modifier,
        factory = { ctx ->
            object : AppCompatEditText(ctx) {
                override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
                    val ic = super.onCreateInputConnection(outAttrs) ?: return null
                    // Tell the IME this field accepts images (GIF / sticker / Bitmoji).
                    EditorInfoCompat.setContentMimeTypes(outAttrs, RICH_MIME_TYPES)
                    return InputConnectionCompat.createWrapper(this, ic, outAttrs)
                }
            }.apply {
                background = null
                maxLines = 4
                setHint(hint)
                inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE

                addTextChangedListener(object : TextWatcher {
                    override fun beforeTextChanged(s: CharSequence?, a: Int, b: Int, c: Int) {}
                    override fun onTextChanged(s: CharSequence?, a: Int, b: Int, c: Int) {}
                    override fun afterTextChanged(s: Editable?) {
                        onValueChangeState.value(s?.toString().orEmpty())
                    }
                })

                val listener = OnReceiveContentListener { _, payload ->
                    val split = payload.partition { item -> item.uri != null }
                    split.first?.clip?.let { clip ->
                        for (i in 0 until clip.itemCount) {
                            clip.getItemAt(i)?.uri?.let { uri -> onImageState.value(uri) }
                        }
                    }
                    split.second
                }
                ViewCompat.setOnReceiveContentListener(this, RICH_MIME_TYPES, listener)
            }
        },
        update = { editText ->
            // Sync external value changes (e.g. cleared after send) without disturbing typing.
            if (editText.text?.toString() != value) {
                editText.setText(value)
                editText.setSelection(value.length)
            }
            editText.setTextColor(textColor)
            editText.setHintTextColor(hintColor)
        }
    )
}
