<template>
<div class="message-hud">
    <!-- Boundary Headline: Agent name (Header) -->
    <div v-if="msg.type === 'headline' && msg.headlineKind !== 'new-session' && msg.position !== 'footer'" class="headline-container headline-header">
        <div class="headline-line"></div>
        <div class="headline-text">{{ msg.content }}</div>
        <div class="headline-line"></div>
    </div>

    <!-- Boundary Headline: Agent name (Footer) -->
    <div v-else-if="msg.type === 'headline' && msg.headlineKind !== 'new-session' && msg.position === 'footer'" class="headline-footer-wrapper">
        <div class="headline-container headline-footer">
            <div class="headline-line"></div>
            <div class="headline-text">{{ msg.content }}</div>
            <div class="headline-line"></div>
        </div>
    </div>

    <!-- Boundary Headline: New session (subheadline below agent name) -->
    <div v-else-if="msg.type === 'headline' && msg.headlineKind === 'new-session'" class="headline-new-session">
        <span class="new-session-text">{{ msg.content }}</span>
    </div>

    <!-- Grouped System Messages -->
    <div v-else-if="msg.role === 'system_group' || msg.messages" class="system-group">
        <div class="system-group-header" @click="isCollapsed = !isCollapsed">
            <Cog6ToothIcon class="system-group-icon-svg" />
            <span class="system-group-summary">{{ getSummary() }}</span>
            <ChevronDownIcon class="chevron" :class="{ open: !isCollapsed }" />
        </div>
        <div v-if="!isCollapsed" class="system-group-content" ref="groupContentEl">
            <template v-for="(subMsg, idx) in msg.messages" :key="idx">
                <div class="system-item">
                    <template v-if="isSqlResult(subMsg.content)">
                        <div class="sql-table-wrap">
                            <table class="sql-table">
                                <thead>
                                    <tr>
                                        <th v-for="(col, ci) in parseSqlTable(subMsg.content).headers" :key="ci">{{ col }}</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr v-for="(row, ri) in parseSqlTable(subMsg.content).rows" :key="ri">
                                        <td v-for="(cell, ci) in row" :key="ci">{{ cell }}</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </template>
                    <template v-else>
                        <div class="system-content raw-text" :title="subMsg.content">{{ subMsg.content }}</div>
                    </template>
                </div>
            </template>
        </div>
    </div>

    <!-- Fallback Single System Message -->
    <div v-else class="system-group">
        <div class="system-group-header">
            <InformationCircleIcon class="system-group-icon-svg" />
            <span class="system-group-summary">{{ msg.content }}</span>
        </div>
    </div>
</div>
</template>

<script setup lang="ts">
import { ref, onUpdated, nextTick } from 'vue';
import { Cog6ToothIcon, ChevronDownIcon, InformationCircleIcon } from '@heroicons/vue/20/solid';

const props = defineProps<{ msg: any }>();

const isCollapsed = ref(false);
const groupContentEl = ref<HTMLElement | null>(null);
onUpdated(() => {
    nextTick(() => {
        if (groupContentEl.value) {
            groupContentEl.value.scrollTop = groupContentEl.value.scrollHeight;
        }
    });
});

function isSqlResult(content: string): boolean {
    if (!content) return false;
    // Tool results start with "→ " — check after stripping that prefix
    const raw = content.startsWith('→ ') ? content.slice(2) : content;
    const lines = raw.split('\n').filter(l => l.trim());
    if (lines.length < 2) return false;
    // At least 2 lines with tabs = sql result
    return lines.filter(l => l.includes('\t')).length >= 2;
}

function parseSqlTable(content: string): { headers: string[], rows: string[][] } {
    const raw = content.startsWith('→ ') ? content.slice(2) : content;
    const lines = raw.split('\n').filter(l => l.trim());
    const [headerLine, ...dataLines] = lines;
    const headers = headerLine.split('\t');
    const rows = dataLines
        .filter(l => !l.startsWith('… ['))
        .map(l => l.split('\t'));
    return { headers, rows };
}

function getSummary() {
    const msgs = props.msg.messages;
    if (!msgs?.length) return 'Event';
    const toolNames: string[] = [];
    for (const m of msgs) {
        const raw = (m.content || '') as string;
        const match = raw.match(/^[^\w]*(\w+)/u);
        if (match) {
            const name = match[1];
            if (!['true', 'false', 'null', 'done', 'ok'].includes(name.toLowerCase())) {
                if (!toolNames.includes(name)) toolNames.push(name);
            }
        }
    }
    const callCount = msgs.length;
    const label = toolNames.length ? toolNames.join(' · ') : 'Event';
    return callCount === 1 ? label : `${label} · ${callCount}`;
}
</script>

<style scoped>
.message-hud { display: contents; }
.system-group { margin: -0.75rem 0; border-radius: 8px; background: var(--bg-dim); display: inline-block; max-width: 80%; align-self: flex-start; }
.system-group-header { padding: 0.4rem 0.8rem; display: flex; align-items: center; gap: 0.5rem; cursor: pointer; user-select: none; }
.system-group-header:hover { opacity: 0.8; }
.system-group-icon-svg { width: 13px; height: 13px; color: var(--text-dim); opacity: 0.5; flex-shrink: 0; }
.system-group-summary { flex: 1; font-weight: 500; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.system-group-content { padding: 0.25rem; display: flex; flex-direction: column; gap: 0.15rem; background: rgba(0, 0, 0, 0.1); max-height: 320px; overflow-y: auto; }
.system-item { padding: 0.15rem 0.5rem; border-radius: 4px; }
.headline-container { display: flex; align-items: center; width: 100%; }
.headline-container.headline-header { margin: 0.6rem 0 0.35rem; opacity: 1; }
.headline-container.headline-footer { margin: 0; opacity: 0.45; }
.headline-footer-wrapper { margin: 0; display: flex; flex-direction: column; align-items: center; }
.headline-text { padding: 0 0.75rem; font-weight: 700; color: var(--text-dim); white-space: nowrap; }
.headline-line { flex: 1; height: 1px; background: var(--border); }
.headline-container.headline-header .headline-line:first-child { max-width: 12px; background: var(--accent); }
.headline-container.headline-header .headline-text { color: var(--text); opacity: 0.7; }
.headline-new-session { display: flex; justify-content: center; margin: -0.5rem 0 0.75rem; opacity: 0.45; }
.new-session-text { font-weight: 500; color: var(--text-dim); }
.system-content { color: var(--text-dim); }
.system-content.raw-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; line-height: 1.4; }
.sql-table-wrap { overflow-x: auto; max-width: 600px; }
.sql-table { border-collapse: collapse; color: var(--text); white-space: nowrap; }
.sql-table th { background: var(--surface); color: var(--accent); font-weight: 600; padding: 3px 10px; text-align: left; border-bottom: 1px solid var(--border); }
.sql-table td { padding: 2px 10px; border-bottom: 1px solid var(--border); opacity: 0.85; }
.sql-table tr:last-child td { border-bottom: none; }
.sql-table tr:hover td { background: var(--bg-dim); opacity: 1; }
.chevron { width: 14px; height: 14px; color: var(--text-dim); opacity: 0.6; flex-shrink: 0; transition: transform 0.2s ease; transform: rotate(-90deg); }
.chevron.open { transform: rotate(0deg); }
</style>
