/**
 * 交易搜索 Hook（plan.md「1.4 交易搜索页面」）。
 * 多维筛选（关键字/分类/账户/日期/标签/方向）。
 */

import { useMemo } from 'react';
import type { Transaction } from '../domain/core/types';
import { compareDecimals } from '../domain/core/decimal';
import { useDebounce } from './useDebounce';

export interface SearchFilters {
  keyword?: string;
  account?: string;
  dateFrom?: string;
  dateTo?: string;
  tags?: string[];
  direction?: 'income' | 'expense' | 'transfer';
  amountMin?: string;
  amountMax?: string;
}

export function useSearch(transactions: Transaction[], filters: SearchFilters): Transaction[] {
  const debouncedKeyword = useDebounce(filters.keyword, 300);

  // 解构 filters 为独立原始值，避免对象引用不稳定导致 useMemo 频繁重算
  const { account, dateFrom, dateTo, tags, direction, amountMin, amountMax } = filters;

  const debouncedFilters = useMemo(
    () => ({ keyword: debouncedKeyword, account, dateFrom, dateTo, tags, direction, amountMin, amountMax }),
    [debouncedKeyword, account, dateFrom, dateTo, tags, direction, amountMin, amountMax],
  );

  return useMemo(() => {
    return transactions.filter(t => {
      if (debouncedFilters.keyword) {
        const kw = debouncedFilters.keyword.toLowerCase();
        const text = `${t.narration ?? ''} ${t.payee ?? ''}`.toLowerCase();
        if (!text.includes(kw)) return false;
      }
      if (debouncedFilters.account) {
        if (!t.postings.some(p => p.account.includes(debouncedFilters.account!))) return false;
      }
      const date = t.date.slice(0, 10);
      if (debouncedFilters.dateFrom && date < debouncedFilters.dateFrom) return false;
      if (debouncedFilters.dateTo && date > debouncedFilters.dateTo) return false;
      if (debouncedFilters.tags && debouncedFilters.tags.length > 0) {
        if (!debouncedFilters.tags.some(tag => t.tags.includes(tag))) return false;
      }
      if (debouncedFilters.direction) {
        const isExpense = t.postings.some(p => p.account.startsWith('Expenses'));
        const isIncome = t.postings.some(p => p.account.startsWith('Income'));
        const isTransfer = !isExpense && !isIncome;
        if (debouncedFilters.direction === 'expense' && !isExpense) return false;
        if (debouncedFilters.direction === 'income' && !isIncome) return false;
        if (debouncedFilters.direction === 'transfer' && !isTransfer) return false;
      }
      if (debouncedFilters.amountMin || debouncedFilters.amountMax) {
        const raw = t.postings.find(p => p.amount)?.amount;
        const abs = raw?.replace(/^-/, '');
        if (debouncedFilters.amountMin && (!abs || compareDecimals(abs, debouncedFilters.amountMin) < 0)) return false;
        if (debouncedFilters.amountMax && abs && compareDecimals(abs, debouncedFilters.amountMax) > 0) return false;
      }
      return true;
    });
  }, [transactions, debouncedFilters]);
}
