"""
Web Application - FastAPI server for groknroll

Provides a web interface for interacting with groknroll agents.
"""

from pathlib import Path
from typing import Optional

from groknroll import __version__


def create_app(
    project_path: Optional[Path] = None,
    debug: bool = False,
    cors_origins: Optional[list[str]] = None,
) -> "FastAPI":
    """
    Create the FastAPI application

    Args:
        project_path: Project directory
        debug: Enable debug mode
        cors_origins: Allowed CORS origins

    Returns:
        Configured FastAPI application
    """
    try:
        from fastapi import FastAPI
        from fastapi.middleware.cors import CORSMiddleware
        from fastapi.responses import HTMLResponse
        from fastapi.staticfiles import StaticFiles
    except ImportError:
        raise ImportError(
            "FastAPI is required for web interface. Install with: pip install fastapi uvicorn"
        )

    # Create app
    app = FastAPI(
        title="groknroll API",
        description="Web interface for the groknroll CLI coding agent",
        version=__version__,
        docs_url="/api/docs",
        redoc_url="/api/redoc",
        openapi_url="/api/openapi.json",
    )

    # Add CORS middleware
    origins = cors_origins or ["*"]
    app.add_middleware(
        CORSMiddleware,
        allow_origins=origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    # Create routes
    from groknroll.web.routes import create_routes

    create_routes(app, project_path)

    # Add basic UI route
    @app.get("/", response_class=HTMLResponse)
    async def index():
        """Serve the main UI"""
        return _get_index_html()

    return app


def _get_index_html() -> str:
    """Generate the main UI HTML"""
    return f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>groknroll - Web Interface</title>
    <style>
        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            background: #1a1a2e;
            color: #eee;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }}
        header {{
            background: #16213e;
            padding: 1rem 2rem;
            display: flex;
            align-items: center;
            justify-content: space-between;
            border-bottom: 1px solid #0f3460;
        }}
        .logo {{
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }}
        .logo h1 {{
            font-size: 1.5rem;
            background: linear-gradient(135deg, #00d9ff, #00ff88);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }}
        .version {{
            color: #666;
            font-size: 0.8rem;
        }}
        .agent-selector {{
            display: flex;
            gap: 0.5rem;
        }}
        .agent-btn {{
            padding: 0.5rem 1rem;
            border: 1px solid #0f3460;
            background: transparent;
            color: #888;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s;
        }}
        .agent-btn:hover {{
            border-color: #00d9ff;
            color: #00d9ff;
        }}
        .agent-btn.active {{
            background: #0f3460;
            color: #00d9ff;
            border-color: #00d9ff;
        }}
        main {{
            flex: 1;
            display: flex;
            flex-direction: column;
            max-width: 1200px;
            margin: 0 auto;
            width: 100%;
            padding: 1rem;
        }}
        .messages {{
            flex: 1;
            overflow-y: auto;
            padding: 1rem;
            display: flex;
            flex-direction: column;
            gap: 1rem;
        }}
        .message {{
            padding: 1rem;
            border-radius: 8px;
            max-width: 80%;
        }}
        .message.user {{
            background: #0f3460;
            align-self: flex-end;
        }}
        .message.assistant {{
            background: #16213e;
            align-self: flex-start;
            border: 1px solid #0f3460;
        }}
        .message pre {{
            background: #1a1a2e;
            padding: 0.5rem;
            border-radius: 4px;
            overflow-x: auto;
        }}
        .message code {{
            font-family: 'Fira Code', 'Monaco', monospace;
            font-size: 0.9em;
        }}
        .input-area {{
            display: flex;
            gap: 0.5rem;
            padding: 1rem;
            background: #16213e;
            border-radius: 8px;
        }}
        .input-area textarea {{
            flex: 1;
            background: #1a1a2e;
            border: 1px solid #0f3460;
            color: #eee;
            padding: 1rem;
            border-radius: 4px;
            resize: none;
            font-family: inherit;
            font-size: 1rem;
        }}
        .input-area textarea:focus {{
            outline: none;
            border-color: #00d9ff;
        }}
        .input-area button {{
            padding: 1rem 2rem;
            background: linear-gradient(135deg, #00d9ff, #00ff88);
            border: none;
            color: #1a1a2e;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: transform 0.2s;
        }}
        .input-area button:hover {{
            transform: scale(1.05);
        }}
        .input-area button:disabled {{
            opacity: 0.5;
            cursor: not-allowed;
            transform: none;
        }}
        .status {{
            text-align: center;
            padding: 0.5rem;
            color: #666;
        }}
        .typing {{
            color: #00d9ff;
            animation: pulse 1s infinite;
        }}
        @keyframes pulse {{
            0%, 100% {{ opacity: 1; }}
            50% {{ opacity: 0.5; }}
        }}
        .empty-state {{
            text-align: center;
            color: #666;
            padding: 4rem;
        }}
        .empty-state h2 {{
            font-size: 2rem;
            margin-bottom: 1rem;
            color: #888;
        }}
        .empty-state p {{
            margin-bottom: 0.5rem;
        }}
    </style>
</head>
<body>
    <header>
        <div class="logo">
            <h1>groknroll</h1>
            <span class="version">v{__version__}</span>
        </div>
        <div class="agent-selector">
            <button class="agent-btn active" data-agent="build">Build</button>
            <button class="agent-btn" data-agent="plan">Plan</button>
            <button class="agent-btn" data-agent="oracle">Oracle</button>
        </div>
    </header>

    <main>
        <div class="messages" id="messages">
            <div class="empty-state">
                <h2>Welcome to groknroll</h2>
                <p>The ultimate CLI coding agent with unlimited context</p>
                <p>Type a message below to get started</p>
            </div>
        </div>

        <div class="status" id="status"></div>

        <div class="input-area">
            <textarea
                id="input"
                placeholder="Ask me anything about your code..."
                rows="3"
            ></textarea>
            <button id="send">Send</button>
        </div>
    </main>

    <script>
        const messagesEl = document.getElementById('messages');
        const inputEl = document.getElementById('input');
        const sendBtn = document.getElementById('send');
        const statusEl = document.getElementById('status');
        const agentBtns = document.querySelectorAll('.agent-btn');

        let sessionId = null;
        let currentAgent = 'build';
        let isProcessing = false;

        // Agent selection
        agentBtns.forEach(btn => {{
            btn.addEventListener('click', () => {{
                agentBtns.forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                currentAgent = btn.dataset.agent;
            }});
        }});

        // Send message
        async function sendMessage() {{
            const message = inputEl.value.trim();
            if (!message || isProcessing) return;

            isProcessing = true;
            sendBtn.disabled = true;
            inputEl.value = '';

            // Clear empty state
            const emptyState = messagesEl.querySelector('.empty-state');
            if (emptyState) emptyState.remove();

            // Add user message
            addMessage('user', message);

            // Show typing indicator
            statusEl.innerHTML = '<span class="typing">Assistant is typing...</span>';

            try {{
                const response = await fetch('/api/v1/chat/stream', {{
                    method: 'POST',
                    headers: {{ 'Content-Type': 'application/json' }},
                    body: JSON.stringify({{
                        message: message,
                        session_id: sessionId,
                        agent: currentAgent,
                        stream: true,
                    }})
                }});

                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let assistantMsg = null;
                let fullContent = '';

                while (true) {{
                    const {{ done, value }} = await reader.read();
                    if (done) break;

                    const text = decoder.decode(value);
                    const lines = text.split('\\n');

                    for (const line of lines) {{
                        if (line.startsWith('data: ')) {{
                            const data = JSON.parse(line.slice(6));

                            if (!sessionId) {{
                                sessionId = data.session_id;
                            }}

                            if (data.type === 'text') {{
                                fullContent += data.content;
                                if (!assistantMsg) {{
                                    assistantMsg = addMessage('assistant', fullContent);
                                }} else {{
                                    assistantMsg.querySelector('.content').innerHTML = formatContent(fullContent);
                                }}
                            }} else if (data.type === 'done') {{
                                // Complete
                            }} else if (data.type === 'error') {{
                                addMessage('assistant', 'Error: ' + data.content);
                            }}
                        }}
                    }}
                }}
            }} catch (error) {{
                addMessage('assistant', 'Error: ' + error.message);
            }}

            statusEl.innerHTML = '';
            isProcessing = false;
            sendBtn.disabled = false;
            inputEl.focus();
        }}

        function addMessage(role, content) {{
            const div = document.createElement('div');
            div.className = 'message ' + role;
            div.innerHTML = '<div class="content">' + formatContent(content) + '</div>';
            messagesEl.appendChild(div);
            messagesEl.scrollTop = messagesEl.scrollHeight;
            return div;
        }}

        function formatContent(text) {{
            // Basic markdown formatting
            return text
                .replace(/```(\\w*)\\n([\\s\\S]*?)```/g, '<pre><code>$2</code></pre>')
                .replace(/`([^`]+)`/g, '<code>$1</code>')
                .replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>')
                .replace(/\\n/g, '<br>');
        }}

        // Event listeners
        sendBtn.addEventListener('click', sendMessage);
        inputEl.addEventListener('keydown', (e) => {{
            if (e.key === 'Enter' && !e.shiftKey) {{
                e.preventDefault();
                sendMessage();
            }}
        }});

        // Focus input on load
        inputEl.focus();
    </script>
</body>
</html>
"""


def run_server(
    host: str = "127.0.0.1",
    port: int = 8080,
    project_path: Optional[Path] = None,
    debug: bool = False,
    reload: bool = False,
) -> None:
    """
    Run the web server

    Args:
        host: Host to bind to
        port: Port to listen on
        project_path: Project directory
        debug: Enable debug mode
        reload: Enable auto-reload (for development)
    """
    try:
        import uvicorn
    except ImportError:
        raise ImportError(
            "uvicorn is required to run the web server. Install with: pip install uvicorn"
        )

    app = create_app(project_path=project_path, debug=debug)

    uvicorn.run(
        app,
        host=host,
        port=port,
        reload=reload,
        log_level="debug" if debug else "info",
    )
