<?php
require_once 'config.php';

$memory_chat_limit = 50;
$memory_knowledge_limit = 50;
$system_prompt = "Ты — профессиональный помощник и аналитик. Отвечай четко, по делу, без лишней воды. Используй предоставленную базу знаний для ответов.";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    
    if ($action === 'get_balance') {
        $ch = curl_init('https://gptunnel.ru/v1/balance');
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: ' . $apiKey]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        echo curl_exec($ch); exit;
    }

    if ($action === 'chat') {
        // РАСШИФРОВКА ЗАПРОСА (Обход антивируса хостинга)
        $userText = isset($_POST['text_b64']) ? base64_decode($_POST['text_b64']) : ($_POST['text'] ?? '');
        $realModel = $_POST['model'] ?? 'gpt-4o-mini';

        $db->prepare("INSERT INTO chat_history (role, content) VALUES ('user', ?)")->execute([htmlspecialchars($userText)]);
        $userId = $db->lastInsertId();

        $stmt = $db->prepare("SELECT content FROM knowledge ORDER BY id DESC LIMIT ?");
        $stmt->execute([$memory_knowledge_limit]);
        $knowledgeContext = implode("\n---\n", $stmt->fetchAll(PDO::FETCH_COLUMN));
        
        $stmt = $db->prepare("SELECT role, content, model_name FROM chat_history ORDER BY id DESC LIMIT ?");
        $stmt->execute([$memory_chat_limit]);
        $historyRaw = array_reverse($stmt->fetchAll(PDO::FETCH_ASSOC));
        
        $messages = [["role" => "system", "content" => $system_prompt . "\n\nТвоя база знаний:\n" . $knowledgeContext]];
        
        foreach ($historyRaw as $msg) {
            $cleanContent = preg_replace('/<br><img src=\'.*?\' class=\'chat-img\'>/', '', $msg['content']);
            $cleanContent = str_replace('<br>', "\n", $cleanContent);
            
            // ЖЕСТКИЙ ФИЛЬТР: Вырезаем любые квадратные скобки с именами в начале строки (лечит галлюцинации)
            $cleanContent = preg_replace('/^\[.*?\]:\s*/', '', $cleanContent);
            
            $messages[] = ["role" => $msg['role'], "content" => $cleanContent];
        }

        // УМНОЕ УДАЛЕНИЕ ДУБЛИКАТОВ: Если последнее сообщение в истории - это вопрос пользователя, 
        // удаляем его, чтобы не было двух вопросов подряд (из-за этого ломались Gemini и Claude)
        $lastMessage = end($messages);
        if ($lastMessage && $lastMessage['role'] === 'user') {
            array_pop($messages);
        }

        if (empty($userText)) { echo json_encode(['error' => 'Пустое сообщение']); exit; }
        $messages[] = ["role" => "user", "content" => $userText];

        $ch = curl_init('https://gptunnel.ru/v1/chat/completions');
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: ' . $apiKey, 'Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(["model" => $realModel, "messages" => $messages]));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        $result = json_decode($response, true);

        if (isset($result['choices'][0]['message']['content'])) {
            $aiText = $result['choices'][0]['message']['content'];
            
            // Еще раз на всякий случай чистим ответ от ИИ перед сохранением
            $aiText = preg_replace('/^\[.*?\]:\s*/', '', $aiText);
            
            $db->prepare("INSERT INTO chat_history (role, content, model_name) VALUES ('assistant', ?, ?)")->execute([htmlspecialchars($aiText), $realModel]);
            
            $voiceId = getSetting('tts_voice') ?: '65f4092eddc5862248a18d72';
            $ttsData = ["text" => mb_substr($aiText, 0, 4900), "voice_id" => $voiceId]; 
            
            $chTts = curl_init('https://gptunnel.ru/v1/tts/create');
            curl_setopt($chTts, CURLOPT_HTTPHEADER, ['Authorization: ' . $apiKey, 'Content-Type: application/json']);
            curl_setopt($chTts, CURLOPT_POST, true);
            curl_setopt($chTts, CURLOPT_POSTFIELDS, json_encode($ttsData));
            curl_setopt($chTts, CURLOPT_RETURNTRANSFER, true); curl_setopt($chTts, CURLOPT_SSL_VERIFYPEER, false);
            $ttsResponse = curl_exec($chTts);
            $ttsResult = json_decode($ttsResponse, true);
            
            $audioBase64 = $ttsResult['data'] ?? '';

            echo json_encode([
                'text' => htmlspecialchars($aiText), 
                'audio' => $audioBase64,
                'speed' => getSetting('tts_speed') ?: '1.0'
            ]);
        } else {
            $err = $result['error']['message'] ?? 'Неизвестная ошибка API';
            echo json_encode(['error' => $err]);
        }
        exit;
    }
}

$activeModels = $db->query("SELECT * FROM active_models ORDER BY id ASC")->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
    <title>Voice AI</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
    <style>
        :root { --bg: #0f172a; --panel: #1e293b; --accent: #10b981; --text: #f8fafc; --red: #ef4444; }
        * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
        body { background: var(--bg); color: var(--text); font-family: 'Inter', sans-serif; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
        
        /* ИСПРАВЛЕННАЯ ВЕРХНЯЯ ПАНЕЛЬ */
        .top-bar { background: var(--panel); padding: max(10px, env(safe-area-inset-top)) 15px 10px 15px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #334155; gap: 10px; }
        .model-select { flex: 1; background: transparent; color: var(--accent); border: none; font-size: 15px; font-weight: 600; outline: none; min-width: 0; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
        .top-right { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
        .balance { font-size: 13px; color: #fbbf24; font-weight: 600; white-space: nowrap; }
        .settings-btn { color: var(--text); text-decoration: none; font-size: 18px; }

        /* Чат */
        .chat-area { flex: 1; overflow-y: auto; padding: 15px; display: flex; flex-direction: column; gap: 15px; scroll-behavior: smooth; }
        .msg { padding: 12px 16px; border-radius: 12px; font-size: 15px; line-height: 1.4; max-width: 90%; word-wrap: break-word; }
        .msg.user { align-self: flex-end; background: #047857; border-bottom-right-radius: 4px; }
        .msg.ai { align-self: flex-start; background: var(--panel); border: 1px solid #334155; border-bottom-left-radius: 4px; }
        .status-text { text-align: center; font-size: 12px; color: var(--accent); font-style: italic; display: none; }

        /* Нижняя панель управления */
        .bottom-bar { background: var(--panel); padding: 15px; padding-bottom: max(15px, env(safe-area-inset-bottom)); border-top: 1px solid #334155; display: flex; flex-direction: column; gap: 15px; }
        
        .text-input-wrapper { display: flex; gap: 10px; align-items: flex-end; }
        .clear-btn { background: none; border: none; color: var(--text); opacity: 0.5; font-size: 20px; padding: 10px; cursor: pointer; }
        .clear-btn:active { opacity: 1; }
        textarea { flex: 1; background: var(--bg); border: 1px solid #334155; color: white; border-radius: 12px; padding: 12px; font-size: 16px; font-family: inherit; resize: none; outline: none; max-height: 100px; }
        textarea:focus { border-color: var(--accent); }
        
        .controls { display: flex; justify-content: center; align-items: center; gap: 30px; position: relative; }
        
        /* Кнопка микрофона */
        .mic-btn { width: 70px; height: 70px; border-radius: 50%; background: rgba(16, 185, 129, 0.1); border: 2px solid var(--accent); color: var(--accent); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: 0.2s; box-shadow: 0 0 15px rgba(16, 185, 129, 0.2); }
        .mic-btn svg { width: 30px; height: 30px; fill: currentColor; }
        .mic-btn.recording { background: var(--red); border-color: var(--red); color: white; box-shadow: 0 0 20px rgba(239, 68, 68, 0.6); animation: pulse 1.5s infinite; }
        
        /* Кнопка отправки */
        .send-btn { width: 50px; height: 50px; border-radius: 50%; background: var(--accent); border: none; color: white; display: flex; align-items: center; justify-content: center; cursor: pointer; }
        .send-btn svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
        .send-btn:disabled { background: #334155; color: #94a3b8; }

        /* Кнопка остановки аудио */
        .stop-audio-btn { position: absolute; right: 0; background: var(--red); color: white; border: none; padding: 8px 12px; border-radius: 8px; font-size: 12px; font-weight: bold; display: none; }

        @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
    </style>
</head>
<body>

<div class="top-bar">
    <select id="modelSelect" class="model-select">
    <option value="">Выберите модель</option>
    <?php foreach($activeModels as $m): ?>
        <option value="<?= htmlspecialchars($m['api_name']) ?>">
            <?= htmlspecialchars($m['custom_name'] ?: $m['api_name']) ?>
        </option>
    <?php endforeach; ?>
</select>
    <div class="top-right">
        <div id="balanceDisplay" class="balance">... ₽</div>
        <a href="m_settings.php" class="settings-btn">⚙️</a>
        <a href="pult.php" class="settings-btn">💻</a>
    </div>
</div>

<div class="chat-area" id="chatArea">
    <div class="msg ai">Привет! Нажми на микрофон, чтобы продиктовать сообщение.</div>
</div>
<div class="status-text" id="statusText">ИИ думает и генерирует голос...</div>

<div class="bottom-bar">
    <div class="text-input-wrapper">
        <button class="clear-btn" onclick="clearInput()">✖</button>
        <textarea id="textInput" rows="1" placeholder="Текст сообщения..." oninput="this.style.height='';this.style.height=this.scrollHeight+'px'"></textarea>
    </div>
    <div class="controls">
        <button class="mic-btn" id="micBtn" onclick="toggleDictation()">
            <svg viewBox="0 0 24 24"><path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z"/><path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z"/></svg>
        </button>
        <button class="send-btn" id="sendBtn" onclick="sendMessage()">
            <svg viewBox="0 0 24 24"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
        </button>
        <button class="stop-audio-btn" id="stopAudioBtn" onclick="stopAudio()">СТОП ⏹</button>
    </div>
</div>

<script>
    // --- ФУНКЦИЯ ШИФРОВАНИЯ ДЛЯ ОБХОДА АНТИВИРУСА ХОСТИНГА ---
    function encodeBase64Safe(str) {
        return btoa(new TextEncoder().encode(str).reduce((data, byte) => data + String.fromCharCode(byte), ''));
    }

    const chatArea = document.getElementById('chatArea');
    const textInput = document.getElementById('textInput');
    const micBtn = document.getElementById('micBtn');
    const sendBtn = document.getElementById('sendBtn');
    const statusText = document.getElementById('statusText');
    const stopAudioBtn = document.getElementById('stopAudioBtn');
    
    let keepRecording = false; 
    let currentAudio = null;
    let finalTranscript = ''; 

    textInput.addEventListener('input', () => {
        finalTranscript = textInput.value;
    });

    function clearInput() {
        textInput.value = '';
        finalTranscript = '';
        textInput.style.height = 'auto';
    }

    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    let recognition = null;
    
    if (SpeechRecognition) {
        recognition = new SpeechRecognition();
        recognition.lang = 'ru-RU';
        recognition.interimResults = true;
        recognition.continuous = false; 
        
        recognition.onresult = (event) => {
            let interimTranscript = '';
            for (let i = event.resultIndex; i < event.results.length; ++i) {
                if (event.results[i].isFinal) {
                    finalTranscript += event.results[i][0].transcript + ' ';
                } else {
                    interimTranscript += event.results[i][0].transcript;
                }
            }
            textInput.value = finalTranscript + interimTranscript;
            textInput.style.height = 'auto';
            textInput.style.height = textInput.scrollHeight + 'px';
        };
        
        recognition.onend = () => {
            if (keepRecording) {
                try { recognition.start(); } catch(e) {}
            } else {
                micBtn.classList.remove('recording');
            }
        };
    } else {
        alert("Ваш браузер не поддерживает голосовой ввод.");
    }

    function toggleDictation() {
        if (!recognition) return;
        
        if (keepRecording) {
            keepRecording = false;
            recognition.stop();
            micBtn.classList.remove('recording');
        } else {
            stopAudio();
            keepRecording = true;
            try { recognition.start(); } catch(e) {}
            micBtn.classList.add('recording');
        }
    }

    function stopAudio() {
        if (currentAudio) {
            currentAudio.pause();
            currentAudio = null;
            stopAudioBtn.style.display = 'none';
        }
    }

    function addMsg(text, type) {
        const div = document.createElement('div');
        div.className = `msg ${type}`;
        div.innerHTML = text.replace(/\n/g, '<br>');
        chatArea.appendChild(div);
        chatArea.scrollTop = chatArea.scrollHeight;
    }

     async function sendMessage() {
        const modelSelect = document.getElementById('modelSelect');
        
        // ПРОВЕРКА: Выбрана ли модель?
        if (!modelSelect.value) {
            alert("Прежде отправки сообщения, выберите, пожалуйста модель ИИ");
            return;
        }

        const text = textInput.value.trim();
        if (!text) return;
        
        if (keepRecording) {
            keepRecording = false;
            recognition.stop();
            micBtn.classList.remove('recording');
        }
        stopAudio(); 
        
        const model = document.getElementById('modelSelect').value;
        addMsg(text, 'user');
        
        clearInput();
        
        sendBtn.disabled = true;
        statusText.style.display = 'block';

        try {
            // ОТПРАВЛЯЕМ ЗАШИФРОВАННЫЙ ТЕКСТ
            const resp = await fetch('', {
                method: 'POST',
                headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                body: `action=chat&text_b64=${encodeURIComponent(encodeBase64Safe(text))}&model=${encodeURIComponent(model)}`
            });
            const data = await resp.json();
            
            if (data.text && data.text.trim() !== '') {
                addMsg(data.text, 'ai');
                
                if (data.audio) {
                    currentAudio = new Audio("data:audio/mp3;base64," + data.audio);
                    currentAudio.playbackRate = parseFloat(data.speed) || 1.0;
                    stopAudioBtn.style.display = 'block';
                    currentAudio.onended = () => stopAudioBtn.style.display = 'none';
                    currentAudio.play().catch(e => console.log("Автовоспроизведение заблокировано", e));
                }
            } else if (data.error) {
                addMsg("⚠️ Ошибка: " + data.error, 'ai');
            } else {
                addMsg("⚠️ Модель вернула пустой ответ.", 'ai');
            }
        } catch (e) {
            addMsg("Ошибка связи с сервером.", 'ai');
        } finally {
            sendBtn.disabled = false;
            statusText.style.display = 'none';
            updateBalance();
        }
    }

    async function updateBalance() {
        try {
            const r = await fetch('', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'action=get_balance' });
            const d = await r.json();
            if(d.balance !== undefined) document.getElementById('balanceDisplay').innerText = Math.round(d.balance) + ' ₽';
        } catch(e) {}
    }
    updateBalance();
</script>
</body>
</html>