/**
 * app.mjs — Main application bootstrap
 */

import store from './store.mjs';
import eventBus, { EVENTS } from './event-bus.mjs';
import api from './api.mjs';
import router from './router.mjs';

function _tryParseJSON(str) {
  try { return JSON.parse(str); } catch { return {}; }
}

async function initialize() {
  console.log('[app] Initializing AI-Do v4.0...');

  // Apply saved theme
  const theme = store.getState().ui.theme;
  document.documentElement.setAttribute('data-theme', theme);

  // Init API client (reads auth token from meta tag)
  api.init();

  // Init router
  router.init();

  // Connect WebSocket for real-time updates
  api.connectWebSocket();

  // Load initial data in parallel
  await loadInitialData();

  // Load secondary data (non-blocking)
  loadSecondaryData();

  // Setup keyboard shortcuts
  setupKeyboardShortcuts();

  // Setup responsive behavior
  setupResponsive();

  // Init UI components (lazy load)
  await initComponents();

  // Setup desktop bridge listeners (Electron IPC)
  setupDesktopBridge();

  console.log('[app] AI-Do ready');
}

async function loadInitialData() {
  try {
    const [config, events] = await Promise.all([
      api.getConfig().catch(err => { console.warn('[app] Config load failed:', err.message); return null; }),
      api.getEvents(50).catch(err => { console.warn('[app] Events load failed:', err.message); return []; })
    ]);

    if (config) {
      store.dispatch('SET_SETTINGS', config);
    }

    // Convert events to chat messages
    // DB rows use 'type' field (not 'kind'); normalise for both.
    if (Array.isArray(events)) {
      const chatMessages = events
        .filter(e => (e.type || e.kind) === 'chat')
        .map(e => ({
          id: e.id,
          role: e.source === 'user' ? 'user' : 'agent',
          content: e.content,
          timestamp: e.created_at || e.timestamp || Date.now()
        }));
      store.dispatch('SET_MESSAGES', chatMessages);

      // Populate activity feed with ALL events (not just chat)
      const activityFeed = events.map(e => ({
        kind: e.type || e.kind || 'system',
        source: e.source || '',
        content: e.content || '',
        timestamp: e.created_at || e.timestamp || Date.now(),
        metadata: e.metadata ? (typeof e.metadata === 'string' ? _tryParseJSON(e.metadata) : e.metadata) : {}
      }));
      store.dispatch('SET_ACTIVITY_FEED', activityFeed);
    }
  } catch (err) {
    console.error('[app] Initial data load error:', err);
  }
}

async function loadSecondaryData() {
  const loads = [
    api.getSkillsPalette()
      .then(palette => store.dispatch('SET_SKILL_PALETTE', palette))
      .catch(() => {}),
    api.getPersona()
      .then(persona => store.dispatch('SET_PERSONA', persona))
      .catch(() => {}),
    api.getVoiceStatus()
      .then(status => {
        store.dispatch('SET_VOICE_ENABLED', status?.enabled || false);
        // On page load, the browser voice orb should always start idle.
        // Server voice states (listening, detecting, etc.) are server-side
        // and don't mean the browser mic is active.
        store.dispatch('SET_VOICE_STATUS', 'idle');
      })
      .catch(() => {}),
    api.getWorkspaces()
      .then(ws => {
        store.dispatch('SET_WORKSPACES', ws?.workspaces || ws || []);
        if (ws?.active) store.dispatch('SET_ACTIVE_WORKSPACE', ws.active);
      })
      .catch(() => {}),
    api.getKGStats()
      .then(stats => store.dispatch('SET_KG_STATS', stats))
      .catch(() => {})
  ];

  await Promise.allSettled(loads);
}

function setupKeyboardShortcuts() {
  document.addEventListener('keydown', (e) => {
    // Escape: exit focus mode
    if (e.key === 'Escape') {
      if (store.getState().ui.focusMode) {
        store.dispatch('SET_FOCUS_MODE', false);
        document.getElementById('app')?.removeAttribute('data-focus');
        e.preventDefault();
      }
    }

    // Cmd/Ctrl+K: focus chat input
    if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
      const input = document.querySelector('.chat-input textarea');
      if (input) {
        input.focus();
        e.preventDefault();
      }
    }

    // Cmd/Ctrl+\: toggle sidebar
    if ((e.metaKey || e.ctrlKey) && e.key === '\\') {
      store.dispatch('TOGGLE_SIDEBAR');
      e.preventDefault();
    }

    // Cmd/Ctrl+Shift+F: toggle focus mode
    if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'f') {
      const newFocus = !store.getState().ui.focusMode;
      store.dispatch('SET_FOCUS_MODE', newFocus);
      const app = document.getElementById('app');
      if (app) {
        newFocus ? app.setAttribute('data-focus', '') : app.removeAttribute('data-focus');
      }
      e.preventDefault();
    }
  });
}

function setupResponsive() {
  const mq = window.matchMedia('(max-width: 768px)');

  const handleResize = (e) => {
    store.dispatch('SET_MOBILE', e.matches);
  };

  mq.addEventListener('change', handleResize);
  handleResize(mq);

  // Sync sidebar/right-panel collapsed state to DOM
  store.subscribe(
    (s) => s.ui.sidebarCollapsed,
    (collapsed) => {
      document.getElementById('app')?.classList.toggle('sidebar-collapsed', collapsed);
    }
  );

  store.subscribe(
    (s) => s.ui.rightPanelCollapsed,
    (collapsed) => {
      document.getElementById('app')?.classList.toggle('right-panel-collapsed', collapsed);
    }
  );

  // Panel backdrop click closes panels on mobile
  const backdrop = document.querySelector('.panel-backdrop');
  if (backdrop) {
    backdrop.addEventListener('click', () => {
      store.dispatch('TOGGLE_SIDEBAR');
    });
  }
}

async function initComponents() {
  // Lazy-load components — each registers itself
  const componentPaths = [
    './components/toast.mjs',
    './components/modal.mjs',
    './components/avatar.mjs',
    './components/chat.mjs',
    './components/voice-orb.mjs',
    './components/dock.mjs',
    './components/sidebar.mjs',
    './components/activity-feed.mjs',
    './components/function-palette.mjs',
    './components/knowledge-explorer.mjs',
    './components/workspace-panel.mjs',
    './components/settings.mjs'
  ];

  const results = await Promise.allSettled(
    componentPaths.map(async (path) => {
      try {
        const mod = await import(path);
        if (mod.init) mod.init();
      } catch (err) {
        console.warn(`[app] Component ${path} load deferred:`, err.message);
      }
    })
  );
}

function setupDesktopBridge() {
  if (!window.desktopBridge) return;

  // Theme change from Electron menu
  if (window.desktopBridge.onThemeChange) {
    window.desktopBridge.onThemeChange((theme) => {
      document.documentElement.setAttribute('data-theme', theme);
      store.dispatch('SET_THEME', theme);
    });
  }

  // Focus mode toggle from Electron menu/hotkey
  if (window.desktopBridge.onFocusModeToggle) {
    window.desktopBridge.onFocusModeToggle(() => {
      const newFocus = !store.getState().ui.focusMode;
      store.dispatch('SET_FOCUS_MODE', newFocus);
      const app = document.getElementById('app');
      if (app) {
        newFocus ? app.setAttribute('data-focus', '') : app.removeAttribute('data-focus');
      }
    });
  }

  // Open persona editor from Electron menu
  if (window.desktopBridge.onOpenPersonaEditor) {
    window.desktopBridge.onOpenPersonaEditor(async () => {
      try {
        const { openPersonaEditor } = await import('./components/persona-editor.mjs');
        openPersonaEditor();
      } catch (err) {
        console.warn('[app] Could not open persona editor:', err.message);
      }
    });
  }
}

// Boot on DOM ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initialize);
} else {
  initialize();
}

export { initialize };
