/**
 * 图表统计纯函数（plan.md「5.2 图表与可视化」的数据计算部分）。
 * 从 components/charts/ 抽出，使可单测（不依赖 react-native）。
 *
 * 内部聚合使用 addDecimals（decimal string）保证精度，
 * 最终返回 number 供图表组件做 SVG 坐标计算。
 */

import { addDecimals, negateDecimal } from '../core/decimal';
import type { Transaction } from '../core/types';

/** 按月分组统计。 */
export function groupByMonth(transactions: Transaction[]): { month: string; income: number; expense: number }[] {
  const byMonth = new Map<string, { income: string[]; expense: string[] }>();
  for (const t of transactions) {
    const month = t.date.slice(0, 7);
    const cur = byMonth.get(month) ?? { income: [], expense: [] };
    for (const p of t.postings) {
      if (!p.amount) continue;
      if (p.account.startsWith('Income')) {
        cur.income.push(negateDecimal(p.amount));
      }
      if (p.account.startsWith('Expenses')) {
        cur.expense.push(p.amount);
      }
    }
    byMonth.set(month, cur);
  }
  return [...byMonth.entries()]
    .map(([month, v]) => ({
      month,
      income: parseFloat(addDecimals(v.income.length ? v.income : ['0'])),
      expense: parseFloat(addDecimals(v.expense.length ? v.expense : ['0'])),
    }))
    .sort((a, b) => a.month.localeCompare(b.month));
}

/** 按分类统计支出。 */
export function groupByCategory(transactions: Transaction[]): { category: string; amount: number; percentage: number }[] {
  const byCategory = new Map<string, string[]>();
  const allExpenses: string[] = [];
  for (const t of transactions) {
    for (const p of t.postings) {
      if (p.amount && p.account.startsWith('Expenses')) {
        const existing = byCategory.get(p.account) ?? [];
        existing.push(p.amount);
        byCategory.set(p.account, existing);
        allExpenses.push(p.amount);
      }
    }
  }
  const totalStr = addDecimals(allExpenses.length ? allExpenses : ['0']);
  const total = parseFloat(totalStr);
  return [...byCategory.entries()]
    .map(([category, amounts]) => {
      const amountStr = addDecimals(amounts);
      const amount = parseFloat(amountStr);
      return {
        category,
        amount,
        percentage: total > 0 ? Math.round((amount / total) * 100) : 0,
      };
    })
    .sort((a, b) => b.amount - a.amount);
}

/** 按日期统计支出。 */
export function dailyExpenseMap(transactions: Transaction[]): Map<string, number> {
  const byDate = new Map<string, string[]>();
  for (const t of transactions) {
    const date = t.date.slice(0, 10);
    const existing = byDate.get(date) ?? [];
    for (const p of t.postings) {
      if (p.amount && p.account.startsWith('Expenses')) {
        existing.push(p.amount);
      }
    }
    if (existing.length > 0) byDate.set(date, existing);
  }
  const result = new Map<string, number>();
  for (const [date, amounts] of byDate) {
    result.set(date, parseFloat(addDecimals(amounts)));
  }
  return result;
}
