// portfolio-data.jsx — ru number formatting helpers + API→PF mapping
// Exports to window: fmt (formatting), mapPortfolio (API→PF), PF (mock fallback)

// ---------- formatting ----------
const MINUS = "−"; // proper minus sign −
const NBSP = " ";

function group(intPart) {
  // space thousands separator, ru style
  return intPart.replace(/\B(?=(\d{3})+(?!\d))/g, NBSP);
}

function num(value, decimals) {
  const neg = value < 0;
  const abs = Math.abs(value);
  let s = abs.toFixed(decimals);
  let [int, dec] = s.split(".");
  int = group(int);
  let out = dec != null && decimals > 0 ? int + "," + dec : int;
  return { neg, out };
}

// auto-decimals for prices: <1 → 4 decimals, else 2
function priceDecimals(v) {
  return Math.abs(v) > 0 && Math.abs(v) < 1 ? 4 : 2;
}
// auto-decimals for quantity: <10 → up to 4, else 2
function qtyDecimals(v) {
  return Math.abs(v) < 10 ? 4 : 2;
}

const fmt = {
  MINUS,
  NBSP,
  // money: cur '$' | '€'; opts {dec, sign}
  money(value, cur = "$", opts = {}) {
    const dec = opts.dec != null ? opts.dec : 2;
    const { neg, out } = num(value, dec);
    const sign = opts.sign ? (neg ? MINUS : "+") : neg ? MINUS : "";
    return sign + cur + out;
  },
  price(value, cur = "$") {
    let { neg, out } = num(value, priceDecimals(value));
    // trim trailing ",00" / extra zeros for cleaner prices
    if (out.indexOf(",") !== -1) out = out.replace(/0+$/, "").replace(/,$/, "");
    return (neg ? MINUS : "") + cur + out;
  },
  qty(value) {
    // trim trailing zeros but keep ru comma
    const dec = qtyDecimals(value);
    let { out } = num(value, dec);
    if (out.indexOf(",") !== -1) out = out.replace(/0+$/, "").replace(/,$/, "");
    return out;
  },
  pct(value, opts = {}) {
    const dec = opts.dec != null ? opts.dec : 1;
    const { neg, out } = num(value, dec);
    const sign = opts.sign ? (neg ? MINUS : "+") : neg ? MINUS : "";
    return sign + out + "%";
  },
  rate(value) {
    const { out } = num(value, 4);
    return out;
  },
};

// ---------- API → PF mapping ----------
// Преобразует ответ portfolio_db.get_full_portfolio() в форму, которую рендерит
// PortfolioScreen (см. структуру PF ниже). Расчёты не дублируются — берём готовые поля.
function mapPortfolio(api) {
  const fx = api.eur_usd_rate || 1;
  const positions = api.positions || [];
  const lp = api.lp || [];
  const loans = api.loans || [];
  const cash = api.cash || { total_usd: 0, breakdown: [], percent_of_portfolio: 0 };

  return {
    empty: !!api.empty,
    updatedAt: Date.now(),
    fx,
    summary: {
      investedEur: api.total_invested_eur || 0,
      valueUsd: api.total_assets_usd || 0,
      valueEur: fx > 0 ? (api.total_assets_usd || 0) / fx : 0,
      pnlEur: api.pnl_eur || 0,
      pnlPct: api.pnl_eur_pct || 0,
      debtUsd: api.loans_total_usd || 0,
      netUsd: api.net_value_usd || 0,
      netEur: api.net_value_eur || 0,
      // Валюта пользователя (Portfolio_saas мультивалютный): символ для money() и
      // код для меток курса. «eur»-имена полей выше оставлены ради переиспользования
      // дизайна price_alert, но значения — в этой валюте.
      cur: api.currency_symbol || "$",
      curCode: api.currency || "USD",
    },
    coins: positions.map((p) => ({
      ticker: p.symbol,
      name: p.symbol,
      share: p.percent_of_portfolio || 0,
      invested: p.invested_amount || 0,
      qty: p.quantity || 0,
      avg: p.avg_entry_price || 0,
      price: p.current_price || 0,
      value: p.current_value || 0,
      pnl: (p.current_value || 0) - (p.invested_amount || 0),
      pnlPct: (p.drawdown_percent || 0) - 100,
    })),
    cash: {
      total: cash.total_usd || 0,
      share: cash.percent_of_portfolio || 0,
      items: (cash.breakdown || []).map((b) => ({ ticker: b.symbol, amount: b.amount })),
    },
    lp: lp.map((l) => ({
      id: l.id,
      pair: `${l.token0_symbol} / ${l.token1_symbol}`,
      venue: l.dex || (l.is_v3 ? "Uniswap V3" : "Uniswap V2"),
      share: l.percent_of_portfolio || 0,
      isV3: !!l.is_v3,
      rangeLow: l.price_lower,
      rangeHigh: l.price_upper,
      curPrice: l.current_price,
      inRange: l.in_range,
      invested: l.invested_usd || 0,
      value: l.current_value_usd || 0,
      il: l.impermanent_loss_pct || 0,
      pnl: l.pnl_usd || 0,
      pnlPct: l.pnl_pct || 0,
      composition: [
        { ticker: l.token0_symbol, qty: l.amount0 || 0, value: l.value0_usd || 0, weight: Math.round(l.proportion0_pct || 0) },
        { ticker: l.token1_symbol, qty: l.amount1 || 0, value: l.value1_usd || 0, weight: Math.round(l.proportion1_pct || 0) },
      ],
    })),
    loans: loans.map((l) => ({
      id: l.id,
      amount: l.amount,
      ticker: l.currency,
      collateral: l.collateral || "—",
    })),
    debtTotal: api.loans_total_usd || 0,
  };
}

// ---------- mock data (fallback for offline design preview only) ----------
const PF = {
  updatedAt: Date.now() - 3 * 60 * 1000,
  fx: 1.08,
  summary: { investedEur: 60000, valueUsd: 77220, valueEur: 71500, pnlEur: 8722, pnlPct: 14.5, debtUsd: 3000, netUsd: 74220, netEur: 68722 },
  coins: [
    { ticker: "BTC", name: "Bitcoin", share: 43.1, invested: 28000, qty: 0.35, avg: 80000, price: 95000, value: 33250, pnl: 5250, pnlPct: 18.8 },
    { ticker: "ETH", name: "Ethereum", share: 16.9, invested: 12000, qty: 4.2, avg: 2857, price: 3100, value: 13020, pnl: 1020, pnlPct: 8.5 },
    { ticker: "SOL", name: "Solana", share: 8.7, invested: 7500, qty: 50, avg: 150, price: 135, value: 6750, pnl: -750, pnlPct: -10.0 },
  ],
  cash: { total: 8400, share: 10.9, items: [{ ticker: "USDC", amount: 5400 }, { ticker: "USDT", amount: 3000 }] },
  lp: [
    { id: 1, pair: "cbBTC / USDC", venue: "Uniswap V3", share: 20.5, isV3: true, rangeLow: 85000, rangeHigh: 110000, curPrice: 95000, inRange: true, invested: 15000, value: 15800, il: -0.4, pnl: 800, pnlPct: 5.3,
      composition: [{ ticker: "cbBTC", qty: 0.08, value: 7600, weight: 48 }, { ticker: "USDC", qty: 8200, value: 8200, weight: 52 }] },
  ],
  loans: [{ id: 1, amount: 3000, ticker: "USDC", collateral: "cbBTC" }],
  debtTotal: 3000,
};

Object.assign(window, { PF, fmt, mapPortfolio });
