import { DEFAULT_GOAL_EMOJI } from '../../../../constants';

export const toMicros = value => {
  const numeric = Number(value || 0);
  if (!Number.isFinite(numeric) || numeric <= 0) return 0;
  return Math.round(numeric * 1_000_000);
};

export const fromMicros = value => {
  const numeric = Number(value || 0);
  if (!Number.isFinite(numeric)) return 0;
  return (numeric / 1_000_000).toFixed(2);
};

export const formatTxDate = timestamp => {
  const date = new Date(Number(timestamp || Date.now()));
  return date.toLocaleDateString(undefined, {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  });
};

export async function fetchSavingsInterestPayouts(
  pubKeyHex,
  limit = 10,
  offset = 0,
) {
  try {
    const res = await fetch(
      `https://rewards.flashnet.xyz/v1/rewards/${pubKeyHex}/payouts?limit=${limit}&offset=${offset}`,
    );
    if (!res.ok) return [];
    const data = await res.json();
    if (Array.isArray(data)) return data;
    if (Array.isArray(data.payouts)) return data.payouts;
    return [];
  } catch {
    return [];
  }
}

export function parseGoalMetadata(metadata) {
  if (!metadata) return {};
  try {
    const parsed = JSON.parse(metadata);
    return typeof parsed === 'object' && parsed ? parsed : {};
  } catch {
    return {};
  }
}

export function serializeGoalMetadata(metadata) {
  if (!metadata || typeof metadata !== 'object') return null;
  try {
    return JSON.stringify(metadata);
  } catch {
    return null;
  }
}

function signedTransactionAmountMicros(transaction) {
  const amount = Math.max(
    0,
    Math.round(Number(transaction?.amountMicros || 0)),
  );
  return transaction?.type === 'withdrawal' ? -amount : amount;
}

export function computeSavingsBalanceMicros(transactions) {
  return transactions.reduce(
    (sum, tx) => sum + signedTransactionAmountMicros(tx),
    0,
  );
}

export function computeGoalBalanceMicros(goalId, transactions) {
  if (!goalId) return 0;
  return transactions
    .filter(tx => tx.goalId === goalId)
    .reduce((sum, tx) => sum + signedTransactionAmountMicros(tx), 0);
}

export function toLegacyDisplayTransaction(transaction, goalName, t) {
  const signedAmountMicros = signedTransactionAmountMicros(transaction);
  const isWithdrawal = transaction.type === 'withdrawal';
  const isBtcWithdrawl = transaction.type === 'bitcoinWithdrawal';

  const key = isWithdrawal
    ? goalName
      ? 'savings.withdrawalWithGoal'
      : 'savings.withdrawal'
    : goalName
    ? 'savings.depositWithGoal'
    : 'savings.deposit';

  return {
    txId: transaction.id,
    goalId: transaction.goalId,
    type: transaction.type,
    amountMicros: signedAmountMicros,
    createdAt: transaction.timestamp,
    description: isBtcWithdrawl
      ? t('savings.rewardsWithdrawal')
      : t(key, { goalName }),
  };
}

export function normalizeGoalForUI(goal) {
  if (!goal) return null;
  const metadata = parseGoalMetadata(goal.metadata);

  return {
    ...goal,
    amountMicros: goal.targetAmountMicros,
    emoji: metadata.emoji || DEFAULT_GOAL_EMOJI,
  };
}

export function resolveGoalAndAmount(goalIdOrPayload, maybeAmount) {
  if (
    goalIdOrPayload &&
    typeof goalIdOrPayload === 'object' &&
    !Array.isArray(goalIdOrPayload)
  ) {
    return {
      goalId: goalIdOrPayload.goalId,
      amount: goalIdOrPayload.amount,
    };
  }

  return {
    goalId: typeof goalIdOrPayload === 'string' ? goalIdOrPayload : undefined,
    amount: maybeAmount,
  };
}

export function mergeAndSortSavingsActivity(
  contributions = [],
  interestPayouts = [],
  t,
) {
  const normalised = interestPayouts.map(payout => ({
    txId: payout.txId,
    type: 'interest',
    amountMicros: toMicros(payout.payoutSats),
    createdAt: new Date(payout.createdAt).getTime(),
    description: t('savings.rewardsPayout'),
  }));

  return [...contributions, ...normalised].sort(
    (a, b) => b.createdAt - a.createdAt,
  );
}
