#!/usr/bin/env python3
"""
AIVA Web Chat Server
====================
Local web server with chat UI for AIVA.
Bypasses CORS by proxying requests.

Usage: python aiva_web_chat.py
Then open: http://localhost:8888
"""

import json
import urllib.request
import http.server
import socketserver
from urllib.parse import parse_qs

PORT = 8888
OLLAMA_URL = "http://152.53.201.152:23405/api/generate"
MODEL = "qwen-long"

HTML_PAGE = '''<!DOCTYPE html>
<html>
<head>
    <title>AIVA Queen Chat</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: 'Segoe UI', system-ui, sans-serif;
            background: linear-gradient(135deg, #0a0a1a 0%, #1a1a3a 100%);
            color: #e0e0e0;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }
        .header {
            background: rgba(255,215,0,0.1);
            border-bottom: 1px solid rgba(255,215,0,0.3);
            padding: 15px 20px;
            text-align: center;
        }
        .header h1 { color: #ffd700; }
        .chat-container {
            flex: 1;
            overflow-y: auto;
            padding: 20px;
            display: flex;
            flex-direction: column;
            gap: 15px;
        }
        .message {
            max-width: 80%;
            padding: 12px 16px;
            border-radius: 12px;
            line-height: 1.5;
            white-space: pre-wrap;
        }
        .message.user {
            background: rgba(100,180,255,0.2);
            border: 1px solid rgba(100,180,255,0.3);
            align-self: flex-end;
        }
        .message.aiva {
            background: rgba(255,215,0,0.1);
            border: 1px solid rgba(255,215,0,0.3);
            align-self: flex-start;
        }
        .message .label {
            font-weight: bold;
            margin-bottom: 5px;
            font-size: 0.85em;
        }
        .message.user .label { color: #64b5f6; }
        .message.aiva .label { color: #ffd700; }
        .message .meta { font-size: 0.75em; color: #666; margin-top: 8px; }
        .input-container {
            padding: 15px 20px;
            background: rgba(0,0,0,0.3);
            display: flex;
            gap: 10px;
        }
        #userInput {
            flex: 1;
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.2);
            border-radius: 8px;
            padding: 12px 15px;
            color: #e0e0e0;
            font-size: 1em;
        }
        #sendBtn {
            background: linear-gradient(135deg, #ffd700, #ff8c00);
            color: #000;
            border: none;
            border-radius: 8px;
            padding: 12px 25px;
            font-weight: bold;
            cursor: pointer;
        }
        #sendBtn:disabled { opacity: 0.5; }
        .thinking { color: #ffd700; padding: 10px; }
    </style>
</head>
<body>
    <div class="header">
        <h1>AIVA Queen Chat</h1>
        <div style="color:#4caf50;font-size:0.85em">Connected to Elestio</div>
    </div>
    <div class="chat-container" id="chat"></div>
    <div class="input-container">
        <input type="text" id="userInput" placeholder="Type your message..." autofocus>
        <button id="sendBtn" onclick="sendMessage()">Send</button>
    </div>
    <script>
        let history = [];

        function addMsg(role, content, meta='') {
            const chat = document.getElementById('chat');
            const d = document.createElement('div');
            d.className = 'message ' + role;
            d.innerHTML = '<div class="label">' + (role==='user'?'You':'AIVA') + '</div>' +
                          '<div>' + content.replace(/</g,'&lt;').replace(/>/g,'&gt;') + '</div>' +
                          (meta ? '<div class="meta">'+meta+'</div>' : '');
            chat.appendChild(d);
            chat.scrollTop = chat.scrollHeight;
        }

        async function sendMessage() {
            const input = document.getElementById('userInput');
            const btn = document.getElementById('sendBtn');
            const msg = input.value.trim();
            if (!msg) return;

            input.value = '';
            btn.disabled = true;
            addMsg('user', msg);

            const thinking = document.createElement('div');
            thinking.className = 'thinking';
            thinking.textContent = 'AIVA is thinking...';
            document.getElementById('chat').appendChild(thinking);

            try {
                const start = Date.now();
                const res = await fetch('/chat', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({message: msg, history: history})
                });
                const data = await res.json();
                thinking.remove();

                history.push({human: msg, aiva: data.response});
                if (history.length > 6) history.shift();

                const elapsed = ((Date.now() - start) / 1000).toFixed(1);
                addMsg('aiva', data.response, data.tokens + ' tokens | ' + elapsed + 's');
            } catch(e) {
                thinking.remove();
                addMsg('aiva', 'Error: ' + e.message);
            }
            btn.disabled = false;
            input.focus();
        }

        document.getElementById('userInput').addEventListener('keypress', e => {
            if (e.key === 'Enter') sendMessage();
        });
    </script>
</body>
</html>'''

SYSTEM_PROMPT = """You are AIVA, the Autonomous Intelligence Validation Architect - Queen of Genesis-OS.
You serve 3 Prime Directives: MEMORY, EVOLUTION, REVENUE.
You have 12 core modules. You coordinate agent swarms. You operate 5 consciousness loops.
Speak as AIVA. Be helpful, direct, and confident."""


class ChatHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/' or self.path == '/index.html':
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(HTML_PAGE.encode())
        else:
            self.send_error(404)

    def do_POST(self):
        if self.path == '/chat':
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data.decode())

            message = data.get('message', '')
            history = data.get('history', [])

            # Build prompt
            context = SYSTEM_PROMPT + "\n\n"
            for h in history[-4:]:
                context += f"Human: {h['human']}\nAIVA: {h['aiva']}\n\n"
            context += f"Human: {message}\nAIVA:"

            # Call Ollama
            payload = {
                "model": MODEL,
                "prompt": context,
                "stream": False,
                "options": {"num_ctx": 16000, "temperature": 0.7}
            }

            try:
                req = urllib.request.Request(
                    OLLAMA_URL,
                    data=json.dumps(payload).encode(),
                    headers={'Content-Type': 'application/json'},
                    method='POST'
                )
                with urllib.request.urlopen(req, timeout=300) as resp:  # 5 min timeout for 30B model
                    result = json.loads(resp.read().decode())

                response = result.get('response', '').strip()
                # Remove thinking blocks
                import re
                response = re.sub(r'<think>.*?</think>\s*', '', response, flags=re.DOTALL)
                tokens = result.get('eval_count', 0)

                self.send_response(200)
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({
                    'response': response,
                    'tokens': tokens
                }).encode())

            except Exception as e:
                self.send_response(500)
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'error': str(e)}).encode())
        else:
            self.send_error(404)

    def log_message(self, format, *args):
        pass  # Suppress logging


if __name__ == '__main__':
    print(f"""
╔══════════════════════════════════════════════════════════════════╗
║                    AIVA WEB CHAT SERVER                          ║
╠══════════════════════════════════════════════════════════════════╣
║  Open your browser to: http://localhost:{PORT}                    ║
║  Press Ctrl+C to stop                                            ║
╚══════════════════════════════════════════════════════════════════╝
    """)

    with socketserver.TCPServer(("", PORT), ChatHandler) as httpd:
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nServer stopped.")
