/**
 * Bridge Client — Antigravity Extension Bridge (localhost:9850)와 통신
 * 
 * Extension이 설치된 Antigravity에서 제공하는 REST API + WebSocket을 통해
 * 대화 목록, 메시지 전송, 승인/거절 등을 수행합니다.
 */

const http = require('http');
const WebSocket = require('ws');

const BRIDGE_HOST = 'localhost';
const BRIDGE_PORT = 9850;
const BRIDGE_BASE = `http://${BRIDGE_HOST}:${BRIDGE_PORT}`;

class BridgeClient {
    constructor() {
        this.ws = null;
        this.connected = false;
        this.listeners = new Map();
        this.reconnectTimer = null;
    }

    /**
     * Bridge 서버 상태 확인
     */
    async checkHealth() {
        try {
            const data = await this._get('/api/health');
            return { available: true, ...data };
        } catch {
            return { available: false };
        }
    }

    /**
     * 대화 목록 (제목, stepCount, 수정일시)
     */
    async getSessions() {
        return this._get('/api/sessions');
    }

    /**
     * 전체 Cascade 데이터 (대화 내용, 스텝, notify_user 등)
     */
    async getCascades() {
        return this._get('/api/cascades');
    }

    /**
     * 메시지 전송
     */
    async sendMessage(message, sessionId) {
        return this._post('/api/send', { message, sessionId });
    }

    /**
     * 코드 편집 승인
     */
    async acceptStep() {
        return this._post('/api/accept', {});
    }

    /**
     * 코드 편집 거절
     */
    async rejectStep() {
        return this._post('/api/reject', {});
    }

    /**
     * 터미널 명령 승인
     */
    async acceptTerminal() {
        return this._post('/api/accept-terminal', {});
    }

    /**
     * 에이전트 설정 조회
     */
    async getPreferences() {
        return this._get('/api/preferences');
    }

    /**
     * WebSocket 실시간 이벤트 연결
     */
    connectWs(onMessage) {
        if (this.ws) {
            this.ws.close();
        }

        try {
            this.ws = new WebSocket(`ws://${BRIDGE_HOST}:${BRIDGE_PORT}/ws`);
        } catch (err) {
            console.log(`[Bridge WS] 연결 실패: ${err.message}`);
            this._scheduleReconnect(onMessage);
            return;
        }

        this.ws.on('open', () => {
            this.connected = true;
            console.log('[Bridge WS] 연결됨');
        });

        this.ws.on('message', (data) => {
            try {
                const msg = JSON.parse(data.toString());
                onMessage(msg);
            } catch { }
        });

        this.ws.on('close', () => {
            this.connected = false;
            console.log('[Bridge WS] 연결 해제');
            this._scheduleReconnect(onMessage);
        });

        this.ws.on('error', () => {
            this.connected = false;
        });
    }

    _scheduleReconnect(onMessage) {
        if (this.reconnectTimer) return;
        this.reconnectTimer = setTimeout(() => {
            this.reconnectTimer = null;
            console.log('[Bridge WS] 재연결 시도...');
            this.connectWs(onMessage);
        }, 5000);
    }

    disconnect() {
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        if (this.ws) {
            this.ws.close();
            this.ws = null;
        }
    }

    // --- HTTP 헬퍼 ---

    _get(path) {
        return new Promise((resolve, reject) => {
            http.get(`${BRIDGE_BASE}${path}`, (res) => {
                let body = '';
                res.on('data', (c) => body += c);
                res.on('end', () => {
                    try { resolve(JSON.parse(body)); }
                    catch { reject(new Error('Invalid JSON')); }
                });
            }).on('error', reject);
        });
    }

    _post(path, data) {
        return new Promise((resolve, reject) => {
            const body = JSON.stringify(data);
            const req = http.request(`${BRIDGE_BASE}${path}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(body),
                },
            }, (res) => {
                let resBody = '';
                res.on('data', (c) => resBody += c);
                res.on('end', () => {
                    try { resolve(JSON.parse(resBody)); }
                    catch { reject(new Error('Invalid JSON')); }
                });
            });
            req.on('error', reject);
            req.write(body);
            req.end();
        });
    }
}

module.exports = BridgeClient;
