/**
 * useSearch 金额区间筛选（P4）。
 * 仓库无 testing-library，且 node_modules 中 react-dom(19.2.7) 与 react(19.1.0)
 * 版本不一致无法 SSR，因此 vi.mock('react') 提供最小 hook 实现，将 useSearch
 * 当纯函数直接调用（useState 恒返回初值 → useDebounce 直通，无需 timer）。
 */
import { vi, describe, expect, it } from 'vitest';

vi.mock('react', () => ({
  useMemo: (fn: () => unknown) => fn(),
  useState: (init: unknown) => [init, () => {}],
  useEffect: () => {},
  useCallback: (fn: unknown) => fn,
  useRef: (v: unknown) => ({ current: v }),
}));

import { useSearch, type SearchFilters } from '../src/hooks/useSearch';
import type { Transaction } from '../src/domain/core/types';

function tx(id: string, postings: { account: string; amount?: string }[]): Transaction {
  return {
    id, date: '2026-07-21', flag: '*', narration: id,
    postings: postings.map(p => ({ account: p.account, amount: p.amount, currency: 'CNY' })),
    tags: [], links: [], source: 'test', raw: '',
  };
}

describe('金额区间筛选', () => {
  const txs = [
    tx('expense35', [{ account: 'Assets:招行', amount: '-35' }, { account: 'Expenses:餐饮', amount: '35' }]),
    tx('expense200', [{ account: 'Assets:招行', amount: '-200' }, { account: 'Expenses:购物', amount: '200' }]),
    tx('income5000', [{ account: 'Assets:招行', amount: '5000' }, { account: 'Income:工资', amount: '-5000' }]),
  ];

  it('amountMin/amountMax 按主金额绝对值过滤', () => {
    // 三笔：支出 35、支出 200、收入 5000（收入主金额为负 → 绝对值 5000）
    const range = useSearch(txs, { amountMin: '30', amountMax: '300' } as SearchFilters);
    expect(range.map(t => t.id)).toEqual(['expense35', 'expense200']);

    const minOnly = useSearch(txs, { amountMin: '1000' } as SearchFilters);
    expect(minOnly.map(t => t.id)).toEqual(['income5000']);
  });

  it('无金额 posting 的交易在设了下限时被排除', () => {
    const withNoAmount = [
      ...txs,
      tx('noAmount', [{ account: 'Assets:招行' }, { account: 'Expenses:其他' }]),
    ];
    const result = useSearch(withNoAmount, { amountMin: '1' } as SearchFilters);
    expect(result.map(t => t.id)).not.toContain('noAmount');
    expect(result).toHaveLength(3);
  });

  it('不设区间时不过滤（回归兜底）', () => {
    const result = useSearch(txs, {});
    expect(result).toHaveLength(3);
  });
});
