import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Database from 'better-sqlite3';
import { up } from '../../src/main/db/migrations/m006_revisions.js';

describe('m006 migration — note_revisions table', () => {
  let db: Database.Database;

  beforeEach(() => {
    db = new Database(':memory:');
    db.pragma('foreign_keys = ON');
    db.exec(`
      CREATE TABLE notes (
        id                       TEXT PRIMARY KEY,
        raw_text                 TEXT NOT NULL,
        ai_title                 TEXT,
        ai_summary               TEXT,
        ai_status                TEXT NOT NULL
                                 CHECK (ai_status IN ('pending','done','failed','disabled')),
        ai_error                 TEXT,
        ai_provider              TEXT,
        ai_generated_at          TEXT,
        title_edited_by_user     INTEGER NOT NULL DEFAULT 0,
        summary_edited_by_user   INTEGER NOT NULL DEFAULT 0,
        user_intent              TEXT,
        intent_prompted_at       TEXT,
        created_at               TEXT NOT NULL,
        updated_at               TEXT NOT NULL,
        due_date                 TEXT,
        due_date_edited_by_user  INTEGER NOT NULL DEFAULT 0,
        deleted_at               TEXT,
        last_recalled_at         TEXT,
        recall_dismissed_at      TEXT,
        status                   TEXT NOT NULL DEFAULT 'active',
        status_changed_at        TEXT,
        move_reason              TEXT
      );
      INSERT INTO notes (id, raw_text, ai_status, created_at, updated_at)
        VALUES ('a', 'first text', 'done', '2026-05-01T00:00:00Z', '2026-05-01T00:00:00Z'),
               ('b', 'second text', 'done', '2026-05-02T00:00:00Z', '2026-05-02T00:00:00Z');
    `);
  });

  afterEach(() => { db.close(); });

  it('creates note_revisions table with required columns', () => {
    up(db);
    const cols = db.prepare(`PRAGMA table_info(note_revisions)`).all() as Array<{ name: string }>;
    const names = cols.map((c) => c.name);
    expect(names).toEqual(
      expect.arrayContaining(['rev_id', 'note_id', 'raw_text', 'edited_at', 'edited_by'])
    );
  });

  it('creates idx_note_revisions_note_id index', () => {
    up(db);
    const idx = db.prepare(`PRAGMA index_list(note_revisions)`).all() as Array<{ name: string }>;
    expect(idx.map((i) => i.name)).toContain('idx_note_revisions_note_id');
  });

  it('cascades on note delete (FK ON DELETE CASCADE)', () => {
    up(db);
    db.prepare(
      `INSERT INTO note_revisions (note_id, raw_text, edited_at, edited_by)
       VALUES ('a', 'manual rev', '2026-05-03T00:00:00Z', 'user')`
    ).run();
    db.prepare(`DELETE FROM notes WHERE id=?`).run('a');
    const rows = db.prepare(`SELECT * FROM note_revisions WHERE note_id=?`).all('a');
    expect(rows).toHaveLength(0);
  });

  it("backfills existing notes as edited_by='capture' revisions", () => {
    up(db);
    const rows = db
      .prepare(`SELECT note_id, raw_text, edited_at, edited_by FROM note_revisions ORDER BY note_id`)
      .all() as Array<{ note_id: string; raw_text: string; edited_at: string; edited_by: string }>;
    expect(rows).toHaveLength(2);
    expect(rows[0]).toEqual({
      note_id: 'a',
      raw_text: 'first text',
      edited_at: '2026-05-01T00:00:00Z',
      edited_by: 'capture'
    });
    expect(rows[1]).toEqual({
      note_id: 'b',
      raw_text: 'second text',
      edited_at: '2026-05-02T00:00:00Z',
      edited_by: 'capture'
    });
  });

  it('exports version=6', async () => {
    const mod = await import('../../src/main/db/migrations/m006_revisions.js');
    expect(mod.version).toBe(6);
  });
});
