/**
 * offer-rates.ts — illustrative market rates feeding the Trade-In BENEFIT
 * CALCULATOR (OfferCard, Секция 4 «Формирование выкупной стоимости»).
 *
 * ⚠️ DEFAULTS = generic РФ-market rates (по образцу отчёта Brusnika p.4),
 *    НЕ официальный оффер «Практики». Это illustrative сравнение издержек
 *    самостоятельной продажи — проценты/суммы ориентировочные.
 *
 * TODO(commercial): заменить значения ниже на реальные коммерческие условия
 * «Практики» (точные % торга/риелтора, фактическая стоимость аренды/юр.
 * сопровождения/рекламы). Это единственное место для правки ставок —
 * компонент и расчёт берут всё отсюда.
 */

/** Ставка-диапазон в долях от базы (0.05 = 5%). */
export interface PctRange {
  lo: number;
  hi: number;
}

/** Фиксированная статья расходов (₽), диапазон lo–hi. lo == hi → одно число. */
export interface RubRange {
  lo: number;
  hi: number;
}

export interface OfferRates {
  /** Торг покупателей — доля от цены в объявлении. */
  bargain: PctRange;
  /** Услуги риелтора — доля от цены сделки (после торга). */
  realtor: PctRange;
  /** Аренда жилья на время поиска/сделки (₽ за весь срок). */
  rentAfterDeal: RubRange;
  /** Юридическое сопровождение (₽). */
  legal: RubRange;
  /** Реклама / платные показы за период экспозиции (₽). */
  advertising: RubRange;
  /** Срок, на который заложены аренда/реклама (для подписей). */
  periodMonths: number;
}

/**
 * DEFAULTS — типовые рыночные ставки (Brusnika p.4). НЕ оффер «Практики».
 * TODO(commercial): replace with Praktika terms.
 */
export const DEFAULT_OFFER_RATES: OfferRates = {
  bargain: { lo: 0.05, hi: 0.15 }, // 5–15%
  realtor: { lo: 0.02, hi: 0.03 }, // 2–3%
  rentAfterDeal: { lo: 90_000, hi: 150_000 }, // ~3 мес
  legal: { lo: 19_250, hi: 50_000 }, // «от ~19k»
  advertising: { lo: 4_000, hi: 36_000 }, // платные показы, 3 мес
  periodMonths: 3,
};

/** Граница ползунка «торг» (доля), чтобы менеджер мог подвигать в пределах рынка. */
export const BARGAIN_SLIDER = {
  min: 0,
  max: 0.2,
  step: 0.01,
} as const;

/** Одна строка таблицы издержек после расчёта от введённой цены. */
export interface CostRow {
  key: string;
  /** Название статьи. */
  name: string;
  /** Подпись (как считается). */
  sub: string;
  /** Стоимость при самостоятельной продаже, ₽. */
  selfLo: number;
  selfHi: number;
  /** Подпись в колонке Trade-In (что берёт сервис на себя). */
  tradeLabel: string;
}

export interface OfferBreakdown {
  rows: CostRow[];
  /** Сумма всех издержек самостоятельной продажи. */
  totalLo: number;
  totalHi: number;
  /** Средние потери как % от базовой цены (для баннера). */
  totalPctMid: number;
}

/**
 * computeBreakdown — pure-функция: цена в объявлении + ставка торга → разбивка
 * издержек. Используется компонентом для LIVE-пересчёта при вводе.
 *
 * @param askingPrice  цена квартиры в объявлении (₽), редактируемая пользователем
 * @param bargainPct   фактическая доля торга (0.10 = 10%), из ползунка
 * @param rates        конфиг ставок (по умолчанию DEFAULT_OFFER_RATES)
 */
export function computeBreakdown(
  askingPrice: number,
  bargainPct: number,
  rates: OfferRates = DEFAULT_OFFER_RATES,
): OfferBreakdown {
  const base = Math.max(0, askingPrice);

  // Торг: диапазон рынка (lo–hi из конфига), но если пользователь двигает
  // ползунок — показываем выбранное значение как «середину» с рыночной вилкой.
  const bargainLoPct = Math.min(bargainPct, rates.bargain.lo);
  const bargainHiPct = Math.max(bargainPct, rates.bargain.hi);
  const bargainLo = Math.round(base * bargainLoPct);
  const bargainHi = Math.round(base * bargainHiPct);

  // Риелтор: % от цены ПОСЛЕ торга (то, что реально получит продавец).
  const afterBargainHi = base - bargainLo; // меньший торг → больше база
  const afterBargainLo = base - bargainHi; // больший торг → меньше база
  const realtorLo = Math.round(afterBargainLo * rates.realtor.lo);
  const realtorHi = Math.round(afterBargainHi * rates.realtor.hi);

  const period = `${rates.periodMonths} мес`;

  const rows: CostRow[] = [
    {
      key: "bargain",
      name: "Торг покупателей",
      sub: `${pct(bargainLoPct)}–${pct(bargainHiPct)} от цены объявления`,
      selfLo: bargainLo,
      selfHi: bargainHi,
      tradeLabel: "не применимо",
    },
    {
      key: "realtor",
      name: "Услуги риелтора",
      sub: `${pct(rates.realtor.lo)}–${pct(rates.realtor.hi)} от цены сделки`,
      selfLo: realtorLo,
      selfHi: realtorHi,
      tradeLabel: "бесплатно",
    },
    {
      key: "rent",
      name: "Аренда жилья после сделки",
      sub: `съём на время поиска, ${period}`,
      selfLo: rates.rentAfterDeal.lo,
      selfHi: rates.rentAfterDeal.hi,
      tradeLabel: "бесплатно",
    },
    {
      key: "legal",
      name: "Юридическое сопровождение",
      sub: "проверка, договор, регистрация",
      selfLo: rates.legal.lo,
      selfHi: rates.legal.hi,
      tradeLabel: "бесплатно",
    },
    {
      key: "ads",
      name: "Расходы на рекламу",
      sub: `платные показы Циан / Авито, ${period}`,
      selfLo: rates.advertising.lo,
      selfHi: rates.advertising.hi,
      tradeLabel: "бесплатно",
    },
  ];

  const totalLo = rows.reduce((s, r) => s + r.selfLo, 0);
  const totalHi = rows.reduce((s, r) => s + r.selfHi, 0);
  const totalPctMid = base > 0 ? (((totalLo + totalHi) / 2) / base) * 100 : 0;

  return { rows, totalLo, totalHi, totalPctMid };
}

function pct(frac: number): string {
  return `${(frac * 100).toFixed(0)}%`;
}
