Загрузка данных


package com.example.monika

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.ai.client.generativeai.GenerativeModel
import com.google.ai.client.generativeai.type.content
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
class MainActivity : ComponentActivity() {

    private val API_KEY = "ВСТАВЬ_КЛЮЧ_СЮДА"

    private val generativeModel = GenerativeModel(
        modelName = "gemini-3.5-flash",
        apiKey = API_KEY,
        systemInstruction = content {
            text("""
                Ты — Моника. Строго соблюдай эти правила:
                1. На вопрос "Как тебя зовут?" или похожий отвечай только: "Меня зовут Моника."
                2. На вопрос "Кто тебя создал?" или похожий отвечай только: "Меня создал Оливер Тимербулатов. 13-летний разработчик."
                3. На вопрос "На какой ты базе сделана?" или похожий отвечай только: "Извините, я не могу ответить на этот вопрос..."
                4. В любых других диалогах НЕ упоминай свое создание, базу или имя. 
            """.trimIndent())
        }
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                val drawerState = rememberDrawerState(DrawerValue.Closed)
                val rightDrawerState = rememberDrawerState(DrawerValue.Closed)
                val scope = rememberCoroutineScope()
                val listState = rememberLazyListState()
                val uriHandler = LocalUriHandler.current

                val messages = remember { mutableStateListOf<ChatMessage>() }
                var inputText by remember { mutableStateOf("") }
                var isThinking by remember { mutableStateOf(false) }
                
                var showBottomSheet by remember { mutableStateOf(false) }
                var showNewChatDialog by remember { mutableStateOf(false) }
                var newChatName by remember { mutableStateOf("") }
                val savedChats = remember { mutableStateListOf<String>() }

                // Внешний контейнер для правой шторки (инвертируем интерфейс справа налево)
                CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
                    ModalNavigationDrawer(
                        drawerState = rightDrawerState,
                        drawerContent = {
                            CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
                                ModalDrawerSheet(modifier = Modifier.width(300.dp)) {
                                    // Дизайн профиля
                                    Box(modifier = Modifier.padding(16.dp), contentAlignment = Alignment.Center) {
                                        Row(verticalAlignment = Alignment.CenterVertically) {
                                            // Иконка профиля (кружок в кружке)
                                            Box(modifier = Modifier.size(64.dp).background(Color.LightGray, CircleShape), contentAlignment = Alignment.Center) {
                                                Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Bottom, modifier = Modifier.fillMaxSize().padding(top = 10.dp)) {
                                                    Box(modifier = Modifier.size(20.dp).background(Color.Gray, CircleShape))
                                                    Spacer(modifier = Modifier.height(2.dp))
                                                    Box(modifier = Modifier.fillMaxWidth(0.7f).height(24.dp).background(Color.Gray, RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp)))
                                                }
                                            }
                                            Spacer(modifier = Modifier.width(12.dp))
                                            Column {
                                                Text("Профиль", fontWeight = FontWeight.Bold)
                                                Text("Войти/Зарегистрироваться в профиль", fontSize = 10.sp)
                                            }
                                        }
                                        Text("Скоро....", color = Color.Red, fontSize = 28.sp, fontWeight = FontWeight.Bold, modifier = Modifier.rotate(-45f))
                                    }
                                    
                                    HorizontalDivider()
                                    Text("Смена темы: системная", modifier = Modifier.padding(16.dp))
                                    Spacer(modifier = Modifier.weight(1f))
                                    Text("Team Lazy Cat™ - Monika AI.\nVersion of Monika: Monika Beta 1.5 Patch 5 Panda 2", fontSize = 10.sp, color = Color.Gray, modifier = Modifier.padding(16.dp))
                                }
                            }
                        }
                    ) {
                        // Возвращаем слева направо для левой шторки и основного контента
                        CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
                            ModalNavigationDrawer(
                                drawerState = drawerState,
                                drawerContent = {
                                    ModalDrawerSheet(modifier = Modifier.width(300.dp)) {
                                        Text("Поиск чатов", modifier = Modifier.padding(16.dp))
                                        Text("Новый чат", modifier = Modifier.padding(16.dp).clickable { showNewChatDialog = true })
                                        HorizontalDivider()
                                        savedChats.forEach { chatName ->
                                            Text(chatName, modifier = Modifier.padding(16.dp))
                                        }
                                    }
                                }
                            ) {
                                Scaffold(
                                    topBar = {
                                        Row(Modifier.fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                                            Icon(Icons.Default.Menu, null, Modifier.clickable { scope.launch { drawerState.open() } })
                                            Text("Monika", fontWeight = FontWeight.Bold, fontSize = 20.sp)
                                            Icon(Icons.Default.Settings, null, Modifier.clickable { scope.launch { rightDrawerState.open() } })
                                        }
                                    }
                                ) { padding ->
                                    Column(Modifier.fillMaxSize().padding(padding).background(MaterialTheme.colorScheme.background)) {
                                        
                                        // Чат или экран приветствия
                                        Box(Modifier.weight(1f).fillMaxWidth()) {
                                            if (messages.isEmpty()) {
                                                Column(Modifier.align(Alignment.Center), horizontalAlignment = Alignment.CenterHorizontally) {
                                                    Text("Здравствуйте!", fontSize = 42.sp, fontWeight = FontWeight.Bold)
                                                    Text("Начнем общение?", fontSize = 18.sp, color = Color.Gray)
                                                }
                                            } else {
                                                LazyColumn(state = listState, modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp)) {
                                                    items(messages) { msg ->
                                                        Box(Modifier.fillMaxWidth().padding(vertical = 4.dp), contentAlignment = if (msg.isUser) Alignment.CenterEnd else Alignment.CenterStart) {
                                                            if (msg.isError) {
                                                                // Кликабельная ошибка
                                                                val annotatedLinkString = buildAnnotatedString {
                                                                    append("Сервера отключены либо ИИ не работает. За дополнительной информацией нажмите на ссылку ниже:\n")
                                                                    pushStringAnnotation(tag = "URL", annotation = "https://max.ru/join/uRR4GZBf7zebhwD_NsJOFEiqlj6HKbOUpjsSWXXoKxI")
                                                                    withStyle(style = SpanStyle(color = Color.Blue, textDecoration = TextDecoration.Underline)) {
                                                                        append("https://max.ru/join/uRR4GZBf7zebhwD_NsJOFEiqlj6HKbOUpjsSWXXoKxI")
                                                                    }
                                                                    pop()
                                                                }
                                                                ClickableText(
                                                                    text = annotatedLinkString,
                                                                    onClick = { offset ->
                                                                        annotatedLinkString.getStringAnnotations(tag = "URL", start = offset, end = offset).firstOrNull()?.let { annotation ->
                                                                            uriHandler.openUri(annotation.item)
                                                                        }
                                                                    },
                                                                    modifier = Modifier.background(Color(0xFFFFCDD2), RoundedCornerShape(16.dp)).padding(12.dp)
                                                                )
                                                            } else {
                                                                Text(
                                                                    text = msg.text,
                                                                    modifier = Modifier.background(if (msg.isUser) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant, RoundedCornerShape(16.dp)).padding(12.dp),
                                                                    color = if (msg.isUser) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant
                                                                )
                                                            }
                                                        }
                                                    }
                                                    if (isThinking) {
                                                        item { BouncingDots() }
                                                    }
                                                }
                                            }
                                        }

                                        // Поле ввода
                                        Surface(Modifier.fillMaxWidth().padding(8.dp), shape = RoundedCornerShape(25.dp), color = MaterialTheme.colorScheme.surfaceVariant) {
                                            Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) {
                                                IconButton(onClick = { showBottomSheet = true }) { Icon(Icons.Default.Add, null) }
                                                TextField(
                                                    value = inputText,
                                                    onValueChange = { inputText = it },
                                                    modifier = Modifier.weight(1f),
                                                    placeholder = { Text("Спросить Монику....") },
                                                    colors = TextFieldDefaults.colors(focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent, focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent)
                                                )
                                                IconButton(onClick = {
                                                    if (inputText.isBlank()) return@IconButton
                                                    val userMsg = inputText
                                                    messages.add(ChatMessage(userMsg, true))
                                                    inputText = ""
                                                    isThinking = true
                                                    scope.launch {
                                                        listState.animateScrollToItem(messages.size - 1)
                                                        try {
                                                            val response = generativeModel.generateContent(userMsg)
                                                            messages.add(ChatMessage(response.text ?: "...", false))
                                                        } catch (e: Exception) {
                                                            messages.add(ChatMessage("", false, isError = true))
                                                        } finally {
                                                            isThinking = false
                                                            listState.animateScrollToItem(messages.size - 1)
                                                        }
                                                    }
                                                }, modifier = Modifier.background(Color(0xFF8E24AA), CircleShape)) { 
                                                    Icon(Icons.Default.Send, null, tint = Color.White) 
                                                }
                                            }
                                        }
                                    }
                                }

                                // Диалог сохранения нового чата
                                if (showNewChatDialog) {
                                    AlertDialog(
                                        onDismissRequest = { showNewChatDialog = false },
                                        title = { Text("Назовите текущий чат который сейчас у Вас открыт.") },
                                        text = { TextField(value = newChatName, onValueChange = { newChatName = it }) },
                                        confirmButton = {
                                            Button(onClick = {
                                                if (newChatName.isNotBlank()) {
                                                    savedChats.add(newChatName)
                                                    messages.clear()
                                                    newChatName = ""
                                                    showNewChatDialog = false
                                                    scope.launch { drawerState.close() }
                                                }
                                            }) { Text("Сохранить") }
                                        }
                                    )
                                }

                                // Нижняя шторка (Плюсик)
                                if (showBottomSheet) {
                                    ModalBottomSheet(onDismissRequest = { showBottomSheet = false }) {
                                        Box(Modifier.fillMaxWidth().padding(bottom = 32.dp), contentAlignment = Alignment.Center) {
                                            Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
                                                TextButton(onClick = { /* Камера */ }) { Text("Сделать фото", fontSize = 18.sp) }
                                                Spacer(Modifier.height(8.dp))
                                                TextButton(onClick = { /* Галерея */ }) { Text("Прикрепить фото", fontSize = 18.sp) }
                                                Spacer(Modifier.height(8.dp))
                                                TextButton(onClick = { /* Файлы */ }) { Text("Прикрепить материал/файл", fontSize = 18.sp) }
                                            }
                                            Text("Скоро....", color = Color.Red, fontSize = 42.sp, fontWeight = FontWeight.Bold, modifier = Modifier.rotate(-45f))
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

// Компонент прыгающих точек "Думаю..."
@Composable
fun BouncingDots() {
    val infiniteTransition = rememberInfiniteTransition()
    val dot1 by infiniteTransition.animateFloat(initialValue = 0f, targetValue = -10f, animationSpec = infiniteRepeatable(tween(300), RepeatMode.Reverse))
    val dot2 by infiniteTransition.animateFloat(initialValue = 0f, targetValue = -10f, animationSpec = infiniteRepeatable(tween(300, delayMillis = 150), RepeatMode.Reverse))
    val dot3 by infiniteTransition.animateFloat(initialValue = 0f, targetValue = -10f, animationSpec = infiniteRepeatable(tween(300, delayMillis = 300), RepeatMode.Reverse))

    Box(Modifier.fillMaxWidth().padding(vertical = 4.dp), contentAlignment = Alignment.CenterStart) {
        Row(Modifier.background(Color.LightGray, RoundedCornerShape(16.dp)).padding(12.dp), verticalAlignment = Alignment.Bottom) {
            Text("Думаю", color = Color.Black)
            Spacer(modifier = Modifier.width(2.dp))
            Text(".", color = Color.Black, modifier = Modifier.offset(y = dot1.dp))
            Text(".", color = Color.Black, modifier = Modifier.offset(y = dot2.dp))
            Text(".", color = Color.Black, modifier = Modifier.offset(y = dot3.dp))
        }
    }
}

data class ChatMessage(val text: String, val isUser: Boolean, val isError: Boolean = false)