/**
 * WebSocket API for chunked streaming
 */

export class WebSocketAPI {
    constructor() {
        this.stompClient = null;
        this.currentQueryId = null;
        this.isConnected = false;
        this.onConnectionChange = null;
        this.handlers = {};
    }

    /**
     * WebSocket 연결
     */
    connect(wsUrl = null) {
        return new Promise((resolve, reject) => {
            if (this.isConnected) {
                resolve();
                return;
            }

            // WebSocket URL 결정: 파라미터 > 환경변수 > 현재 호스트
            const socketUrl = wsUrl ||
                             window.WS_ENDPOINT ||
                             `${window.location.protocol}//${window.location.hostname}:8090/ws-tracks`;

            console.log('Connecting to WebSocket:', socketUrl);

            const socket = new SockJS(socketUrl);
            this.stompClient = Stomp.over(socket);
            this.stompClient.debug = null; // 디버그 끄기

            this.stompClient.connect({}, (frame) => {
                this.isConnected = true;
                this.onConnectionChange?.(true);
                this.setupSubscriptions();
                resolve(frame);
            }, (error) => {
                this.isConnected = false;
                this.onConnectionChange?.(false);
                reject(error);
            });
        });
    }

    /**
     * WebSocket 연결 해제
     */
    disconnect() {
        return new Promise((resolve) => {
            if (this.stompClient && this.stompClient.connected) {
                this.stompClient.disconnect(() => {
                    this.isConnected = false;
                    this.onConnectionChange?.(false);
                    resolve();
                });
            } else {
                resolve();
            }
        });
    }

    /**
     * 구독 설정
     */
    setupSubscriptions() {
        if (!this.stompClient || !this.stompClient.connected) return;

        this.stompClient.subscribe('/user/queue/tracks/response', (message) => {
            this.handlers.response?.(JSON.parse(message.body));
        });

        this.stompClient.subscribe('/user/queue/tracks/status', (message) => {
            this.handlers.status?.(JSON.parse(message.body));
        });

        this.stompClient.subscribe('/user/queue/tracks/chunk', (message) => {
            this.handlers.chunk?.(message);
        });

        this.stompClient.subscribe('/user/queue/errors', (message) => {
            this.handlers.error?.(message.body);
        });
    }

    /**
     * 쿼리 시작
     */
    startQuery(queryParams) {
        if (!this.isConnected || !this.stompClient) {
            throw new Error('WebSocket이 연결되지 않았습니다');
        }

        const request = {
            startTime: queryParams.startTime,
            endTime: queryParams.endTime,
            viewport: queryParams.viewport,
            zoomLevel: queryParams.zoomLevel,
            chunkedMode: true,
            chunkSize: queryParams.chunkSize || 20000
        };

        this.stompClient.send('/app/tracks/query', {}, JSON.stringify(request));
    }

    /**
     * 쿼리 취소
     */
    cancelQuery() {
        if (this.currentQueryId && this.stompClient && this.stompClient.connected) {
            this.stompClient.send('/app/tracks/cancel/' + this.currentQueryId, {});
        }
    }

    /**
     * 이벤트 핸들러 설정
     */
    setHandlers(handlers) {
        this.handlers = { ...this.handlers, ...handlers };
    }

    /**
     * 연결 상태 핸들러 설정
     */
    onConnectionStatusChange(callback) {
        this.onConnectionChange = callback;
    }

    /**
     * 현재 연결 상태 반환
     */
    getConnectionStatus() {
        return this.isConnected;
    }

    /**
     * 현재 쿼리 ID 설정
     */
    setCurrentQueryId(queryId) {
        this.currentQueryId = queryId;
    }

    /**
     * 현재 쿼리 ID 반환
     */
    getCurrentQueryId() {
        return this.currentQueryId;
    }
}