package io.nexilis.alpha.ui.main

import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
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.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.saveable.rememberSaveable
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.components.AttachmentItemList
import io.nexilis.alpha.ui.components.Attachments
import io.nexilis.alpha.ui.components.ContentChat
import io.nexilis.alpha.ui.components.LeftBubbleChat
import io.nexilis.alpha.ui.components.RightBubbleChat
import io.nexilis.alpha.ui.components.getAttachmentItem
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

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun Chat(
    navController: NavHostController,
    contentPadding: PaddingValues,
    pin: String,
    me: Buddy
) {
    var textInput by rememberSaveable(stateSaver = TextFieldValue.Saver) {
        mutableStateOf(TextFieldValue("", TextRange(0, 7)))
    }
    val messageModel: MessageViewModel = hiltViewModel()
    val list by messageModel.getOpposite(pin).observeAsState()
    val state = rememberLazyListState()
    val context = LocalContext.current
    var openAlertDialog by remember { mutableStateOf(false) }
    val attachments = remember { mutableStateListOf<Uri>() }
    Column(
        modifier = Modifier
            .fillMaxSize()
            .consumeWindowInsets(contentPadding)
            .imePadding()
            .imeNestedScroll()
    ) {
        LazyColumn(
            modifier = Modifier
                .weight(1f),
            state = state,
            reverseLayout = true
        ) {
            list?.let { l ->
                items(l) { message ->
                    ListItem(modifier = Modifier.fillMaxWidth(), headlineContent = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = if (message.f_pin == me.f_pin) Arrangement.End else Arrangement.Start
                        ) {
                            if (message.f_pin == me.f_pin) {
                                Spacer(modifier = Modifier.weight(0.1f))
                                RightBubbleChat(
                                    modifier = Modifier.weight(weight = 0.9f, fill = false),
                                    message = message,
                                ) {
                                    ContentChat(
                                        modifier = Modifier.fillMaxWidth(0.7f),
                                        message = message
                                    )
                                }
                            } else {
                                LeftBubbleChat(
                                    modifier = Modifier.weight(weight = 0.9f, fill = false),
                                    message = message
                                ) {
                                    ContentChat(
                                        modifier = Modifier.fillMaxWidth(0.7f),
                                        message = message
                                    )
                                }
                                Spacer(modifier = Modifier.weight(0.1f))
                            }
                        }
                    }, colors = ListItemDefaults.colors(containerColor = Color.Transparent))
                }
            }
        }
        TextField(
            modifier = Modifier
                .fillMaxWidth()
                .graphicsLayer {
                    shape = CircleShape
                    clip = true
                }
                .padding(4.dp),
            value = textInput,
            onValueChange = { textInput = it },
            label = null,
            placeholder = {
                Text(text = "Typing here...", color = MaterialTheme.colorScheme.onSurface)
            },
            leadingIcon = {
                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.surfaceContainer),
                    onAttachment = { list ->
                        attachments.addAll(list)
                        val items = list.map {
                            context.getAttachmentItem(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 (textInput.text.trim().isEmpty()) {
                            return@IconButton
                        }
                        me.let {
                            messageModel.send(
                                context,
                                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 (attachments.size > 0) attachments[0] else Uri.EMPTY
                                )
                            )
                            textInput = TextFieldValue("")
                        }
                    }) {
                        Icon(
                            imageVector = Icons.AutoMirrored.Filled.Send,
                            contentDescription = "",
                            tint = MaterialTheme.colorScheme.primary
                        )
                    }
                }
            },
            colors = TextFieldDefaults.colors(
                focusedContainerColor = MaterialTheme.colorScheme.surfaceContainer,
                unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainer,
                disabledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
                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 ${attachments.size} documents to ${it.first_name} ${it.last_name}?".trim())
                    },
                    onDismissRequest = {
                        openAlertDialog = false
                    },
                    confirmButton = {
                        TextButton(
                            onClick = {
                                openAlertDialog = false
                                me.let {
                                    attachments.forEach { uri ->
                                        messageModel.send(
                                            context,
                                            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")
                        }
                    }
                )
            }
        }
    }
}

