import { describe, it, expect } from 'vitest';
import { parseTasksFile, writeTasksFile } from '../tasks-file.js';
import type { MissionTask } from '../types.js';

const SAMPLE_TASKS_MD = `# Tasks — MVP

> Single-writer: orchestrator only. Workers read but never modify.

| id     | status      | milestone | description                                | pr  | notes |
| ------ | ----------- | --------- | ------------------------------------------ | --- | ----- |
| P0-001 | done        | Phase 0   | Scaffold monorepo                          | #60 | #1    |
| P0-002 | done        | Phase 0   | @mosaicstack/types — migrate and extend         | #65 | #2    |
| P1-001 | in-progress | Phase 1   | apps/gateway scaffold                      | #61 | #10   |
| P2-001 | not-started | Phase 2   | @mosaicstack/agent — Pi SDK integration         | —   | #19   |
| P2-002 | blocked     | Phase 2   | Multi-provider support                     | —   | #20   |
`;

describe('parseTasksFile', () => {
  it('parses a valid TASKS.md into MissionTask[]', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    expect(tasks).toHaveLength(5);
  });

  it('extracts task IDs correctly', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    expect(tasks.map((t) => t.id)).toEqual(['P0-001', 'P0-002', 'P1-001', 'P2-001', 'P2-002']);
  });

  it('extracts statuses correctly', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    expect(tasks.map((t) => t.status)).toEqual([
      'done',
      'done',
      'in-progress',
      'not-started',
      'blocked',
    ]);
  });

  it('extracts milestones correctly', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    expect(tasks[0]!.milestone).toBe('Phase 0');
    expect(tasks[2]!.milestone).toBe('Phase 1');
    expect(tasks[3]!.milestone).toBe('Phase 2');
  });

  it('extracts PR references', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    expect(tasks[0]!.pr).toBe('#60');
    expect(tasks[3]!.pr).toBe('—');
  });

  it('returns empty array for empty content', () => {
    expect(parseTasksFile('')).toEqual([]);
    expect(parseTasksFile('# No table here')).toEqual([]);
  });

  it('handles legacy status values', () => {
    const content = `| id | status | description |
|----|--------|-------------|
| T1 | completed | Task one |
| T2 | pending | Task two |
| T3 | failed | Task three |
`;
    const tasks = parseTasksFile(content);
    expect(tasks[0]!.status).toBe('done');
    expect(tasks[1]!.status).toBe('not-started');
    expect(tasks[2]!.status).toBe('blocked');
  });
});

describe('writeTasksFile', () => {
  it('generates valid markdown table', () => {
    const tasks: MissionTask[] = [
      {
        id: 'T-001',
        title: 'Test task',
        status: 'done',
        dependencies: [],
        milestone: 'Phase 1',
        pr: '#42',
        notes: '#1',
      },
    ];

    const output = writeTasksFile(tasks);
    expect(output).toContain('| T-001 | done | Phase 1 | Test task | #42 | #1 |');
    expect(output).toContain('# Tasks');
  });

  it('roundtrips parse/write', () => {
    const tasks = parseTasksFile(SAMPLE_TASKS_MD);
    const output = writeTasksFile(tasks);
    const reparsed = parseTasksFile(output);
    expect(reparsed).toHaveLength(tasks.length);
    for (let i = 0; i < tasks.length; i++) {
      expect(reparsed[i]!.id).toBe(tasks[i]!.id);
      expect(reparsed[i]!.status).toBe(tasks[i]!.status);
      expect(reparsed[i]!.title).toBe(tasks[i]!.title);
    }
  });
});
