/**
 * sidebar.mjs — AI-Do v4.0 sidebar component
 * Persona card, navigation links, agent status indicator, collapse toggle.
 */

import store from '../store.mjs';
import { $, createElement, icon, empty } from '../utils/dom.mjs';
import { openPersonaEditor } from './persona-editor.mjs';
import { openVoiceMode } from './voice-mode.mjs';
import { createAvatar } from './avatar.mjs';
import api from '../api.mjs';
import eventBus, { EVENTS } from '../event-bus.mjs';
import { openPreview } from './preview-panel.mjs';

// ── DOM references ──
let contentEl = null;
let personaAvatarEl = null;
let personaNameEl = null;
let personaGreetingEl = null;
let personaStatusEl = null;
let agentStatusEl = null;
let recentFilesEl = null;
let navItems = {};

// ── Recent files state ──
let recentFilesTimer = null;

// ── Nav link definitions ──
const NAV_LINKS = [
  { view: 'chat',       icon: 'chat',       label: 'Chat' },
  { view: 'activity',   icon: 'activity',   label: 'Activity' },
  { view: 'skills',     icon: 'skills',     label: 'Skills' },
  { view: 'knowledge',  icon: 'knowledge',  label: 'Memory' },
  { view: 'workspaces', icon: 'workspace',  label: 'Files' },
  { view: 'settings',   icon: 'settings',   label: 'Settings' }
];

// ── Status display map ──
const STATUS_LABELS = {
  running: 'Running',
  paused: 'Paused',
  idle: 'Idle',
  busy: 'Busy',
  unknown: 'Unknown'
};

// ──────────────────────────────────────
// Public init
// ──────────────────────────────────────

export function init() {
  contentEl = $('.sidebar-content');
  if (!contentEl) {
    console.warn('[sidebar] .sidebar-content not found');
    return;
  }

  buildDOM();
  subscribeToStore();
  setupToggle();

  // Set initial state from store
  const state = store.getState();
  updatePersona(state.persona);
  updateAgentStatus(state.agent.status);
  updateActiveNav(state.ui.currentView);
  updateCollapsed(state.ui.sidebarCollapsed);

  // Recent files: initial load + periodic refresh
  refreshRecentFiles();
  recentFilesTimer = setInterval(refreshRecentFiles, 30000);

  // Refresh file list when a skill completes (likely produced a file)
  // Small delay to ensure the file is written to disk before we list.
  eventBus.on(EVENTS.SKILL_COMPLETE, () => {
    setTimeout(refreshRecentFiles, 500);
  });

  // Also refresh on activity events that may indicate new files
  eventBus.on(EVENTS.ACTIVITY_EVENT, (data) => {
    const kind = data?.kind || data?.type;
    if (kind === 'skill' || kind === 'file') {
      setTimeout(refreshRecentFiles, 500);
    }
    // Check for file creation mentions in content
    const content = String(data?.content || '').toLowerCase();
    if (content.includes('created') || content.includes('wrote') || content.includes('saved')) {
      setTimeout(refreshRecentFiles, 1000);
    }
  });

  // Refresh when agent sends a chat message that mentions creating a file
  eventBus.on(EVENTS.CHAT_MESSAGE, (data) => {
    if (data?.source !== 'agent' && data?.role !== 'agent') return;
    const content = String(data?.content || '').toLowerCase();
    if (content.includes('created') || content.includes('.html') || content.includes('.js') || content.includes('.md') || content.includes('workspace')) {
      setTimeout(refreshRecentFiles, 1000);
    }
  });
}

// ──────────────────────────────────────
// DOM construction
// ──────────────────────────────────────

function buildDOM() {
  empty(contentEl);

  // Persona card
  const personaCard = buildPersonaCard();
  contentEl.appendChild(personaCard);

  // Navigation
  const nav = buildNav();
  contentEl.appendChild(nav);

  // Recent files
  recentFilesEl = buildRecentFiles();
  contentEl.appendChild(recentFilesEl);

  // Agent status at bottom
  agentStatusEl = buildAgentStatus();
  contentEl.appendChild(agentStatusEl);
}

function buildPersonaCard() {
  const state = store.getState();
  const { persona, agent } = state;

  const card = createElement('div', { className: 'persona-card' });

  // Avatar (inline SVG component) — click to open voice mode
  personaAvatarEl = createAvatar('sidebar');
  personaAvatarEl.classList.add('persona-card-avatar', `status-${agent.status}`);
  personaAvatarEl.style.cursor = 'pointer';
  personaAvatarEl.title = 'Click for voice mode';
  personaAvatarEl.addEventListener('click', (e) => {
    e.stopPropagation();
    openVoiceMode();
  });
  card.appendChild(personaAvatarEl);

  // Name
  personaNameEl = createElement('h3', { className: 'persona-card-name' }, [
    persona.name || 'AI-Do'
  ]);
  card.appendChild(personaNameEl);

  // Greeting
  personaGreetingEl = createElement('p', { className: 'persona-card-greeting' }, [
    persona.greeting || 'Hello! I\'m AI-Do, your personal AI.'
  ]);
  card.appendChild(personaGreetingEl);

  // Status badge
  personaStatusEl = createElement('div', {
    className: `persona-card-status status-${agent.status}`
  }, [
    createElement('span', { className: 'status-dot' }),
    STATUS_LABELS[agent.status] || 'Unknown'
  ]);
  card.appendChild(personaStatusEl);

  // Edit button (pencil icon, shown on hover)
  const editBtn = createElement('button', {
    className: 'persona-card-edit',
    'aria-label': 'Edit persona'
  });
  editBtn.appendChild(icon('edit', { size: 14 }));
  editBtn.addEventListener('click', (e) => {
    e.stopPropagation();
    openPersonaEditor();
  });
  card.appendChild(editBtn);

  return card;
}

function buildNav() {
  const nav = createElement('nav', { className: 'sidebar-nav' });
  navItems = {};

  for (const link of NAV_LINKS) {
    const item = createElement('div', {
      className: 'sidebar-nav-item',
      dataset: { view: link.view },
      'aria-label': link.label
    });

    item.appendChild(icon(link.icon, { size: 20 }));

    const label = createElement('span', { className: 'nav-label' }, [link.label]);
    item.appendChild(label);

    item.addEventListener('click', () => {
      // Expand sidebar if collapsed so the user can see the view
      if (store.getState().ui.sidebarCollapsed) {
        store.dispatch('TOGGLE_SIDEBAR');
      }

      store.dispatch('SET_VIEW', link.view);

      // Close mobile sidebar
      const sidebar = $('.sidebar');
      if (sidebar) sidebar.classList.remove('open');

      const backdrop = $('.panel-backdrop');
      if (backdrop) backdrop.classList.remove('active');
    });

    navItems[link.view] = item;
    nav.appendChild(item);
  }

  return nav;
}

function buildRecentFiles() {
  const section = createElement('div', { className: 'sidebar-files' });

  const header = createElement('div', { className: 'sidebar-files-header' });
  header.appendChild(icon('file', { size: 14 }));
  header.appendChild(createElement('span', {}, ['Recent Files']));
  section.appendChild(header);

  const list = createElement('div', { className: 'sidebar-files-list' });
  const emptyMsg = createElement('div', { className: 'sidebar-files-empty' }, ['No files yet']);
  list.appendChild(emptyMsg);
  section.appendChild(list);

  return section;
}

function formatRelativeTime(isoString) {
  const diff = Date.now() - new Date(isoString).getTime();
  const seconds = Math.floor(diff / 1000);
  if (seconds < 60) return 'just now';
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  return `${days}d ago`;
}

async function refreshRecentFiles() {
  if (!recentFilesEl) return;
  const list = $('.sidebar-files-list', recentFilesEl);
  if (!list) return;

  try {
    const files = await api.getWorkspaceFiles();
    const recent = (files || []).slice(0, 5);

    empty(list);

    if (recent.length === 0) {
      list.appendChild(createElement('div', { className: 'sidebar-files-empty' }, ['No files yet']));
      return;
    }

    for (const file of recent) {
      const item = createElement('div', {
        className: 'sidebar-file-item',
        'aria-label': file.name,
        style: { cursor: 'pointer' }
      });

      item.addEventListener('click', () => {
        const path = `/workspace-files/${encodeURIComponent(file.name)}`;
        openPreview(path);
        store.dispatch('SET_VIEW', 'chat');
      });

      const nameEl = createElement('span', { className: 'sidebar-file-name' }, [file.name]);
      item.appendChild(nameEl);

      const timeEl = createElement('span', { className: 'sidebar-file-time' }, [
        formatRelativeTime(file.modified)
      ]);
      item.appendChild(timeEl);

      list.appendChild(item);
    }
  } catch (err) {
    console.warn('[sidebar] Failed to load recent files:', err);
  }
}

function buildAgentStatus() {
  const state = store.getState();
  const status = state.agent.status;

  const el = createElement('div', {
    className: `sidebar-agent-status status-${status}`
  });

  const dot = createElement('span', { className: 'status-dot' });
  el.appendChild(dot);

  const text = createElement('span', { className: 'status-text' }, [
    `Agent: ${STATUS_LABELS[status] || 'Unknown'}`
  ]);
  el.appendChild(text);

  // Help button
  const helpBtn = createElement('button', {
    className: 'sidebar-help-btn',
    'aria-label': 'Open help'
  }, ['?']);
  helpBtn.addEventListener('click', async () => {
    const { showTopicPicker } = await import('./help.mjs');
    showTopicPicker();
  });
  el.appendChild(helpBtn);

  return el;
}

// ──────────────────────────────────────
// Store subscriptions
// ──────────────────────────────────────

function subscribeToStore() {
  // Persona changes
  store.subscribe(
    (s) => s.persona,
    (persona) => updatePersona(persona)
  );

  // Agent status
  store.subscribe(
    (s) => s.agent.status,
    (status) => updateAgentStatus(status)
  );

  // Current view (active nav link)
  store.subscribe(
    (s) => s.ui.currentView,
    (view) => updateActiveNav(view)
  );

  // Sidebar collapsed
  store.subscribe(
    (s) => s.ui.sidebarCollapsed,
    (collapsed) => updateCollapsed(collapsed)
  );
}

// ──────────────────────────────────────
// Update functions
// ──────────────────────────────────────

function updatePersona(persona) {
  if (personaNameEl) {
    personaNameEl.textContent = persona.name || 'AI-Do';
  }
  if (personaGreetingEl) {
    personaGreetingEl.textContent = persona.greeting || 'Hello! I\'m AI-Do, your personal AI.';
  }

  // Update header title
  const titleEl = $('.sidebar-title');
  if (titleEl) {
    titleEl.textContent = persona.name || 'AI-Do';
  }
}

function updateAgentStatus(status) {
  const validStatus = STATUS_LABELS[status] ? status : 'unknown';

  // Persona card avatar ring
  if (personaAvatarEl) {
    // Preserve avatar-component classes, update status
    personaAvatarEl.className = `avatar-component avatar-component--sidebar persona-card-avatar status-${validStatus}`;
  }

  // Persona card status badge
  if (personaStatusEl) {
    personaStatusEl.className = `persona-card-status status-${validStatus}`;
    empty(personaStatusEl);
    personaStatusEl.appendChild(createElement('span', { className: 'status-dot' }));
    personaStatusEl.appendChild(document.createTextNode(STATUS_LABELS[validStatus] || 'Unknown'));
  }

  // Bottom agent status indicator
  if (agentStatusEl) {
    agentStatusEl.className = `sidebar-agent-status status-${validStatus}`;
    const textEl = $('.status-text', agentStatusEl);
    if (textEl) {
      textEl.textContent = `Agent: ${STATUS_LABELS[validStatus] || 'Unknown'}`;
    }
  }
}

function updateActiveNav(view) {
  for (const [key, item] of Object.entries(navItems)) {
    if (key === view) {
      item.classList.add('active');
    } else {
      item.classList.remove('active');
    }
  }
}

function updateCollapsed(collapsed) {
  const app = $('#app');
  if (!app) return;

  if (collapsed) {
    app.classList.add('sidebar-collapsed');
  } else {
    app.classList.remove('sidebar-collapsed');
  }

  // Update toggle icon direction
  const toggleBtn = $('.sidebar-toggle');
  if (toggleBtn) {
    empty(toggleBtn);
    toggleBtn.appendChild(icon(collapsed ? 'chevron-right' : 'chevron-left', { size: 20 }));
  }
}

// ──────────────────────────────────────
// Toggle setup
// ──────────────────────────────────────

function setupToggle() {
  const toggleBtn = $('.sidebar-toggle');
  if (toggleBtn) {
    toggleBtn.addEventListener('click', () => {
      store.dispatch('TOGGLE_SIDEBAR');
    });
  }
}
