/**
 * Gravity Web Bridge Extension
 *
 * Antigravity IDE 내부에서 동작하여:
 * 1. antigravity-sdk로 대화/상태 접근
 * 2. 로컬 HTTP/WS 서버를 열어 Gravity Web 서버와 통신
 *
 * API:
 *   GET  /api/sessions     → 대화 목록
 *   GET  /api/session/:id  → 대화 상세
 *   POST /api/send         → 메시지 전송
 *   POST /api/accept       → 스텝 승인
 *   POST /api/reject       → 스텝 거절
 *   WS   /ws               → 실시간 이벤트 스트림
 */

import * as vscode from 'vscode';

// antigravity-sdk는 런타임에 로드 (VS Code Extension 환경에서만 동작)
let AntigravitySDK: any;

const BRIDGE_PORT = 9850;

export async function activate(context: vscode.ExtensionContext) {
    const output = vscode.window.createOutputChannel('Gravity Web Bridge');
    output.appendLine('[Bridge] Extension 활성화...');

    // antigravity-sdk 로드
    try {
        const sdkModule = require('antigravity-sdk');
        AntigravitySDK = sdkModule.AntigravitySDK;
    } catch (err: any) {
        output.appendLine(`[Bridge] antigravity-sdk 로드 실패: ${err.message}`);
        vscode.window.showErrorMessage('Gravity Web Bridge: antigravity-sdk를 찾을 수 없습니다.');
        return;
    }

    // SDK 초기화
    const sdk = new AntigravitySDK(context);
    try {
        await sdk.initialize();
        output.appendLine('[Bridge] SDK 초기화 완료');
    } catch (err: any) {
        output.appendLine(`[Bridge] SDK 초기화 실패: ${err.message}`);
        return;
    }

    // Express + WS 서버
    const express = require('express');
    const http = require('http');
    const { WebSocketServer } = require('ws');

    const app = express();
    const server = http.createServer(app);
    const wss = new WebSocketServer({ server, path: '/ws' });

    app.use(express.json());

    // CORS 허용
    app.use((_req: any, res: any, next: any) => {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Content-Type');
        res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
        next();
    });

    // --- REST API ---

    app.get('/api/sessions', async (_req: any, res: any) => {
        try {
            const sessions = await sdk.cascade.getSessions();
            res.json({ sessions });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.post('/api/send', async (req: any, res: any) => {
        try {
            const { message, sessionId } = req.body;
            if (sessionId) {
                await sdk.cascade.focusSession(sessionId);
            }
            await sdk.cascade.sendPrompt(message);
            res.json({ success: true });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.post('/api/accept', async (_req: any, res: any) => {
        try {
            await sdk.cascade.acceptStep();
            res.json({ success: true });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.post('/api/reject', async (_req: any, res: any) => {
        try {
            await sdk.cascade.rejectStep();
            res.json({ success: true });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.post('/api/accept-terminal', async (_req: any, res: any) => {
        try {
            await sdk.cascade.acceptTerminalCommand();
            res.json({ success: true });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.get('/api/preferences', async (_req: any, res: any) => {
        try {
            const prefs = await sdk.cascade.getPreferences();
            res.json({ preferences: prefs });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.get('/api/health', (_req: any, res: any) => {
        res.json({ status: 'ok', port: BRIDGE_PORT, version: '0.1.0' });
    });

    // --- WebSocket 이벤트 스트림 ---

    const wsClients = new Set<any>();

    wss.on('connection', (ws: any) => {
        wsClients.add(ws);
        output.appendLine('[Bridge WS] 클라이언트 연결');

        ws.on('close', () => {
            wsClients.delete(ws);
            output.appendLine('[Bridge WS] 클라이언트 해제');
        });

        // 초기 세션 목록 전송
        sdk.cascade.getSessions().then((sessions: any) => {
            ws.send(JSON.stringify({ type: 'sessions', sessions }));
        }).catch(() => { });
    });

    function broadcast(data: any) {
        const json = JSON.stringify(data);
        for (const ws of wsClients) {
            if (ws.readyState === 1) { // WebSocket.OPEN
                ws.send(json);
            }
        }
    }

    // SDK 모니터 이벤트 → WS 브로드캐스트
    sdk.monitor.onStepCountChanged((e: any) => {
        broadcast({
            type: 'step_changed',
            title: e.title,
            delta: e.delta,
            newCount: e.newCount,
            sessionId: e.sessionId,
        });
    });

    sdk.monitor.onActiveSessionChanged((e: any) => {
        broadcast({
            type: 'session_changed',
            title: e.title,
            sessionId: e.sessionId,
        });
    });

    sdk.monitor.onNewConversation(() => {
        broadcast({ type: 'new_conversation' });
        // 세션 목록 갱신
        sdk.cascade.getSessions().then((sessions: any) => {
            broadcast({ type: 'sessions', sessions });
        }).catch(() => { });
    });

    sdk.monitor.onStateChanged((e: any) => {
        broadcast({
            type: 'state_changed',
            key: e.key,
            previousSize: e.previousSize,
            newSize: e.newSize,
        });
    });

    sdk.monitor.start(3000, 5000); // USS 3초, trajectory 5초 폴링

    // --- LS Bridge (Language Server 직접 접근) ---

    app.get('/api/cascades', async (_req: any, res: any) => {
        try {
            const cascades = await sdk.ls.listCascades();
            res.json({ cascades });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    app.post('/api/ls/send', async (req: any, res: any) => {
        try {
            const { cascadeId, text, model } = req.body;
            await sdk.ls.sendMessage({ cascadeId, text, model });
            res.json({ success: true });
        } catch (err: any) {
            res.status(500).json({ error: err.message });
        }
    });

    // --- 서버 시작 ---

    server.listen(BRIDGE_PORT, () => {
        output.appendLine(`[Bridge] 서버 시작: http://localhost:${BRIDGE_PORT}`);
        vscode.window.showInformationMessage(
            `Gravity Web Bridge 활성화 — localhost:${BRIDGE_PORT}`
        );
    });

    // 정리
    context.subscriptions.push(sdk);
    context.subscriptions.push({
        dispose: () => {
            server.close();
            sdk.monitor.stop();
            output.appendLine('[Bridge] 서버 종료');
        },
    });
}

export function deactivate() { }
