package io.nexilis.alpha.ui.components

import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import io.nexilis.alpha.ui.screen.Screen
import io.nexilis.service.data.entities.Buddy
import io.nexilis.service.data.entities.Message
import io.nexilis.service.data.viewmodels.BuddyViewModel
import io.nexilis.service.data.viewmodels.MessageViewModel
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Composable
fun InputChat(
    modifier: Modifier = Modifier,
    navController: NavHostController,
    pin: String,
    me: Buddy,
    placeHolderText: String = "Typing here...",
    enableAttachment: Boolean = true,
    enableEmpty: Boolean = false,
    popAfterSent: Boolean = false,
    attachments: ArrayList<Uri> = arrayListOf()
) {
    val context = LocalContext.current
    val messageModel: MessageViewModel = hiltViewModel()
    var textInput by rememberSaveable(stateSaver = TextFieldValue.Saver) {
        mutableStateOf(TextFieldValue("", TextRange(0, 7)))
    }
    var openAlertDialog by remember { mutableStateOf(false) }
    val attachmentState = remember { mutableStateListOf<Uri>() }
    attachmentState.addAll(attachments)
    TextField(
        modifier = modifier
            .fillMaxWidth()
            .padding(4.dp)
            .graphicsLayer {
                shape = RoundedCornerShape(16.dp)
                clip = true
            },
        value = textInput,
        onValueChange = { textInput = it },
        label = null,
        placeholder = {
            Text(text = placeHolderText, color = MaterialTheme.colorScheme.onSurface)
        },
        leadingIcon = addAttachment(enableAttachment = enableAttachment) { list ->
            attachmentState.addAll(list)
            val items = list.map {
                context.toAttachmentItem(it)
            }
            if (items.size == 1) {
                val params = AttachmentItemList(items)
                val data = Uri.encode(Json.encodeToString(params))
                navController.navigate(Screen.AttachmentCaption.route + "?data=${data}&pin=${pin}") {
                    launchSingleTop = true
                    restoreState = true
                }
            } else if (items.size > 1) {
                openAlertDialog = true
            }
        },
        trailingIcon = {
            Row {
                IconButton(onClick = {
                    if (pin.trim().isEmpty()) {
                        return@IconButton
                    }
                    if (!enableEmpty && textInput.text.trim().isEmpty()) {
                        return@IconButton
                    }
                    me.let {
                        messageModel.send(
                            context = context,
                            entity = Message(
                                message_id = System.nanoTime().toString(),
                                f_pin = it.f_pin,
                                l_pin = pin,
                                message_scope_id = "3", // 3: chat, 15: sms, 16: email
                                server_date = System.currentTimeMillis(),
                                status = "1",
                                message_text = textInput.text,
                                opposite_pin = pin,
                                f_display_name = "${it.first_name} ${it.last_name}".trim(),
                                message_large_text = "",
                                message_text_plain = "",
                                uri = if (attachmentState.size > 0) attachmentState[0] else Uri.EMPTY
                            )
                        )
                        textInput = TextFieldValue("")
                        if (popAfterSent) navController.popBackStack()
                    }
                }) {
                    Icon(
                        imageVector = Icons.AutoMirrored.Filled.Send,
                        contentDescription = "",
                        tint = MaterialTheme.colorScheme.primary
                    )
                }
            }
        },
        colors = TextFieldDefaults.colors(
            focusedContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
            unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
            disabledContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent,
            errorIndicatorColor = Color.Transparent,
        ),
        keyboardOptions = KeyboardOptions(KeyboardCapitalization.Sentences),
        maxLines = 3
    )
    if (openAlertDialog) {
        val buddyModel: BuddyViewModel = hiltViewModel()
        val buddy by buddyModel.getBuddy(pin).observeAsState()
        buddy?.let {
            AlertDialog(
                text = {
                    Text(text = "Send ${attachmentState.size} documents to ${it.first_name} ${it.last_name}?".trim())
                },
                onDismissRequest = {
                    openAlertDialog = false
                },
                confirmButton = {
                    TextButton(
                        onClick = {
                            openAlertDialog = false
                            me.let {
                                attachmentState.forEach { uri ->
                                    messageModel.send(
                                        context = context,
                                        entity = Message(
                                            message_id = System.nanoTime().toString(),
                                            f_pin = it.f_pin,
                                            l_pin = pin,
                                            message_scope_id = "3", // 3: chat, 15: sms, 16: email
                                            server_date = System.currentTimeMillis(),
                                            status = "1",
                                            message_text = "",
                                            opposite_pin = pin,
                                            f_display_name = "${it.first_name} ${it.last_name}".trim(),
                                            message_large_text = "",
                                            message_text_plain = "",
                                            uri = uri
                                        )
                                    )
                                }
                                textInput = TextFieldValue("")
                            }
                        }
                    ) {
                        Text("Send")
                    }
                },
                dismissButton = {
                    TextButton(
                        onClick = {
                            openAlertDialog = false
                        }
                    ) {
                        Text("Cancel")
                    }
                }
            )
        }
    }
}

private fun addAttachment(
    enableAttachment: Boolean = true,
    onAttachment: (List<Uri>) -> Unit
): (@Composable () -> Unit)? {
    val leadingIcon: (@Composable () -> Unit)? = if (enableAttachment) {
        {
            Attachments(
                modifier = Modifier
                    .height(300.dp)
                    .fillMaxWidth()
                    .padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
                    .graphicsLayer {
                        shape = RoundedCornerShape(16.dp)
                        clip = true
                    }
                    .background(MaterialTheme.colorScheme.surfaceContainerLowest),
                onAttachment = onAttachment
            )
        }
    } else null
    return leadingIcon
}