<template>
    <aside
        class="app-sidebar"
        :class="{ 'is-collapsed': !isOpen }"
    >
        <!-- Gradient shadow next to expanded sidebar -->
        <div class="sidebar-shadow" />
        <!-- Invisible full-screen click target to close -->
        <div class="sidebar-close-target" @click="collapse" />

        <!-- Top: [chevron] [logo + brand] -->
        <div class="sidebar-header">
            <button class="sidebar-toggle-btn" @click="toggle" :title="isOpen ? 'Collapse' : 'Expand'">
                <ChevronLeftIcon v-if="isOpen" class="sidebar-chevron-anim w-4 h-4" />
                <ChevronRightIcon v-else class="sidebar-chevron-anim w-4 h-4" />
            </button>
            <RouterLink v-if="isOpen" to="/" class="sidebar-brand" title="Home" @click="collapse">
                <img v-if="navLogo" :src="navLogo" class="sidebar-brand-logo" alt="Home" />
                <component v-else :is="THEME_ICONS[theme]" class="sidebar-brand-icon" />
                <span class="sidebar-brand-name">{{ THEME_NAMES[theme] }}</span>
            </RouterLink>
        </div>

        <!-- Top section: default agent + agents link + files (grows to fill space) -->
        <div v-if="isLoggedIn && isOpen" class="sidebar-top-section" :class="{ 'has-tree': sharedOpen || workspaceOpen }">
            <!-- Default agent (placeholder keeps layout stable before WS config) -->
            <div class="sidebar-home">
                <div
                    v-if="homeAgent"
                    class="sidebar-room"
                    :class="[`role-${homeAgent.role}`, { active: selectedAgent === homeAgent.id }]"
                    @click="handleModeClick(homeAgent.id, defaultMode(homeAgent))"
                    :title="'Chat with ' + homeAgent.name"
                >
                    <span class="sidebar-room-dot" :class="`dot-${homeAgent.role}`"></span>
                    <span class="sidebar-room-name">{{ homeAgent.name }}</span>
                </div>
                <div v-else class="sidebar-room sidebar-room-placeholder">
                    <span class="sidebar-room-dot"></span>
                </div>
            </div>

            <!-- Agents nav link -->
            <button class="sidebar-link" :class="{ active: route.name === 'agents' && !route.query.agent }" @click="goAgentsOverview">
                <ChatBubbleLeftRightIcon class="w-4 h-4" />
                <span>Agents</span>
            </button>

            <!-- Shared files -->
            <div v-if="viewerToken" class="sidebar-file-section" :class="{ 'is-open': sharedOpen }">
                <button class="sidebar-link sidebar-file-toggle" :class="{ active: sharedOpen }" @click="toggleFileSection('shared')">
                    <FolderIcon class="w-4 h-4" />
                    <span>Shared</span>
                </button>
                <OverlayScrollbarsComponent v-if="sharedOpen" class="sidebar-file-scroll" :options="scrollbarOptions" element="div">
                    <FileTree
                        :token="viewerToken"
                        :active-path="lastViewerPath"
                        :expand-to="lastViewerPath"
                        :roots="['shared']"
                        :hide-root="true"
                        :folders-only="true"
                        @select="openInViewer"
                    />
                </OverlayScrollbarsComponent>
            </div>

            <!-- Workspace files -->
            <div v-if="viewerToken" class="sidebar-file-section" :class="{ 'is-open': workspaceOpen }">
                <button class="sidebar-link sidebar-file-toggle" :class="{ active: workspaceOpen }" @click="toggleFileSection('workspace')">
                    <FolderOpenIcon class="w-4 h-4" />
                    <span>Workspace</span>
                </button>
                <OverlayScrollbarsComponent v-if="workspaceOpen" class="sidebar-file-scroll" :options="scrollbarOptions" element="div">
                    <FileTree
                        :token="viewerToken"
                        :active-path="lastViewerPath"
                        :expand-to="lastViewerPath"
                        :roots="[viewerWorkspaceRoot]"
                        :hide-root="true"
                        :folders-only="true"
                        @select="openInViewer"
                    />
                </OverlayScrollbarsComponent>
            </div>
        </div>
        <!-- Collapsed: top icons -->
        <div v-if="isLoggedIn && !isOpen" class="sidebar-collapsed-top">
            <div
                v-if="homeAgent"
                class="sidebar-room"
                :class="[`role-${homeAgent.role}`, { active: selectedAgent === homeAgent.id }]"
                @click="handleModeClick(homeAgent.id, defaultMode(homeAgent))"
                :title="homeAgent.name"
            >
                <span class="sidebar-room-dot" :class="`dot-${homeAgent.role}`"></span>
            </div>
            <button class="sidebar-link" :class="{ active: route.name === 'agents' && !route.query.agent }" title="Agents" @click="goAgentsOverview">
                <ChatBubbleLeftRightIcon class="w-4 h-4" />
            </button>
            <RouterLink :to="{ name: 'viewer', query: { path: 'shared' } }" class="sidebar-link" :class="{ active: route.name === 'viewer' && lastViewerPath.startsWith('shared') }" title="Shared files">
                <FolderIcon class="w-4 h-4" />
            </RouterLink>
            <RouterLink :to="{ name: 'viewer', query: { path: viewerWorkspaceRoot } }" class="sidebar-link" :class="{ active: route.name === 'viewer' && lastViewerPath.startsWith('workspace') }" title="Workspace files">
                <FolderOpenIcon class="w-4 h-4" />
            </RouterLink>
        </div>


        <!-- Spacer: push bottom section down -->
        <div v-if="isLoggedIn" class="sidebar-flex-spacer" />

        <!-- Panel backdrop: click outside to close any open panel -->
        <div v-if="anyPanelOpen" class="sidebar-panel-backdrop" @click="closeAllPanels" />

        <!-- Expanded: collapsible System section (no OverlayScrollbars — panels must escape overflow) -->
        <div v-if="isLoggedIn && isOpen" class="sidebar-system-section" :class="{ collapsed: !systemOpen }">
            <button class="sidebar-link sidebar-system-toggle" @click="systemOpen = !systemOpen; sessionStorage.setItem('sidebar_panel_system', String(systemOpen))">
                <ChevronDownIcon v-if="systemOpen" class="w-4 h-4" />
                <ChevronRightIcon v-else class="w-4 h-4" />
                <span>System</span>
            </button>
            <div v-if="systemOpen" class="sidebar-system-content">
                <!-- Connection -->
                <div class="sidebar-conn-wrap">
                    <button class="sidebar-link sidebar-conn-link" :class="{ active: connActive }" @click="toggleConnPanel">
                        <WifiIcon class="w-4 h-4" />
                        <span>{{ connLabel }}</span>
                    </button>
                    <div v-if="connPanelOpen" class="sidebar-panel">
                        <div class="sidebar-panel-header">Connection</div>
                        <div class="sidebar-panel-row"><span>WebSocket</span><span>{{ chatStore.connectionState }}</span></div>
                        <div class="sidebar-panel-row"><span>Channel</span><span>{{ chatStore.channelState }}</span></div>
                        <div class="sidebar-panel-row"><span>Agent</span><span>{{ selectedAgent || 'none' }}</span></div>
                        <div class="sidebar-panel-row"><span>Mode</span><span>{{ selectedMode }}</span></div>
                    </div>
                </div>

                <!-- Takeover -->
                <div class="sidebar-takeover-wrap" :class="{ active: !!takeoverToken }">
                    <button class="sidebar-link" :class="{ active: !!takeoverToken }" @click="toggleTakeoverPanel">
                        <SignalIcon class="w-4 h-4" />
                        <span>Takeover</span>
                    </button>
                    <div v-if="takeoverPanelOpen && takeoverToken" class="sidebar-panel">
                        <div class="sidebar-panel-header">Takeover Token</div>
                        <div class="sidebar-panel-token" @click="copyToken" :title="tokenCopied ? 'Copied!' : 'Click to copy'">
                            <code>{{ takeoverToken }}</code>
                            <span v-if="tokenCopied" class="sidebar-panel-copied">Copied!</span>
                        </div>
                        <div class="sidebar-panel-row">
                            <span>Capture</span>
                            <span :style="{ color: captureActive ? 'var(--success, #22c55e)' : 'var(--text-dim)' }">{{ captureActive ? 'ON' : 'OFF' }}</span>
                        </div>
                        <button class="sidebar-panel-item" @click="toggleCapture">
                            {{ captureActive ? 'Disable Capture' : 'Enable Capture' }}
                        </button>
                        <button class="sidebar-panel-item" @click="revokeAndClose">Revoke</button>
                    </div>
                </div>

                <!-- Dev -->
                <RouterLink to="/dev" class="sidebar-link" :class="{ active: route.name === 'dev' }" @click="collapse">
                    <CodeBracketIcon class="w-4 h-4" />
                    <span>dev</span>
                </RouterLink>

                <!-- Version -->
                <div class="sidebar-version-wrap">
                    <button class="sidebar-link sidebar-version-link" @click="toggleVersionPanel">
                        <span class="sidebar-version-text">{{ versionShort }}</span>
                    </button>
                    <div v-if="versionPanelOpen" class="sidebar-panel sidebar-version-panel">
                        <div class="sidebar-panel-header">Version</div>
                        <div class="sidebar-panel-row"><span>Frontend</span><span>{{ version }}</span></div>
                        <div class="sidebar-panel-row"><span>Backend</span><span>{{ chatStore.beVersion || '...' }}</span></div>
                        <div class="sidebar-panel-row"><span>Env</span><span>{{ envLabel }}</span></div>
                        <button class="sidebar-panel-item" @click="copyVersionDetails">
                            {{ versionCopied ? '✓ Copied' : 'Copy details' }}
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Collapsed: bottom icons -->
        <div v-if="isLoggedIn && !isOpen" class="sidebar-bottom-section">
            <div class="sidebar-conn-wrap">
                <button class="sidebar-link sidebar-conn-link" :class="{ active: connActive }" @click="toggleConnPanel" :title="connLabel">
                    <WifiIcon class="w-4 h-4" />
                </button>
                <div v-if="connPanelOpen" class="sidebar-panel">
                    <div class="sidebar-panel-header">Connection</div>
                    <div class="sidebar-panel-row"><span>WebSocket</span><span>{{ chatStore.connectionState }}</span></div>
                    <div class="sidebar-panel-row"><span>Channel</span><span>{{ chatStore.channelState }}</span></div>
                    <div class="sidebar-panel-row"><span>Agent</span><span>{{ selectedAgent || 'none' }}</span></div>
                    <div class="sidebar-panel-row"><span>Mode</span><span>{{ selectedMode }}</span></div>
                </div>
            </div>
            <div class="sidebar-takeover-wrap" :class="{ active: !!takeoverToken }">
                <button class="sidebar-link" :class="{ active: !!takeoverToken }" @click="toggleTakeoverPanel" title="Takeover">
                    <SignalIcon class="w-4 h-4" />
                </button>
                <div v-if="takeoverPanelOpen && takeoverToken" class="sidebar-panel">
                    <div class="sidebar-panel-header">Takeover Token</div>
                    <div class="sidebar-panel-token" @click="copyToken" :title="tokenCopied ? 'Copied!' : 'Click to copy'">
                        <code>{{ takeoverToken }}</code>
                        <span v-if="tokenCopied" class="sidebar-panel-copied">Copied!</span>
                    </div>
                    <div class="sidebar-panel-row">
                        <span>Capture</span>
                        <span :style="{ color: captureActive ? 'var(--success, #22c55e)' : 'var(--text-dim)' }">{{ captureActive ? 'ON' : 'OFF' }}</span>
                    </div>
                    <button class="sidebar-panel-item" @click="toggleCapture">
                        {{ captureActive ? 'Disable Capture' : 'Enable Capture' }}
                    </button>
                    <button class="sidebar-panel-item" @click="revokeAndClose">Revoke</button>
                </div>
            </div>
            <RouterLink to="/dev" class="sidebar-link" :class="{ active: route.name === 'dev' }" title="Dev" @click="collapse">
                <CodeBracketIcon class="w-4 h-4" />
            </RouterLink>
            <div class="sidebar-version-wrap">
                <button class="sidebar-link sidebar-version-link" @click="toggleVersionPanel" :title="versionShort">
                    <span class="sidebar-version-text">{{ versionShort }}</span>
                </button>
                <div v-if="versionPanelOpen" class="sidebar-panel sidebar-version-panel">
                    <div class="sidebar-panel-header">Version</div>
                    <div class="sidebar-panel-row"><span>Frontend</span><span>{{ version }}</span></div>
                    <div class="sidebar-panel-row"><span>Backend</span><span>{{ chatStore.beVersion || '...' }}</span></div>
                    <div class="sidebar-panel-row"><span>Env</span><span>{{ envLabel }}</span></div>
                    <button class="sidebar-panel-item" @click="copyVersionDetails">
                        {{ versionCopied ? '✓ Copied' : 'Copy details' }}
                    </button>
                </div>
            </div>
        </div>

        <!-- User (always unified) -->
        <div class="sidebar-bottom">
            <template v-if="isLoggedIn">
                <div class="sidebar-user-wrap" :class="{ open: userMenuOpen }">
                    <button
                        class="sidebar-user-btn"
                        @click="toggleUserMenu"
                        :title="isOpen ? '' : currentUser"
                    >
                        <UserCircleIcon class="w-4 h-4" />
                        <span v-if="isOpen" class="sidebar-user-name">{{ currentUser }}</span>
                    </button>
                    <div v-if="userMenuOpen" class="sidebar-user-menu">
                        <div class="sidebar-user-menu-header">{{ currentUser }}</div>
                        <button class="sidebar-user-menu-item" @click="handleLogout">Logout</button>
                    </div>
                </div>
            </template>
            <RouterLink v-else to="/login" class="sidebar-link" :title="isOpen ? '' : 'Sign in'">
                <ArrowRightEndOnRectangleIcon class="w-4 h-4" />
                <span v-if="isOpen">Sign in</span>
            </RouterLink>
        </div>
    </aside>
</template>

<script setup lang="ts">
defineOptions({ name: 'AppSidebar' });
import { ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import {
    ChevronDownIcon,
    ChevronLeftIcon,
    ChevronRightIcon,
    FolderIcon,
    FolderOpenIcon,
    CodeBracketIcon,

    UserCircleIcon,
    ArrowRightEndOnRectangleIcon,
    LockClosedIcon,
    UserGroupIcon,
    SignalIcon,
    WifiIcon,
    ChatBubbleLeftRightIcon,
} from '@heroicons/vue/20/solid';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
import { scrollbarOptions } from '../composables/useScrollbar';
import { THEME_ICONS, THEME_LOGOS, THEME_NAMES, useTheme } from '../composables/useTheme';
import { ws, auth, agents, takeover, lastViewerPath, useViewerStore } from '../store';
import { useChatStore } from '../store/chat';
import FileTree from './FileTree.vue';

const takeoverToken = takeover.token;
const captureActive = takeover.capture.isActive;
const takeoverPanelOpen = ref(false);
const tokenCopied = ref(false);

async function toggleCapture() {
    if (captureActive.value) {
        takeover.capture.disable();
    } else {
        await takeover.capture.enable();
    }
}

function copyToken() {
    if (!takeoverToken.value) return;
    navigator.clipboard.writeText(takeoverToken.value);
    tokenCopied.value = true;
    setTimeout(() => { tokenCopied.value = false; }, 1500);
}

const systemOpen = ref(sessionStorage.getItem('sidebar_panel_system') === 'true');
const connPanelOpen = ref(false);
const anyPanelOpen = computed(() => takeoverPanelOpen.value || userMenuOpen.value || versionPanelOpen.value || connPanelOpen.value);

function closeAllPanels() {
    takeoverPanelOpen.value = false;
    userMenuOpen.value = false;
    versionPanelOpen.value = false;
    connPanelOpen.value = false;
}

function toggleConnPanel() {
    const opening = !connPanelOpen.value;
    closeAllPanels();
    if (opening) connPanelOpen.value = true;
}

function toggleTakeoverPanel() {
    if (!takeoverToken.value) { router.push('/dev'); return; }
    const opening = !takeoverPanelOpen.value;
    closeAllPanels();
    if (opening) takeoverPanelOpen.value = true;
}

function toggleUserMenu() {
    const opening = !userMenuOpen.value;
    closeAllPanels();
    if (opening) userMenuOpen.value = true;
}

function revokeAndClose() {
    takeover.revoke();
    closeAllPanels();
}
const homeAgent = computed(() => allAgents.value.find(a => a.id === defaultAgent.value));
const allFilteredSorted = computed(() =>
    filteredAgents.value
        .filter(a => a.id !== defaultAgent.value)
        .sort((a, b) => a.name.localeCompare(b.name))
);

const chatStore = useChatStore();

// Viewer file tree in sidebar
const viewerStore = useViewerStore();
const viewerToken = computed(() => viewerStore.fstoken);
const viewerRoots = computed(() => viewerStore.roots);

const sharedOpen = ref(lastViewerPath.value.startsWith('shared'));
const workspaceOpen = ref(lastViewerPath.value.startsWith('workspace'));

function toggleFileSection(section: 'shared' | 'workspace') {
    const root = section === 'shared' ? 'shared' : viewerWorkspaceRoot.value;
    if (section === 'shared') {
        sharedOpen.value = !sharedOpen.value;
        if (sharedOpen.value) { workspaceOpen.value = false; openInViewer(root); }
    } else {
        workspaceOpen.value = !workspaceOpen.value;
        if (workspaceOpen.value) { sharedOpen.value = false; openInViewer(root); }
    }
}

const viewerWorkspaceRoot = computed(() => {
    const ws = viewerRoots.value.find(r => r.startsWith('workspace'));
    return ws || 'workspace-titan';
});

function openInViewer(path: string) {
    lastViewerPath.value = path;
    localStorage.setItem('viewer_last_path', path);
    router.push({ name: 'viewer', query: { path } });
}

// Version display
import { useUI } from '../composables/ui';
const { version } = useUI(ws.status);
const versionShort = version.split('-')[0];
const envLabel = import.meta.env.PROD ? 'prod' : 'dev';
const versionPanelOpen = ref(false);
const versionCopied = ref(false);

function toggleVersionPanel() {
    const opening = !versionPanelOpen.value;
    closeAllPanels();
    if (opening) versionPanelOpen.value = true;
}

function copyVersionDetails() {
    const details = `env: ${envLabel}\nfe: ${version}\nbe: ${chatStore.beVersion || 'unknown'}\nua: ${navigator.userAgent}`;
    navigator.clipboard.writeText(details);
    versionCopied.value = true;
    setTimeout(() => { versionCopied.value = false; }, 2000);
}

function stateToIndicator(state: string | null) {
    switch (state) {
        case 'AGENT_RUNNING':    return { icon: '⚙️', cls: 'ch-running' };
        case 'FRESH':            return { icon: '✨', cls: 'ch-fresh' };
        case 'READY':            return { icon: '●', cls: 'ch-ready' };
        case 'HANDOVER_PENDING': return { icon: '📝', cls: 'ch-handover' };
        case 'HANDOVER_DONE':    return { icon: '✅', cls: 'ch-handover' };
        case 'RESETTING':        return { icon: '🔄', cls: 'ch-resetting' };
        case 'NO_SESSION':       return { icon: '○', cls: 'ch-nosession' };
        default:                 return { icon: '·', cls: 'ch-none' };
    }
}

// For selected agent: use live WS state from chat store
const selectedIndicator = computed(() => stateToIndicator(chatStore.channelState));

// For any agent: get from HTTP-polled channel states
function agentIndicator(agentId: string, mode: 'private' | 'public' = 'private') {
    // For selected agent + mode: use live WS state only when SYNCED
    if (agentId === selectedAgent.value && mode === selectedMode.value && chatStore.connectionState === 'SYNCED') {
        return selectedIndicator.value;
    }
    const info = agents.getChannelState(agentId, mode);
    return info ? stateToIndicator(info.state) : stateToIndicator(null);
}

const connLabel = computed(() => {
    switch (chatStore.connectionState) {
        case 'CONNECTING':      return 'Connecting...';
        case 'LOADING_HISTORY': return 'Loading...';
        case 'SWITCHING':       return 'Switching...';
        case 'SYNCED':          return 'Connected';
        default:                return '';
    }
});
const connActive = computed(() => chatStore.connectionState === 'SYNCED');

const emit = defineEmits<{ logout: [] }>();

const route = useRoute();
const router = useRouter();
const { theme } = useTheme();
const navLogo = computed(() => THEME_LOGOS[theme.value]);

const { isLoggedIn } = auth;
const { currentUser, send } = ws;
const { filteredAgents, selectedAgent, selectedMode, defaultAgent, allAgents } = agents;

function defaultMode(agent: any): string {
    if (agent.role === 'owner') return 'private';
    if (agent.modes?.includes('public')) return 'public';
    return 'private';
}

function extraMode(agent: any): string | null {
    const def = defaultMode(agent);
    const other = def === 'private' ? 'public' : 'private';
    return agent.modes?.includes(other) ? other : null;
}

function activeMode(agent: any): string | null {
    if (selectedAgent.value !== agent.id) return null;
    return selectedMode.value;
}

const SEGMENTS = ['personal', 'common', 'private', 'public'] as const;

const visibleSegments = computed(() =>
    SEGMENTS
        .map(key => ({
            key,
            agents: filteredAgents.value
                .filter(a => (a.segment ?? 'utility') === key && a.id !== defaultAgent.value)
                .sort((a, b) => a.name.localeCompare(b.name)),
        }))
        .filter(s => s.agents.length > 0)
);

const isMobile = window.innerWidth <= 480;
const isLarge = window.innerWidth >= 1024;
const isOpen = ref(isMobile ? false : isLarge ? true : localStorage.getItem('sidebar_open') !== 'false');
const userMenuOpen = ref(false);

// Auto-collapse when crossing from lg → md
const lgQuery = window.matchMedia('(min-width: 1024px)');
lgQuery.addEventListener('change', (e) => {
    if (e.matches && !isOpen.value) {
        isOpen.value = true;
        localStorage.setItem('sidebar_open', 'true');
    } else if (!e.matches && isOpen.value) {
        isOpen.value = false;
        localStorage.setItem('sidebar_open', 'false');
    }
});

function toggle() {
    isOpen.value = !isOpen.value;
    localStorage.setItem('sidebar_open', String(isOpen.value));
}

function collapse() {
    if (window.innerWidth >= 1024) return;  // large screens: stay open
    isOpen.value = false;
    localStorage.setItem('sidebar_open', 'false');
}

function goAgentsOverview() {
    collapse();
    router.push({ name: 'agents', query: {} });
}



function handleModeClick(agentId: string, mode: string) {
    collapse();
    const sameAgent = selectedAgent.value === agentId && selectedMode.value === mode;
    // Already on this agent+mode on agents view — nothing to do
    if (sameAgent && route.name === 'agents') return;
    // Same agent but on a different view — just navigate back, don't re-switch
    if (sameAgent) {
        router.push({ name: 'agents', query: { agent: agentId, mode } });
        return;
    }
    // Different agent — full switch
    selectedAgent.value = agentId;
    selectedMode.value = mode as 'private' | 'public';
    sessionStorage.setItem('agent', agentId);
    sessionStorage.setItem('agent_mode', mode);
    if (ws.connected.value) {
        ws.switchAgent(agentId, mode);
    } else {
        ws.connect(selectedAgent, auth.isLoggedIn, auth.loginError, selectedMode);
    }
    router.push({ name: 'agents', query: { agent: agentId, mode } });
}

function handleLogout() {
    userMenuOpen.value = false;
    emit('logout');
}
</script>
