const db = require('../db-sqlite');

describe('预支核销状态管理测试', () => {
  let advanceId;
  let verificationId;

  beforeAll(async () => {
    // 清空测试数据
    await db.query('DELETE FROM verifications WHERE 1=1');
    await db.query('DELETE FROM advances WHERE 1=1');
  });

  afterAll(async () => {
    // 清理测试数据
    await db.query('DELETE FROM verifications WHERE 1=1');
    await db.query('DELETE FROM advances WHERE 1=1');
  });

  // 测试1: 创建预支单
  test('创建预支单', async () => {
    const result = await db.query(
      'INSERT INTO advances (user_id, project_id, amount, currency, reason, advance_date, advance_code, status, applicant) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
      [1, 1, 1000, 'CNY', '测试预支', '2026-03-25', 'ADV-TEST-001', 'pending', '隆林']
    );
    advanceId = result.lastID;
    expect(advanceId).toBeDefined();
  });

  // 测试2: 审批预支单
  test('审批预支单', async () => {
    await db.query('UPDATE advances SET status = ? WHERE id = ?', ['approved', advanceId]);
    const advance = await db.query('SELECT * FROM advances WHERE id = ?', [advanceId]);
    expect(advance.rows[0].status).toBe('approved');
  });

  // 测试3: 执行预支单
  test('执行预支单', async () => {
    await db.query('UPDATE advances SET status = ? WHERE id = ?', ['executed', advanceId]);
    const advance = await db.query('SELECT * FROM advances WHERE id = ?', [advanceId]);
    expect(advance.rows[0].status).toBe('executed');
  });

  // 测试4: 创建部分核销单
  test('创建部分核销单', async () => {
    const result = await db.query(
      'INSERT INTO verifications (advance_id, amount, currency, reason, verification_date, verification_code, status, applicant, advance_code, advance_amount, settlement) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
      [advanceId, 300, 'CNY', '部分核销', '2026-03-25', 'VER-TEST-001', 'pending', '隆林', 'ADV-TEST-001', 1000, 0]
    );
    verificationId = result.lastID;
    expect(verificationId).toBeDefined();
  });

  // 测试5: 审批核销单
  test('审批核销单', async () => {
    await db.query('UPDATE verifications SET status = ? WHERE id = ?', ['approved', verificationId]);
    const verification = await db.query('SELECT * FROM verifications WHERE id = ?', [verificationId]);
    expect(verification.rows[0].status).toBe('approved');
  });

  // 测试6: 执行核销单
  test('执行核销单', async () => {
    await db.query('UPDATE verifications SET status = ? WHERE id = ?', ['executed', verificationId]);
    // 更新预支单状态为部分核销
    await db.query('UPDATE advances SET status = ? WHERE id = ?', ['partial_verification', advanceId]);
    // 更新预支单已核销金额
    await db.query('UPDATE advances SET total_reimbursed = ? WHERE id = ?', [300, advanceId]);
    
    const verification = await db.query('SELECT * FROM verifications WHERE id = ?', [verificationId]);
    expect(verification.rows[0].status).toBe('executed');
  });

  // 测试7: 检查预支单状态
  test('检查预支单状态', async () => {
    const advance = await db.query('SELECT * FROM advances WHERE id = ?', [advanceId]);
    expect(advance.rows[0].total_reimbursed).toBe(300);
    expect(advance.rows[0].status).toBe('partial_verification');
  });

  // 测试8: 创建结算核销单（退款）
  test('创建结算核销单（退款）', async () => {
    await db.query(
      'INSERT INTO verifications (advance_id, amount, currency, reason, verification_date, verification_code, status, applicant, advance_code, advance_amount, settlement, settlement_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
      [advanceId, 600, 'CNY', '结算核销（退款）', '2026-03-25', 'VER-TEST-002', 'executed', '隆林', 'ADV-TEST-001', 1000, 1, 100]
    );
    // 更新预支单状态为已完成
    await db.query('UPDATE advances SET status = ? WHERE id = ?', ['completed', advanceId]);
    // 更新预支单已核销金额
    await db.query('UPDATE advances SET total_reimbursed = ? WHERE id = ?', [900, advanceId]);
  });

  // 测试9: 检查预支单是否已完结
  test('检查预支单是否已完结', async () => {
    const advance = await db.query('SELECT * FROM advances WHERE id = ?', [advanceId]);
    expect(advance.rows[0].total_reimbursed).toBe(900);
    expect(advance.rows[0].status).toBe('completed');
  });

  // 测试10: 获取预支核销状态列表
  test('获取预支核销状态列表', async () => {
    const result = await db.query('SELECT * FROM advances');
    expect(Array.isArray(result.rows)).toBe(true);
    expect(result.rows.length).toBeGreaterThan(0);
  });
});