/**
 * Chat Panel — 구조화된 메시지 렌더링 (Antigravity 스타일)
 */

class ChatPanel {
    constructor() {
        this.containerEl = document.getElementById('chatContainer');
        this.emptyEl = document.getElementById('emptyState');
        this.messagesEl = document.getElementById('chatMessages');
        this.inputEl = document.getElementById('chatInput');
        this.sendBtn = document.getElementById('sendBtn');
        this.sessionNameEl = document.getElementById('chatSessionName');
        this.sessionStatusEl = document.getElementById('chatSessionStatus');

        this.onSendMessage = null; // callback(text)
        this.onActionClick = null; // callback(button) - {label, x, y}
        this.activeSession = null;
        this._lastHash = '';

        this._setupInput();
    }

    _setupInput() {
        this.inputEl.addEventListener('input', () => {
            this.inputEl.style.height = 'auto';
            this.inputEl.style.height = Math.min(this.inputEl.scrollHeight, 120) + 'px';
        });

        this.inputEl.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                this._sendMessage();
            }
        });

        this.sendBtn.addEventListener('click', () => this._sendMessage());
    }

    _sendMessage() {
        const text = this.inputEl.value.trim();
        if (!text) return;
        if (this.onSendMessage) this.onSendMessage(text);
        this.inputEl.value = '';
        this.inputEl.style.height = 'auto';
    }

    showSession(session) {
        this.activeSession = session;
        this.emptyEl.style.display = 'none';
        this.containerEl.style.display = 'flex';
        this.sessionNameEl.textContent = session.name;
        this.sessionStatusEl.textContent = session.status === 'connected' ? '● 연결됨' : session.status;
        this.messagesEl.innerHTML = '<div class="chat-welcome"><p>채팅 데이터를 불러오는 중...</p></div>';
        this.inputEl.focus();
    }

    showEmpty() {
        this.activeSession = null;
        this.emptyEl.style.display = 'flex';
        this.containerEl.style.display = 'none';
    }

    /**
     * 구조화된 메시지 배열로 채팅 렌더링
     */
    updateChat(messages) {
        if (!messages || !Array.isArray(messages) || messages.length === 0) {
            this.messagesEl.innerHTML = `
                <div class="chat-welcome">
                    <p>⚠️ 채팅 데이터를 가져올 수 없습니다.<br>
                    Antigravity에서 채팅을 시작해주세요.</p>
                </div>`;
            return;
        }

        // 변경 감지 — 같은 내용이면 리렌더 안 함
        const hash = JSON.stringify(messages).length + ':' + messages.length;
        if (hash === this._lastHash) return;
        this._lastHash = hash;

        const wasAtBottom = this._isScrolledToBottom();
        const frag = document.createDocumentFragment();

        for (const msg of messages) {
            const el = this._renderMessage(msg);
            if (el) frag.appendChild(el);
        }

        this.messagesEl.innerHTML = '';
        this.messagesEl.appendChild(frag);

        if (wasAtBottom) this._scrollToBottom();
    }

    /**
     * 메시지 타입별 렌더러
     */
    _renderMessage(msg) {
        switch (msg.type) {
            case 'task': return this._renderTask(msg);
            case 'text': return this._renderText(msg);
            case 'thought': return this._renderThought(msg);
            case 'code': return this._renderCode(msg);
            case 'image': return this._renderImage(msg);
            case 'actions': return this._renderActions(msg);
            case 'user': return this._renderUser(msg);
            case 'status': return this._renderStatus(msg);
            default: return null;
        }
    }

    /**
     * 작업 카드 — Antigravity의 task boundary 카드
     */
    _renderTask(msg) {
        const card = document.createElement('div');
        card.className = 'msg-card';

        // 헤더
        const header = document.createElement('div');
        header.className = 'msg-card-header';

        const toggle = document.createElement('span');
        toggle.className = 'msg-toggle';
        toggle.textContent = msg.collapsed ? '▸' : '▾';

        const title = document.createElement('span');
        title.className = 'msg-card-title';
        title.textContent = msg.title || 'Task';

        header.appendChild(toggle);
        header.appendChild(title);

        // 요약
        if (msg.summary) {
            const summary = document.createElement('div');
            summary.className = 'msg-card-summary';
            summary.textContent = msg.summary;
            header.appendChild(summary);
        }

        card.appendChild(header);

        // 하위 항목
        if (msg.steps && msg.steps.length > 0) {
            const body = document.createElement('div');
            body.className = 'msg-card-body';
            if (msg.collapsed) body.style.display = 'none';

            for (const step of msg.steps) {
                const row = document.createElement('div');
                row.className = 'msg-step';

                const icon = document.createElement('span');
                icon.className = 'msg-step-icon';
                icon.textContent = step.icon || '•';

                const text = document.createElement('span');
                text.className = 'msg-step-text';
                text.textContent = step.text;

                row.appendChild(icon);
                row.appendChild(text);
                body.appendChild(row);
            }

            card.appendChild(body);

            // 접기/펴기 토글
            header.style.cursor = 'pointer';
            header.addEventListener('click', () => {
                const isHidden = body.style.display === 'none';
                body.style.display = isHidden ? '' : 'none';
                toggle.textContent = isHidden ? '▾' : '▸';
            });
        }

        // 카드 내부 액션 버튼 (Cancel, Review Changes 등)
        if (msg.actions && msg.actions.length > 0) {
            const actionsDiv = document.createElement('div');
            actionsDiv.className = 'msg-card-actions';

            for (const btn of msg.actions) {
                const el = document.createElement('button');
                el.className = 'msg-action-btn';
                el.textContent = btn.label;

                if (['Proceed', 'Approve', 'Accept', 'Yes', 'Allow'].some(k => btn.label.includes(k))) {
                    el.classList.add('msg-action-primary');
                }

                if (btn.x && btn.y) {
                    el.style.cursor = 'pointer';
                    el.addEventListener('click', (e) => {
                        e.stopPropagation(); // 카드 토글 방지
                        if (this.onActionClick) {
                            this.onActionClick({ label: btn.label, x: btn.x, y: btn.y });
                        }
                    });
                }

                actionsDiv.appendChild(el);
            }
            card.appendChild(actionsDiv);
        }

        return card;
    }

    /**
     * 텍스트 메시지 — 마크다운 렌더링
     */
    _renderText(msg) {
        const div = document.createElement('div');
        div.className = 'msg-text';

        if (msg.html) {
            // Antigravity에서 가져온 렌더링된 HTML (sanitized subset)
            div.innerHTML = this._sanitizeHtml(msg.html);
        } else {
            div.textContent = msg.content || '';
        }

        return div;
    }

    /**
     * Thought Process — 접을 수 있는 블록
     */
    _renderThought(msg) {
        const div = document.createElement('div');
        div.className = 'msg-thought';

        const btn = document.createElement('button');
        btn.className = 'msg-thought-btn';
        btn.innerHTML = `<span class="msg-thought-icon">💭</span> ${this._escapeHtml(msg.label || 'Thought')}`;

        div.appendChild(btn);
        return div;
    }

    /**
     * 코드 블록
     */
    _renderCode(msg) {
        const wrapper = document.createElement('div');
        wrapper.className = 'msg-code-block';

        if (msg.language) {
            const lang = document.createElement('div');
            lang.className = 'msg-code-lang';
            lang.textContent = msg.language;
            wrapper.appendChild(lang);
        }

        const pre = document.createElement('pre');
        const code = document.createElement('code');
        code.textContent = msg.content || '';
        pre.appendChild(code);
        wrapper.appendChild(pre);

        return wrapper;
    }

    /**
     * 이미지 — 크기 제한 적용
     */
    _renderImage(msg) {
        const div = document.createElement('div');
        div.className = 'msg-image';

        const img = document.createElement('img');
        img.src = msg.src;
        img.alt = msg.alt || '';
        img.loading = 'lazy';
        // 최대 크기 제한
        img.style.maxWidth = '320px';
        img.style.maxHeight = '200px';

        div.appendChild(img);
        return div;
    }

    /**
     * 액션 버튼 영역
     */
    _renderActions(msg) {
        const div = document.createElement('div');
        div.className = 'msg-actions';

        for (const btn of (msg.buttons || [])) {
            const el = document.createElement('button');
            el.className = 'msg-action-btn';
            el.textContent = btn.label || btn;

            // Proceed/Review 등 주요 액션은 강조
            const label = btn.label || btn;
            if (['Proceed', 'Approve', 'Accept', 'Yes', 'Allow'].some(k => label.includes(k))) {
                el.classList.add('msg-action-primary');
            }

            // 좌표가 있으면 클릭 가능
            if (btn.x && btn.y) {
                el.style.cursor = 'pointer';
                el.addEventListener('click', () => {
                    if (this.onActionClick) {
                        this.onActionClick({ label: btn.label, x: btn.x, y: btn.y });
                    }
                });
            }

            div.appendChild(el);
        }

        return div;
    }

    /**
     * HTML sanitize (간단히 위험 태그 제거)
     */
    _sanitizeHtml(html) {
        // script, iframe, object, embed, on* 속성 제거
        return html
            .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
            .replace(/<iframe\b[^>]*>[\s\S]*?<\/iframe>/gi, '')
            .replace(/<object\b[^>]*>[\s\S]*?<\/object>/gi, '')
            .replace(/<embed\b[^>]*>/gi, '')
            .replace(/\bon\w+\s*=\s*"[^"]*"/gi, '')
            .replace(/\bon\w+\s*=\s*'[^']*'/gi, '')
            // 이미지 크기 제한 인라인 추가
            .replace(/<img\b/gi, '<img style="max-width:320px;max-height:200px;border-radius:8px;" ');
    }

    _escapeHtml(str) {
        const div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

    updateSessionStatus(status) {
        if (!this.activeSession) return;
        const statusText = {
            connected: '● 연결됨',
            disconnected: '○ 연결 끊김',
            error: '⚠ 오류',
        };
        this.sessionStatusEl.textContent = statusText[status] || status;
    }

    _isScrolledToBottom() {
        const el = this.messagesEl;
        return el.scrollTop + el.clientHeight >= el.scrollHeight - 50;
    }

    _scrollToBottom() {
        this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
    }

    /**
     * 사용자 메시지 렌더링
     */
    _renderUser(msg) {
        const wrapper = document.createElement('div');
        wrapper.className = 'msg-user';
        wrapper.textContent = msg.content;
        return wrapper;
    }

    /**
     * 상태 표시 (Running, Generating 등)
     */
    _renderStatus(msg) {
        const wrapper = document.createElement('div');
        wrapper.className = 'msg-status';
        wrapper.textContent = msg.content;
        return wrapper;
    }
}
