import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, copyFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { tmpdir } from 'node:os';
import { fileURLToPath } from 'node:url';

// RE-R2b: SessionStart surfaces the latest dated morning brief — a "## Morning
// Brief" block built from the brief's frontmatter (date + pre-rendered summary),
// read zero-tsx. session-start is a procedural hook with no exports, so we run it
// as a subprocess with an isolated HOME + LINKEDIN_STUDIO_DATA and inspect the
// additionalContext. Pattern: session-start-trends-staleness.test.mjs.
const here = dirname(fileURLToPath(import.meta.url));
const hookPath = join(here, '..', 'session-start.mjs');
const PLUGIN_ROOT = join(here, '..', '..', '..');
const STATE_TEMPLATE = join(PLUGIN_ROOT, 'config', 'state-file.template.md');

const HEADING = '## Morning Brief';
// ASCII fixture summary (the hook surfaces whatever the frontmatter carries verbatim).
const SUMMARY = '3 fresh signals match your pillars. Top: Alpha (AI, 2d).';

// Run the hook against an isolated HOME + data root; optionally seed a dated brief
// at <data>/trends/morning-brief/<name> — the SAME path defaultBriefDir() resolves
// to under this LINKEDIN_STUDIO_DATA (CLI-write path == hook-read path cross-check).
function runHook({ briefName }) {
  const home = mkdtempSync(join(tmpdir(), 'lis-mb-home-'));
  const data = mkdtempSync(join(tmpdir(), 'lis-mb-data-'));
  try {
    mkdirSync(join(home, '.claude'), { recursive: true });
    copyFileSync(STATE_TEMPLATE, join(home, '.claude', 'linkedin-studio.local.md'));

    if (briefName) {
      const briefDir = join(data, 'trends', 'morning-brief');
      mkdirSync(briefDir, { recursive: true });
      writeFileSync(
        join(briefDir, briefName),
        `---\ndate: 2026-06-24\nsummary: ${SUMMARY}\nstore: { trends: 10, matched: 3, fresh: 3 }\nschemaVersion: 1\n---\n\n# Morgen-brief\n\nbody\n`,
      );
    }

    const stdout = execFileSync('node', [hookPath], {
      input: '',
      env: { ...process.env, HOME: home, USERPROFILE: home, LINKEDIN_STUDIO_DATA: data },
      encoding: 'utf-8',
    });
    return JSON.parse(stdout).hookSpecificOutput.additionalContext;
  } finally {
    rmSync(home, { recursive: true, force: true });
    rmSync(data, { recursive: true, force: true });
  }
}

describe('session-start — morning-brief surfacing (RE-R2b)', () => {
  test('surfaces the latest brief: heading + summary + file pointer', () => {
    const ctx = runHook({ briefName: '2026-06-24.md' });
    assert.ok(ctx.includes(HEADING), 'expected the Morning Brief block');
    assert.ok(ctx.includes('Morning Brief (2026-06-24)'), 'block carries the brief date');
    assert.ok(ctx.includes(SUMMARY), 'block surfaces the pre-rendered summary');
    assert.ok(ctx.includes('Full brief:'), 'block carries the full-brief pointer');
    // The summary must be its OWN line (proves it did not bleed into adjacent lines —
    // single-line summary + the \n idiom held).
    assert.ok(ctx.split('\n').includes(SUMMARY), 'summary is a standalone line in the block');
  });

  test('newest brief wins when several dated files exist', () => {
    // (single-file harness asserts the surface; lexical name sort picks the newest —
    // covered structurally by the .md-anchored filter + .sort() in latestMorningBrief.)
    const ctx = runHook({ briefName: '2026-06-24.md' });
    assert.ok(ctx.includes('Morning Brief (2026-06-24)'));
  });

  test('no brief dir -> no block, no crash', () => {
    const ctx = runHook({ briefName: null });
    assert.ok(!ctx.includes(HEADING), 'no brief => no Morning Brief block');
  });
});
