/**
 * help.mjs — In-app help system with topic-based documentation
 * Triggered by eventBus NOTIFICATION events with type 'help', or called directly.
 */

import eventBus, { EVENTS } from '../event-bus.mjs';
import { createElement } from '../utils/dom.mjs';
import { renderMarkdown } from '../utils/markdown.mjs';
import * as modal from './modal.mjs';

// ── Help topic content ──────────────────────────────────────────────────────

const HELP_TOPICS = {
  'getting-started': {
    label: 'Getting Started',
    icon: '🚀',
    content: `
# Getting Started with AI-Do

AI-Do is your autonomous AI agent — it runs continuously, processes your requests,
creates content, and learns over time.

## Quick Start

1. **Chat** — Type a message to talk to your agent. Responses stream in real time.
2. **Skills** — Ask the agent to run tasks: *"research X"*, *"build a page about Y"*, *"write a doc on Z"*.
3. **Knowledge** — Paste a URL or upload a file to add it to the agent's memory.
4. **Settings** — Configure the agent's name, personality, LLM model, and more.

## The Agent Loop

The agent runs on a 5-minute autonomous loop. Between your messages it:

- Checks system health and memory usage
- Processes queued ingestion jobs
- Runs idle thinking and reflection tasks
- Writes reflective journal entries

## Views

| View | Purpose |
|------|---------|
| Chat | Real-time conversation |
| Activity | Live log of agent actions |
| Skills | Browse and trigger skills |
| Knowledge | Explore the knowledge graph |
| Workspaces | Manage project workspaces |
| Settings | Configure the agent |
`
  },

  'chat': {
    label: 'Chat',
    icon: '💬',
    content: `
# Chat

The Chat view is your primary way to interact with the agent.

## Sending Messages

Type in the input box and press **Enter** (or click **Send**). The agent responds
using streaming — you'll see the reply appear word by word as it's generated.

Use **Shift+Enter** to insert a newline without sending.

## Voice Input

Click the **microphone orb** at the bottom of the chat panel to activate browser
voice input. Speak your message; it will be transcribed and sent automatically.

Enable wake-word detection in Settings for fully hands-free activation.

## File Uploads

Click the **paperclip** icon to upload a file. Supported formats include images,
PDFs, text files, markdown, and code. Uploaded files are ingested into the
knowledge graph automatically.

## Triggering Skills via Chat

Describe what you want and the agent detects the right skill:

- *"Research the latest news on quantum computing"*
- *"Build a landing page for my project"*
- *"Summarize the document I just uploaded"*
- *"Write a blog post about productivity tips"*

## Clearing Chat

Click **Clear** in the chat header to reset the conversation history.
`
  },

  'skills': {
    label: 'Skills',
    icon: '⚡',
    content: `
# Skills

Skills are modular task executors your agent can run on your behalf.

## Built-in Skills

| Skill | What it does |
|-------|-------------|
| **research** | Searches for information and synthesizes a report |
| **build-page** | Creates an HTML page in your workspace |
| **write-doc** | Writes a document (markdown or HTML) |
| **summarize** | Summarizes text, files, or URLs |
| **analyze** | Deep analysis of content or data |
| **ingest** | Ingests a file or URL into the knowledge graph |
| **journal** | Writes a reflective journal entry |
| **self-improve** | Agent generates or refines its own skills |

## Triggering Skills

Skills run when you describe a task in chat — the agent detects the intent and
queues the appropriate skill automatically.

You can also browse and trigger skills directly from the **Skills** view using the
function palette cards.

## Task Queue

Running skills appear in the **Activity** feed with live status. Long-running
tasks can be cancelled from the Activity view.

## Autonomous Skills

Some skills can run during the agent's idle loop without your prompt (e.g.
journaling, reflection). User-only skills like *self-improve* only run when you
explicitly request them.
`
  },

  'knowledge': {
    label: 'Knowledge',
    icon: '🧠',
    content: `
# Knowledge Graph

The Knowledge Graph is your agent's long-term memory — a structured store of
entities and relationships extracted from everything you ingest.

## Adding Knowledge

**From chat:** Paste a URL or upload a file — the agent ingests it automatically.

**Via the ingest skill:** Ask the agent to *"ingest https://example.com"* or
*"ingest /path/to/file.pdf"*.

**Automatic:** The agent extracts entities from every conversation and adds
them to the graph.

## Browsing the Graph

Open the **Knowledge** view to:

- Search entities by name or topic
- View entity relationships and connections
- See what the agent knows about a concept
- Monitor the ingestion queue

## How It Works

1. Content (text / file / URL) → raw text extraction
2. LLM extracts entities and relations
3. Stored in SQLite with FTS5 full-text search
4. Injected into prompts as context (RAG-style retrieval)

## Workspace Scoping

Each workspace has its own knowledge graph. Switch workspaces to work with
separate knowledge bases for different projects.
`
  },

  'workspaces': {
    label: 'Workspaces',
    icon: '📁',
    content: `
# Workspaces

Workspaces let you organize the agent's output and knowledge into separate
project areas.

## What's in a Workspace

Each workspace has:

- Its own **output folder** — files created by skills go here
- Its own **knowledge graph** — entities are scoped per workspace
- A **name** and optional description

## Managing Workspaces

Open the **Workspaces** view to:

- Create a new workspace
- Switch the active workspace
- View files in each workspace
- Delete a workspace (cannot delete the default)

## The Default Workspace

The **default** workspace always exists and cannot be deleted. If you haven't
created additional workspaces, all output goes here.

## Active Workspace

The currently active workspace is shown in the sidebar. All new files and
knowledge from ingestion go to the active workspace.

## Accessing Files

Workspace files are accessible at `/workspace-files/<filename>` and listed in
the sidebar under **Recent Files**.
`
  },

  'voice': {
    label: 'Voice',
    icon: '🎤',
    content: `
# Voice Input

AI-Do supports browser-based voice input and offline wake-word detection.

## Browser Voice

Click the **voice orb** (microphone circle) at the bottom of the chat panel.
Your browser will request microphone permission on first use.

Speak your message, then click again (or wait for silence detection) to send.

## Wake Word Detection

Enable **native voice mode** in Settings → Voice to activate always-on
wake-word detection using openWakeWord (runs fully offline, no API key needed).

Once enabled, say the configured wake phrase to activate listening. A 15-second
ring buffer captures context before and after the wake word.

## Electron Hotkey

In the desktop app, press **Cmd+Shift+Space** to instantly start listening
without clicking the orb.

## Voice Settings

Configure in **Settings → Voice**:

- Enable / disable voice
- Choose wake word model
- Adjust detection threshold
- Set ring buffer duration

## Tips

- Speak clearly at a normal pace
- Works best in a quiet environment
- Transcription uses Whisper (local) when available, otherwise falls back to the
  Web Speech API
`
  },

  'keyboard': {
    label: 'Keyboard Shortcuts',
    icon: '⌨️',
    content: `
# Keyboard Shortcuts

## Global

| Shortcut | Action |
|----------|--------|
| **?** | Show keyboard shortcuts |
| **Esc** | Close dialog / exit focus mode |
| **⌘ K** | Focus chat input |
| **⌘ \\** | Toggle sidebar |
| **⌘ ⇧ F** | Toggle focus mode |

## Desktop App Only

| Shortcut | Action |
|----------|--------|
| **⌘ ⇧ V** | Ingest clipboard contents |
| **⌘ ⇧ Space** | Activate voice listening |

## Chat

| Action | How |
|--------|-----|
| Send message | Enter |
| New line | Shift+Enter |
| Cancel streaming | Click Stop button |

## Tips

- **Focus mode** hides the sidebar and dock for distraction-free chat
- **⌘ K** jumps to the chat input from any view
- Press **?** anywhere (outside a text field) to see this shortcut list
`
  }
};

const TOPIC_ORDER = [
  'getting-started', 'chat', 'skills', 'knowledge', 'workspaces', 'voice', 'keyboard'
];

// ── Public API ──────────────────────────────────────────────────────────────

export function init() {
  eventBus.on(EVENTS.NOTIFICATION, (data) => {
    if (data?.type === 'help') {
      if (data.topic && HELP_TOPICS[data.topic]) {
        showHelp(data.topic);
      } else {
        showTopicPicker();
      }
    }
  });
}

export async function showHelp(topic) {
  const entry = HELP_TOPICS[topic];
  if (!entry) {
    showTopicPicker();
    return;
  }

  const html = await renderMarkdown(entry.content.trim());

  const contentWrapper = createElement('div', { className: 'help-modal-body' });

  const backBtn = createElement('button', { className: 'glass-button help-back-btn' }, ['← All Topics']);
  backBtn.addEventListener('click', () => {
    modal.close();
    setTimeout(showTopicPicker, 310);
  });

  const contentEl = createElement('div', { className: 'help-content' });
  contentEl.innerHTML = html;

  contentWrapper.appendChild(backBtn);
  contentWrapper.appendChild(contentEl);

  modal.show({
    title: `${entry.icon}  ${entry.label}`,
    content: contentWrapper,
    actions: [{ label: 'Close', className: 'glass-button', onClick: modal.close }]
  });
}

export function showTopicPicker() {
  const grid = createElement('div', { className: 'help-topics' });

  for (const key of TOPIC_ORDER) {
    const entry = HELP_TOPICS[key];
    if (!entry) continue;

    const btn = createElement('button', { className: 'help-topic-btn glass-button' });
    btn.appendChild(createElement('span', { className: 'help-topic-icon' }, [entry.icon]));
    btn.appendChild(createElement('span', { className: 'help-topic-label' }, [entry.label]));

    btn.addEventListener('click', () => {
      modal.close();
      setTimeout(() => showHelp(key), 310);
    });

    grid.appendChild(btn);
  }

  modal.show({
    title: 'Help',
    content: grid
  });
}
