/**
 * Detailed per-session context pack — `.claude/dashclaw/session-notes/`.
 * The warehouse the root CLAUDE.md deliberately keeps slim.
 *
 * Ported from AgentLens (`src/optimal-files/session-pack.js`). Pure.
 */

export function generateSessionPack(analysis) {
  const a = analysis;
  const sid = (a.session && a.session.session_uuid) || 'unknown';
  const slug = (a.project && (a.project.slug || a.project.cwd || 'project')) || 'project';

  const lines = [];
  lines.push(`# Session notes — \`${sid}\``);
  lines.push('');
  lines.push(`Project: \`${slug}\` · cost: $${a.cost.usd.toFixed(2)} _(parser v${a.cost.parserVersion || '?'}, deduped)_ · model: \`${(a.session && a.session.model_primary) || '?'}\``);
  if (a.cost.naive_usd && a.cost.naive_usd > a.cost.usd * 1.05) {
    lines.push('');
    lines.push(`> Naive row-sum would have been $${a.cost.naive_usd.toFixed(2)} (${(a.cost.naive_usd / a.cost.usd).toFixed(2)}x the deduped value). Parser v${a.cost.parserVersion} rejected the duplicate fragments.`);
  }
  lines.push('');

  lines.push(`## What this session tried to do`);
  lines.push('');
  lines.push(`_Inferred from tool sequence — DashClaw cannot read the user's original prompt by default._`);
  if (a.edits.length) {
    lines.push('');
    lines.push(`Top edit targets: ${a.edits.slice(0, 3).map(e => '`' + shortPath(e.target) + '`').join(', ')}.`);
  }
  lines.push('');

  lines.push(`## Files read most often`);
  if (a.reads.length) {
    lines.push('');
    lines.push(`| File | Reads |`);
    lines.push(`| --- | ---: |`);
    for (const r of a.reads.slice(0, 10)) {
      lines.push(`| \`${escapeMd(shortPath(r.target))}\` | ${r.count} |`);
    }
    lines.push('');
  } else {
    lines.push('');
    lines.push(`_No qualifying reads detected._`);
    lines.push('');
  }

  if (a.edits.length) {
    lines.push(`## Files edited`);
    lines.push('');
    for (const e of a.edits.slice(0, 10)) {
      lines.push(`- \`${escapeMd(shortPath(e.target))}\` x ${e.count}`);
    }
    lines.push('');
  }

  if (a.verificationCommands.length) {
    lines.push(`## Verification commands that ran`);
    lines.push('');
    for (const v of a.verificationCommands.slice(0, 10)) {
      lines.push(`- \`${escapeMd(v.command)}\` x ${v.count}`);
    }
    lines.push('');
  }
  if (a.dangerousCommands.length) {
    lines.push(`## Dangerous commands seen`);
    lines.push('');
    for (const d of a.dangerousCommands.slice(0, 10)) {
      lines.push(`- \`${escapeMd(d.command.slice(0, 120))}\` x ${d.count} — _${d.why}_`);
    }
    lines.push('');
    lines.push(`The \`.claude/hooks/agentlens-dangerous-command-guard.py\` script in this bundle blocks these by default.`);
    lines.push('');
  }
  const otherBash = a.bashCommands.filter(b =>
    !a.verificationCommands.some(v => v.command === b.command)
    && !a.dangerousCommands.some(d => d.command === b.command));
  if (otherBash.length) {
    lines.push(`## Other commands`);
    lines.push('');
    for (const b of otherBash.slice(0, 10)) {
      lines.push(`- \`${escapeMd(b.command.slice(0, 120))}\` x ${b.count}`);
    }
    lines.push('');
  }

  lines.push(`## Repeated tool-run signals`);
  lines.push('');
  lines.push(`Summary: high ${a.repeatedRunSummary.high} · medium ${a.repeatedRunSummary.medium} · low ${a.repeatedRunSummary.low}.`);
  if (a.repeatedRuns.length) {
    lines.push('');
    for (const r of a.repeatedRuns.slice(0, 8)) {
      const tgts = (r.targets || []).slice(0, 2).map(t => '`' + shortPath(t) + '`').join(', ') || '(no target)';
      lines.push(`- **${r.confidence}** · \`${escapeMd(r.name)}\` x ${r.count} on ${tgts} — _${r.evidence}_`);
    }
    lines.push('');
    lines.push(`Only **high**-confidence signals are claimed as cost in the optimizer. Medium and low are surfaced but not totalled.`);
    lines.push('');
  } else {
    lines.push('');
    lines.push(`_No repeated-run signals._`);
    lines.push('');
  }

  lines.push(`## Decisions and open questions`);
  lines.push('');
  lines.push(`_Inferred — review and edit before relying on them._`);
  lines.push('');
  const decisions = inferDecisions(a);
  if (decisions.length) {
    lines.push(`**Likely decisions:**`);
    for (const d of decisions) lines.push(`- ${d}`);
    lines.push('');
  }
  const openQs = inferOpenQuestions(a);
  if (openQs.length) {
    lines.push(`**Open questions for the next session:**`);
    for (const q of openQs) lines.push(`- ${q}`);
    lines.push('');
  }

  lines.push(`## Suggested starting prompt for the next session`);
  lines.push('');
  lines.push('```text');
  lines.push(buildSuggestedPrompt(a));
  lines.push('```');
  lines.push('');

  lines.push(`---`);
  lines.push(`Generated by DashClaw Code Sessions from session \`${sid}\`.`);
  lines.push(`Parser version: \`${a.cost.parserVersion || '?'}\`.`);
  lines.push(`Generated at: \`${a.generatedAt}\`.`);
  lines.push(`Cost numbers above are deduped (request_id -> message.id -> row uuid). Per-tool cost would be an estimate; this file does not claim one.`);
  lines.push(`Review before committing.`);

  return {
    path: `.claude/dashclaw/session-notes/${sid}.md`,
    kind: 'session-pack',
    title: 'Session context pack',
    content: lines.join('\n') + '\n',
    reason: 'Detailed session-derived context that is too noisy for root CLAUDE.md but useful when someone needs to reconstruct what happened.',
    confidence: 'high',
    commitRecommendation: 'gitignore',
    group: 'recommended_now',
  };
}

function escapeMd(s) {
  // Escape backslash first, then the pipe — otherwise a literal '\' in the
  // input corrupts the markdown table cell (js/incomplete-sanitization).
  return String(s || '').replace(/\\/g, '\\\\').replace(/\|/g, '\\|');
}

function shortPath(p) {
  if (!p) return '';
  const parts = String(p).split(/[\\/]/);
  if (parts.length <= 4) return p;
  return '.../' + parts.slice(-4).join('/');
}

function inferDecisions(a) {
  const out = [];
  if (a.verificationCommands.length) {
    out.push(`Verification command of record: \`${a.verificationCommands[0].command}\`.`);
  }
  if (a.repeatedRunSummary.high >= 1) {
    out.push(`A repeated-tool-run pattern recurred ${a.repeatedRunSummary.high}x at high confidence — likely a missing-context decision that should be captured in root CLAUDE.md or a path rule.`);
  }
  return out;
}

function inferOpenQuestions(a) {
  const out = [];
  if (a.edits.length && !a.verificationCommands.length) {
    out.push(`Session edited ${a.edits.length} file(s) but ran no verification command — was the result verified outside this session?`);
  }
  if (a.dangerousCommands.length) {
    out.push(`A dangerous command was attempted — confirm it ran in a safe context and whether the guard hook should be activated.`);
  }
  if (a.repeatedRunSummary.medium >= 3 && a.repeatedRunSummary.high === 0) {
    out.push(`Several medium-confidence repeated runs — could these batches be collapsed into one model request to cut tokens?`);
  }
  return out;
}

function buildSuggestedPrompt(a) {
  const slug = (a.project && (a.project.slug || a.project.cwd)) || 'this project';
  const out = [];
  out.push(`Resume work on ${slug}.`);
  if (a.reads.length) {
    out.push(``);
    out.push(`Files the previous session leaned on (open these first, in order):`);
    for (const r of a.reads.slice(0, 5)) out.push(`  - ${shortPath(r.target)}`);
  }
  if (a.verificationCommands.length) {
    out.push(``);
    out.push(`Verify with: ${a.verificationCommands[0].command}`);
  }
  if (a.repeatedRunSummary.high >= 1) {
    out.push(``);
    out.push(`Avoid: re-reading the same file >=3 times. If you notice yourself doing it, stop and update CLAUDE.md.`);
  }
  return out.join('\n');
}
