import { describe, expect, it } from 'vitest';
import { parseCmbCsv, parseIcbcCsv, parseGenericBankCsv } from '../src/domain/pipeline/adapters';
import { migrateDb, MemoryMigrationDb, SCHEMA_VERSION } from '../src/storage/migrations';

describe('CSV adapters', () => {
  it('parseCmbCsv 招商银行', () => {
    const csv = '交易日期,交易类型,交易金额,交易对方,摘要\n2026-07-10,消费,100.50,超市,买日用品\n2026-07-11,收入,5000.00,公司,工资';
    const events = parseCmbCsv(csv);
    expect(events).toHaveLength(2);
    expect(events[0].direction).toBe('expense');
    expect(events[0].amount).toBe('-100.50');
    expect(events[1].direction).toBe('income');
    expect(events[1].amount).toBe('5000.00');
  });

  it('parseIcbcCsv 工商银行', () => {
    const csv = '交易时间,交易类型,交易金额,对方户名,摘要\n2026-07-10,消费,200,商户,购物';
    const events = parseIcbcCsv(csv);
    expect(events).toHaveLength(1);
    expect(events[0].counterparty).toBe('商户');
  });

  it('parseGenericBankCsv 通用', () => {
    const csv = '日期,金额,交易对方\n2026-07-10,50,便利店';
    const events = parseGenericBankCsv(csv, 'Bank:Custom');
    expect(events).toHaveLength(1);
    expect(events[0].id).toContain('Bank:Custom');
  });

  it('退款项识别为 refund', () => {
    const csv = '日期,交易类型,金额,交易对方\n2026-07-10,退款,30,商家';
    const events = parseGenericBankCsv(csv);
    expect(events[0].direction).toBe('refund');
  });
});

describe('migrations', () => {
  it('从 0 迁移到当前版本', async () => {
    const db = new MemoryMigrationDb();
    await migrateDb(db);
    expect(db.executed.length).toBeGreaterThan(0);
    // 应包含建表语句
    expect(db.executed.some(s => s.includes('CREATE TABLE'))).toBe(true);
    // 应包含 user_version 设置
    expect(db.executed.some(s => s.includes('PRAGMA user_version'))).toBe(true);
  });

  it('已迁移过的不再重复执行', async () => {
    const db = new MemoryMigrationDb();
    await migrateDb(db);
    const firstCount = db.executed.length;
    await migrateDb(db);  // 第二次
    expect(db.executed.length).toBe(firstCount);  // 无新增
  });

  it('SCHEMA_VERSION 至少为 2（含双轨制表）', () => {
    expect(SCHEMA_VERSION).toBeGreaterThanOrEqual(2);
  });

  it('v2 包含 categories 表', async () => {
    const db = new MemoryMigrationDb();
    await migrateDb(db);
    expect(db.executed.some(s => s.includes('categories'))).toBe(true);
    expect(db.executed.some(s => s.includes('credit_cards'))).toBe(true);
  });
});
