package com.aiosman.ravenow.ui.chat

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.aiosman.ravenow.LocalAppTheme
import com.aiosman.ravenow.AppState
import com.aiosman.ravenow.LocalNavController
import com.aiosman.ravenow.R
import com.aiosman.ravenow.entity.ChatItem
import com.aiosman.ravenow.exp.formatChatTime
import com.aiosman.ravenow.ui.NavigationRoute
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
import com.aiosman.ravenow.ui.composables.DropdownMenu
import com.aiosman.ravenow.ui.composables.MenuItem
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import com.aiosman.ravenow.utils.NetworkUtils
import io.openim.android.sdk.enums.MessageType
import kotlinx.coroutines.launch
import java.util.UUID


@Composable
fun ChatScreen(userId: String) {
    val navController = LocalNavController.current
    val context = LocalNavController.current.context
    val AppColors = LocalAppTheme.current
    var goToNewCount by remember { mutableStateOf(0) }
    val viewModel = viewModel<ChatViewModel>(
        key = "ChatViewModel_$userId",
        factory = object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return ChatViewModel(userId) as T
            }
        }
    )
    var isLoadingMore by remember { mutableStateOf(false) } // Add a state for loading
    LaunchedEffect(Unit) {
        viewModel.init(context = context)
    }
    DisposableEffect(Unit) {
        onDispose {
            viewModel.UnRegistListener()
            viewModel.clearUnRead()
        }
    }
    val listState = rememberLazyListState()
    val coroutineScope = rememberCoroutineScope()
    val navigationBarHeight = with(LocalDensity.current) {
        WindowInsets.navigationBars.getBottom(this).toDp()
    }
    var inBottom by remember { mutableStateOf(true) }
    // 监听滚动状态，触发加载更多
    LaunchedEffect(listState) {
        snapshotFlow { listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index }
            .collect { index ->
                Log.d("ChatScreen", "lastVisibleItemIndex: ${index}")
                if (index == listState.layoutInfo.totalItemsCount - 1) {
                    coroutineScope.launch {
                        viewModel.onLoadMore(context)
                    }
                }

            }
    }
    // 监听滚动状态，触发滚动到底部
    LaunchedEffect(listState) {
        snapshotFlow { listState.layoutInfo.visibleItemsInfo.firstOrNull()?.index }
            .collect { index ->
                inBottom = index == 0
                if (index == 0) {
                    goToNewCount = 0
                }
            }
    }


    // 监听是否需要滚动到最新消息
    LaunchedEffect(viewModel.goToNew) {
        if (viewModel.goToNew) {
            if (inBottom) {
                listState.scrollToItem(0)
            } else {
                goToNewCount++
            }
            viewModel.goToNew = false
        }
    }


    Box(
        modifier = Modifier
            .fillMaxSize()
    ) {
        // 背景图层
        val bgUrl = AppState.chatBackgroundUrl
        if (bgUrl != null) {
            CustomAsyncImage(
                imageUrl = bgUrl,
                modifier = Modifier.fillMaxSize(),
                contentDescription = "chat_background",
                contentScale = ContentScale.Crop
            )
        } else {
            // 无背景时使用主题背景色
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(AppColors.background)
            )
        }

        Scaffold(
            modifier = Modifier
                .fillMaxSize(),
            backgroundColor = Color.Transparent,
        topBar = {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(Color.Transparent)
            ) {
                StatusBarSpacer()
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 16.dp, horizontal = 16.dp),
                    horizontalArrangement = Arrangement.Start,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Image(
                        painter = painterResource(R.drawable.rider_pro_back_icon),
                        modifier = Modifier
                            .size(24.dp)
                            .noRippleClickable {
                                navController.navigateUp()
                            },
                        contentDescription = null,
                        colorFilter = ColorFilter.tint(
                            AppColors.text)
                    )
                    Spacer(modifier = Modifier.width(16.dp))
                    CustomAsyncImage(
                        imageUrl = viewModel.userProfile?.avatar ?: "",
                        modifier = Modifier
                            .size(32.dp)
                            .clip(RoundedCornerShape(32.dp)),
                        contentDescription = "avatar"
                    )
                    Spacer(modifier = Modifier.width(8.dp))
                    Text(
                        text = viewModel.userProfile?.nickName ?: "",
                        modifier = Modifier.weight(1f)
                        ,
                        maxLines = 1,
                        overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
                        style = TextStyle(
                            color = AppColors.text,
                            fontSize = 18.sp,
                            fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
                        )
                    )
                    Spacer(modifier = Modifier.width(8.dp))
                    Box {
                        Image(
                            painter = painterResource(R.drawable.rider_pro_more_horizon),
                            modifier = Modifier
                                .size(28.dp)
                                .noRippleClickable {
                                    navController.navigate(NavigationRoute.ChatSetting.route)
                                },
                            contentDescription = null,
                            colorFilter = ColorFilter.tint(
                                AppColors.text)
                        )
                    }
                }
            }
        },
        bottomBar = {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .imePadding()
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(1.dp)

                )
                Spacer(modifier = Modifier.height(8.dp))
                ChatInput(
                    onSendImage = {
                        it?.let {
                            if (NetworkUtils.isNetworkAvailable(context)) {
                                viewModel.sendImageMessage(it, context)
                            } else {
                                android.widget.Toast.makeText(context, "网络连接异常，请检查网络设置", android.widget.Toast.LENGTH_SHORT).show()
                            }
                        }
                    },
                ) {
                    viewModel.sendMessage(it, context)
                }
            }
        }
        ) { paddingValues ->
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Transparent)
                .padding(paddingValues)
        ) {
            LazyColumn(
                state = listState,
                modifier = Modifier.fillMaxSize(),
                reverseLayout = true,
                verticalArrangement = Arrangement.Top
            ) {
                val chatList = groupMessagesByTime(viewModel.getDisplayChatList(), viewModel)
                items(chatList.size, key = { index -> chatList[index].msgId + UUID.randomUUID().toString()}) { index ->
                    val item = chatList[index]
                    if (item.showTimeDivider) {
                        val calendar = java.util.Calendar.getInstance()
                        calendar.timeInMillis = item.timestamp
                        Text(
                            text = calendar.time.formatChatTime(context), // Format the timestamp
                            style = TextStyle(
                                color = AppColors.secondaryText,
                                fontSize = 14.sp,
                                textAlign = TextAlign.Center
                            ),
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(vertical = 8.dp)
                        )
                    }

                    ChatItem(item = item, viewModel.myProfile?.trtcUserId!!)


                }
//            item {
//                Spacer(modifier = Modifier.height(72.dp))
//            }
            }
            if (goToNewCount > 0) {
                Box(
                    modifier = Modifier
                        .align(Alignment.BottomEnd)
                        .padding(bottom = 16.dp, end = 16.dp)
                        .shadow(4.dp, shape = RoundedCornerShape(16.dp))
                        .clip(RoundedCornerShape(16.dp))
                        .background(AppColors.background)
                        .padding(8.dp)
                        .noRippleClickable {
                            coroutineScope.launch {
                                listState.scrollToItem(0)
                            }
                        },

                    ) {
                    Text(
                        text = "${goToNewCount} New Message",
                        style = TextStyle(
                            color = AppColors.text,
                            fontSize = 16.sp,
                        ),
                    )
                }
            }
        }


    }
    }
}

@Composable
fun ChatSelfItem(item: ChatItem) {

    val context = LocalContext.current
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {
        Row(
            horizontalArrangement = Arrangement.End,
            modifier = Modifier.fillMaxWidth()
        ) {
            Column(
                horizontalAlignment = androidx.compose.ui.Alignment.End,
            ) {
                /* Text(
                     text = item.nickname,
                     style = TextStyle(
                         color = Color.Gray,
                         fontSize = 12.sp,
                     ),
                     modifier = Modifier.padding(bottom = 2.dp)
                 )
                 */
                Box(
                    modifier = Modifier
                        .widthIn(
                            min = 20.dp,
                            max = (if (item.messageType == MessageType.TEXT) 250.dp else 150.dp)
                        )
                        .clip(RoundedCornerShape(20.dp))
                        .background(Color(0xFF6246FF))
                        .padding(
                            vertical = (if (item.messageType == MessageType.TEXT) 8.dp else 0.dp),
                            horizontal = (if (item.messageType == MessageType.TEXT) 16.dp else 0.dp)
                        )

                ) {
                    when (item.messageType) {
                        MessageType.TEXT -> {
                            Text(
                                text = item.message,
                                style = TextStyle(
                                    color = Color.White,
                                    fontSize = 14.sp,
                                ),
                                textAlign = TextAlign.Start
                            )
                        }

                        MessageType.PICTURE -> {
                            CustomAsyncImage(
                                imageUrl = item.imageList[1].url,
                                modifier = Modifier.fillMaxSize(),
                                contentDescription = "image"
                            )
                        }

                        else -> {
                            Text(
                                text = "不支持的消息类型",
                                style = TextStyle(
                                    color = Color.White,
                                    fontSize = 14.sp,
                                )
                            )
                        }
                    }
                }
            }
            /*Spacer(modifier = Modifier.width(12.dp))
            Box(
                modifier = Modifier
                    .size(24.dp)
                    .clip(RoundedCornerShape(24.dp))
            ) {
                CustomAsyncImage(
                    imageUrl = item.avatar,
                    modifier = Modifier.fillMaxSize(),
                    contentDescription = "avatar"
                )
            }*/
        }
    }
}

@Composable
fun ChatOtherItem(item: ChatItem) {
    val AppColors = LocalAppTheme.current

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {
        Row(
            horizontalArrangement = Arrangement.Start,
            modifier = Modifier.fillMaxWidth()
        ) {
            Box(
                modifier = Modifier
                    .size(40.dp)
                    .clip(RoundedCornerShape(40.dp))
            ) {
                CustomAsyncImage(
                    imageUrl = item.avatar,
                    modifier = Modifier.fillMaxSize(),
                    contentDescription = "avatar"
                )
            }
            Spacer(modifier = Modifier.width(12.dp))
            Column {
                Box(
                    modifier = Modifier
                        .widthIn(
                            min = 20.dp,
                            max = (if (item.messageType == MessageType.TEXT) 250.dp else 150.dp)
                        )
                        .clip(RoundedCornerShape(8.dp))
                        .background(AppColors.background)
                        .padding(
                            vertical = (if (item.messageType == MessageType.TEXT) 8.dp else 0.dp),
                            horizontal = (if (item.messageType == MessageType.TEXT) 16.dp else 0.dp)
                        )
                        .padding(bottom = (if (item.messageType == MessageType.TEXT) 3.dp else 0.dp))
                ) {
                    when (item.messageType) {
                        MessageType.TEXT -> {
                            Text(
                                text = item.message,
                                style = TextStyle(
                                    color = AppColors.text,
                                    fontSize = 16.sp,
                                ),
                                textAlign = TextAlign.Start
                            )
                        }

                        MessageType.PICTURE -> {
                            CustomAsyncImage(
                                imageUrl = item.imageList[1].url,
                                modifier = Modifier.fillMaxSize(),
                                contentDescription = "image"
                            )
                        }

                        else -> {
                            Text(
                                text = "Unsupported message type",
                                style = TextStyle(
                                    color = AppColors.text,
                                    fontSize = 16.sp,
                                )
                            )
                        }
                    }
                }

            }
        }

    }
}

@Composable
fun ChatItem(item: ChatItem, currentUserId: String) {
    val isCurrentUser = item.userId == currentUserId
    if (isCurrentUser) {
        ChatSelfItem(item)
    } else {
        ChatOtherItem(item)
    }
}

@Composable
fun ChatInput(
    onSendImage: (Uri?) -> Unit = {},
    onSend: (String) -> Unit = {},
) {
    val context = LocalContext.current
    val navigationBarHeight = with(LocalDensity.current) {
        WindowInsets.navigationBars.getBottom(this).toDp()
    }
    var keyboardController by remember { mutableStateOf<SoftwareKeyboardController?>(null) }
    var isKeyboardOpen by remember { mutableStateOf(false) }
    var text by remember { mutableStateOf("") }
    val appColors = LocalAppTheme.current
    val inputBarHeight by animateDpAsState(
        targetValue = if (isKeyboardOpen) 8.dp else (navigationBarHeight + 8.dp),
        animationSpec = tween(
            durationMillis = 300,
            easing = androidx.compose.animation.core.LinearEasing
        ), label = ""
    )

    // 在 isKeyboardOpen 变化时立即更新 inputBarHeight 的动画目标值
    LaunchedEffect(isKeyboardOpen) {
        inputBarHeight // 触发 inputBarHeight 的重组
    }
    val focusManager = LocalFocusManager.current
    val windowInsets = WindowInsets.ime
    val density = LocalDensity.current
    val softwareKeyboardController = LocalSoftwareKeyboardController.current
    val currentDensity by rememberUpdatedState(density)

    LaunchedEffect(windowInsets.getBottom(currentDensity)) {
        if (windowInsets.getBottom(currentDensity) <= 0) {
            focusManager.clearFocus()
        }
    }

    val imagePickUpLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) {
        if (it.resultCode == Activity.RESULT_OK) {
            val uri = it.data?.data
            onSendImage(uri)
        }
    }
    Box( modifier = Modifier
        .fillMaxWidth()
        .padding(start = 16.dp, end = 16.dp, bottom = 45.dp),){

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clip(RoundedCornerShape(20.dp))
                .background(appColors.decentBackground)
                .padding(start = 16.dp, end = 8.dp, top = 2.dp, bottom = 2.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
            ) {
                BasicTextField(
                    value = text,
                    onValueChange = {
                        text = it
                    },
                    textStyle = TextStyle(
                        color = appColors.text,
                        fontSize = 16.sp
                    ),
                    cursorBrush = SolidColor(appColors.text),
                    singleLine = true,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 8.dp)
                        .onFocusChanged { focusState ->
                            isKeyboardOpen = focusState.isFocused
                        }
                        .pointerInput(Unit) {
                            awaitPointerEventScope {
                                keyboardController = softwareKeyboardController
                                awaitFirstDown().also {
                                    keyboardController?.show()
                                }
                            }
                        },
                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
                    keyboardActions = KeyboardActions(
                        onDone = {
                            keyboardController?.hide()
                        }
                    )
                )
            }
            Spacer(modifier = Modifier.width(8.dp))
            Image(
                painter = painterResource(R.mipmap.rider_pro_im_image),
                contentDescription = "Image",
                modifier = Modifier
                    .size(30.dp)
                    .noRippleClickable {
                        if (NetworkUtils.isNetworkAvailable(context)) {
                            imagePickUpLauncher.launch(
                                Intent.createChooser(
                                    Intent(Intent.ACTION_GET_CONTENT).apply {
                                        type = "image/*"
                                    },
                                    "Select Image"
                                )
                            )
                        } else {
                            android.widget.Toast.makeText(context, "网络连接异常，请检查网络设置", android.widget.Toast.LENGTH_SHORT).show()
                        }
                    },
            )

            Spacer(modifier = Modifier.width(8.dp))
            Crossfade(
                targetState = text.isNotEmpty(), animationSpec = tween(500),
                label = ""
            ) { isNotEmpty ->
                val alpha by animateFloatAsState(
                    targetValue = if (isNotEmpty) 1f else 0.5f,
                    animationSpec = tween(300)
                )
                            Image(
                painter = painterResource(R.mipmap.rider_pro_im_send),
                modifier = Modifier
                    .size(24.dp)
                    .alpha(alpha)
                    .noRippleClickable {
                        if (text.isNotEmpty()) {
                            if (NetworkUtils.isNetworkAvailable(context)) {
                                onSend(text)
                                text = ""
                            } else {
                                android.widget.Toast.makeText(context, "网络连接异常，请检查网络设置", android.widget.Toast.LENGTH_SHORT).show()
                            }
                        }
                    },
                contentDescription = null,
            )
            }
        }
    }
}

fun groupMessagesByTime(chatList: List<ChatItem>, viewModel: ChatViewModel): List<ChatItem> {
    for (i in chatList.indices) { // Iterate in normal order
        if (i == 0) {
            viewModel.showTimestampMap[chatList[i].msgId] = false
            chatList[i].showTimeDivider = false
            continue
        }
        val currentMessage = chatList[i]
        val timeDiff = currentMessage.timestamp - chatList[i - 1].timestamp
        // 时间间隔大于 3 分钟，显示时间戳
        if (-timeDiff > 30 * 60 * 1000) {
            viewModel.showTimestampMap[currentMessage.msgId] = true
            currentMessage.showTimeDivider = true
        }
    }
    return chatList
}