'use strict';

/**
 * Brain exporter: generates markdown export of Wall-E brain contents.
 * Organizes by knowledge categories, memory domains, people, and entities.
 */

const brain = require('../brain');

/**
 * Sanitize a string for use as a filename.
 */
function safeFilename(str) {
  if (!str) return 'unknown';
  return str
    .replace(/[^a-zA-Z0-9_-]/g, '_')
    .replace(/_+/g, '_')
    .replace(/^_|_$/g, '')
    .toLowerCase()
    .slice(0, 50) || 'unknown';
}

/**
 * Export brain contents as a structured markdown object.
 * @param {object} [opts] - Options
 * @param {string} [opts.domain] - Filter memories by domain
 * @returns {object} { readme, files: [{ path, content }] }
 */
function exportBrain(opts = {}) {
  const files = [];
  const stats = brain.getBrainStats();
  const ownerName = brain.getOwnerName ? brain.getOwnerName() : 'Owner';

  // README
  const readme = [
    `# ${ownerName}'s Brain Export`,
    ``,
    `Exported: ${new Date().toISOString()}`,
    ``,
    `## Stats`,
    `- Memories: ${stats.memory_count}`,
    `- Knowledge: ${stats.knowledge_count}`,
    `- People: ${stats.people_count}`,
    `- Patterns: ${stats.pattern_count}`,
    `- Pending Questions: ${stats.pending_question_count}`,
    ``,
  ].join('\n');
  files.push({ path: 'README.md', content: readme });

  // Knowledge by category
  const db = brain.getDb();
  const categories = db.prepare(
    "SELECT DISTINCT category FROM knowledge WHERE status = 'active' ORDER BY category"
  ).all().map(r => r.category);

  for (const cat of categories) {
    const entries = brain.findKnowledge({ category: cat, status: 'active', limit: 500 });
    if (entries.length === 0) continue;
    const lines = [`# Knowledge: ${cat}`, ''];
    for (const k of entries) {
      const validity = k.valid_from ? ` (${k.valid_from.slice(0, 10)}${k.valid_to ? ' - ' + k.valid_to.slice(0, 10) : ' - present'})` : '';
      lines.push(`- **${k.subject}** ${k.predicate} ${k.object} [${Math.round((k.confidence || 0.5) * 100)}%]${validity}`);
    }
    files.push({ path: `knowledge/${safeFilename(cat)}.md`, content: lines.join('\n') });
  }

  // Memories by domain/topic
  const domains = db.prepare(
    "SELECT DISTINCT domain FROM memories WHERE domain IS NOT NULL ORDER BY domain"
  ).all().map(r => r.domain);

  for (const domain of domains) {
    if (opts.domain && opts.domain !== domain) continue;
    const topics = db.prepare(
      "SELECT DISTINCT topic FROM memories WHERE domain = ? AND topic IS NOT NULL ORDER BY topic"
    ).all(domain).map(r => r.topic);

    for (const topic of topics) {
      const lines = [];
      let memOffset = 0;
      const PAGE = 1000;
      while (true) {
        const batch = db.prepare(
          "SELECT content, timestamp, source, source_channel FROM memories WHERE domain = ? AND topic = ? AND archived_at IS NULL ORDER BY timestamp DESC LIMIT ? OFFSET ?"
        ).all(domain, topic, PAGE, memOffset);
        if (batch.length === 0 && memOffset === 0) break; // no memories at all
        if (batch.length === 0) break; // no more pages

        if (memOffset === 0) {
          lines.push(`# ${domain} / ${topic}`, '');
        }

        for (const m of batch) {
          const date = m.timestamp ? m.timestamp.slice(0, 10) : 'unknown';
          const src = m.source_channel ? `${m.source}/${m.source_channel}` : m.source;
          lines.push(`### ${date} (${src})`);
          lines.push(m.content ? m.content.slice(0, 500) : '(empty)');
          lines.push('');
        }
        memOffset += batch.length;
        if (batch.length < PAGE) break;
      }
      if (lines.length > 0) {
        lines.splice(1, 0, `${memOffset} memories`); // insert count after header
        files.push({ path: `memories/${safeFilename(domain)}/${safeFilename(topic)}.md`, content: lines.join('\n') });
      }
    }
  }

  // People
  const people = brain.listPeople({});
  if (people.length > 0) {
    for (const p of people) {
      const lines = [`# ${p.name}`, ''];
      if (p.relationship) lines.push(`**Relationship**: ${p.relationship}`);
      if (p.trust_level) lines.push(`**Trust**: ${p.trust_level}`);
      if (p.notes) lines.push(`\n${p.notes}`);
      if (p.aliases) {
        try {
          const aliases = JSON.parse(p.aliases);
          if (Array.isArray(aliases) && aliases.length > 0) {
            lines.push(`**Aliases**: ${aliases.join(', ')}`);
          }
        } catch {}
      }
      files.push({ path: `people/${safeFilename(p.name)}.md`, content: lines.join('\n') });
    }
  }

  // Entities
  try {
    const entities = brain.listEntities({ limit: 500 });
    if (entities.length > 0) {
      for (const e of entities) {
        const lines = [`# ${e.canonical_name}`, '', `**Type**: ${e.entity_type}`];
        if (e.aliases) {
          try {
            const aliases = JSON.parse(e.aliases);
            if (Array.isArray(aliases) && aliases.length > 0) {
              lines.push(`**Aliases**: ${aliases.join(', ')}`);
            }
          } catch {}
        }
        if (e.properties) {
          try {
            const props = JSON.parse(e.properties);
            if (typeof props === 'object') {
              lines.push('', '## Properties');
              for (const [k, v] of Object.entries(props)) {
                lines.push(`- ${k}: ${v}`);
              }
            }
          } catch {}
        }
        files.push({ path: `entities/${safeFilename(e.canonical_name)}.md`, content: lines.join('\n') });
      }
    }
  } catch {}

  return { readme, files };
}

module.exports = { exportBrain, safeFilename };
