/* MBEX — Home screen */

function getHomeRateMeta(dir, rates) {
  const buying = dir === "buy";
  const rate = Number((buying ? rates.buy : rates.sell) || 0);
  const marketRate = Number(
    buying
      ? (rates.marketSell || rates.cbr || rates.buy || 0)
      : (rates.marketBuy || rates.cbr || rates.sell || 0),
  );
  const enabled = buying
    ? rates.tradeAvailability?.buy_enabled !== false
    : rates.tradeAvailability?.sell_enabled !== false;
  const action = buying ? "Вы покупаете USDT" : "Вы продаёте USDT";
  const toneClass = buying ? "rate-hero-buy" : "rate-hero-sell";
  return { buying, rate, marketRate, enabled, action, toneClass };
}

function formatRateTimestamp(value) {
  if (!value) {
    return "Обновляется";
  }
  const parsed = Date.parse(value);
  if (!Number.isFinite(parsed)) {
    return "Обновляется";
  }
  return `Актуально ${new Date(parsed).toLocaleString("ru-RU", {
    day: "2-digit",
    month: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  }).replace(", ", " в ")}`;
}

function getRateRange(data, fallbackRate) {
  const values = (Array.isArray(data) ? data : [])
    .map((item) => Number(typeof item === "object" ? item.value : item))
    .filter((item) => Number.isFinite(item) && item > 0);
  const fallback = Number(fallbackRate) || 0;
  return {
    min: values.length ? Math.min(...values) : fallback,
    max: values.length ? Math.max(...values) : fallback,
  };
}

function formatRateTitle(value) {
  if (!value || !Number.isFinite(Date.parse(value))) {
    return "Курс обновляется";
  }
  return `Обновлено ${new Date(Date.parse(value)).toLocaleString("ru-RU", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  })}`;
}

function RateHero({ dir, app }) {
  const [isRateInfoOpen, setIsRateInfoOpen] = React.useState(false);
  const rates = app.publicState.rates;
  const meta = getHomeRateMeta(dir, rates);
  const marketDiff = meta.marketRate > 0 && meta.rate > 0
    ? meta.rate - meta.marketRate
    : 0;
  const marketDeltaPct = meta.marketRate > 0 && meta.rate > 0
    ? (marketDiff / meta.marketRate) * 100
    : 0;
  const chartData = meta.buying ? rates.buyPoints : rates.sellPoints;
  const updatedLabel = formatRateTimestamp(rates.updatedAt);
  const rateRange = getRateRange(chartData, meta.rate);
  const rateFixingInfo = meta.buying
    ? "Курс фиксируется после пересчёта средств."
    : "Курс фиксируется после поступления и проверки USDT на одноразовый кошелёк.";

  React.useEffect(() => {
    setIsRateInfoOpen(false);
  }, [dir]);

  return (
    <section className={`rate-hero ${meta.toneClass} ${!meta.enabled ? "is-disabled" : ""}`}>
      <div className="rate-hero-top">
        <div className="rate-hero-main">
          <div className="rate-hero-label">USDT / RUB</div>
          <div className="rate-hero-value">
            <span className="num">{window.MBEX.fmtRub2(meta.rate)}</span>
            <span>₽</span>
            <em className={marketDeltaPct >= 0 ? "is-up" : "is-down"}>
              {marketDeltaPct >= 0 ? "+" : ""}{marketDeltaPct.toFixed(1)}%
            </em>
          </div>
          <div className="rate-hero-updated" title={formatRateTitle(rates.updatedAt)}>
            <span />
            {updatedLabel}
          </div>
        </div>
        <div className="rate-hero-range" aria-label="Минимум и максимум курса за период">
          <div>
            <span>Мин.</span>
            <strong className="num">{window.MBEX.fmtRub2(rateRange.min)} ₽</strong>
          </div>
          <div>
            <span>Макс.</span>
            <strong className="num">{window.MBEX.fmtRub2(rateRange.max)} ₽</strong>
          </div>
        </div>
      </div>

      <HeroRateChart data={chartData} updatedAt={rates.updatedAt} />
      <div className="rate-hero-info">
        <div className="rate-hero-info-summary">
          <span>{meta.action}</span>
          <button
            type="button"
            aria-expanded={isRateInfoOpen}
            aria-controls={`rate-fixing-info-${dir}`}
            onClick={() => setIsRateInfoOpen(true)}
          >
            Как фиксируется курс?
          </button>
        </div>
        <div
          id={`rate-fixing-info-${dir}`}
          className={`rate-hero-info-details ${isRateInfoOpen ? "is-open" : ""}`}
          aria-hidden={!isRateInfoOpen}
        >
          <div>
            <p>{rateFixingInfo}</p>
            <button
              type="button"
              aria-label="Закрыть информацию о фиксации курса"
              tabIndex={isRateInfoOpen ? 0 : -1}
              onClick={() => setIsRateInfoOpen(false)}
            >
              <Icons.close size={18} sw={2.2} />
            </button>
          </div>
        </div>
      </div>

      {!meta.enabled ? (
        <div className="rate-hero-note">
          {meta.buying ? "Покупка временно недоступна" : "Продажа временно недоступна"}
        </div>
      ) : null}

    </section>
  );
}

function DirectionSwitcher({ dir, setDir, app }) {
  const rates = app.publicState.rates;
  return (
    <div className="home-direction-switcher" aria-label="Направление обмена">
      <button
        type="button"
        data-testid="direction-buy"
        className={dir === "buy" ? "is-active" : ""}
        onClick={() => setDir("buy")}
      >
        <Icons.arrowUp size={17} sw={2.2} />
        Купить
        {rates.tradeAvailability?.buy_enabled === false ? <span>off</span> : null}
      </button>
      <button
        type="button"
        data-testid="direction-sell"
        className={dir === "sell" ? "is-active" : ""}
        onClick={() => setDir("sell")}
      >
        <Icons.arrowDown size={17} sw={2.2} />
        Продать
        {rates.tradeAvailability?.sell_enabled === false ? <span>off</span> : null}
      </button>
    </div>
  );
}

const CALCULATOR_RECEIVE_NOTICE = "Обратите внимание: сумма в калькуляторе является предварительной и не включает комиссию сервиса и комиссию сети TRC20. Итоговая сумма к получению с учетом всех комиссий указана ниже в расчете";

function CalculatorReceiveNotice({ onClose }) {
  React.useEffect(() => {
    const handleKeyDown = (event) => {
      if (event.key === "Escape") {
        onClose();
      }
    };
    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [onClose]);

  return ReactDOM.createPortal(
    <div className="calc-notice-overlay" onClick={onClose}>
      <section
        className="calc-notice-sheet"
        role="dialog"
        aria-modal="true"
        aria-label="Предварительный расчёт"
        onClick={(event) => event.stopPropagation()}
      >
        <div className="calc-notice-head">
          <strong>Предварительный расчёт</strong>
          <button type="button" onClick={onClose} aria-label="Закрыть уведомление">
            <Icons.close size={19} sw={2.2} />
          </button>
        </div>
        <p>{CALCULATOR_RECEIVE_NOTICE}</p>
      </section>
    </div>,
    document.body,
  );
}

function CalcCard({ dir, setDir, payInput, setPayInput, app, onCreate }) {
  const rates = app.publicState.rates;
  const profile = app.privateState.profile || {};
  const referral = app.privateState.referral || {};
  const [activeInput, setActiveInput] = React.useState("pay");
  const [receiveInput, setReceiveInput] = React.useState("");
  const [isReceiveNoticeOpen, setIsReceiveNoticeOpen] = React.useState(false);
  const meta = getHomeRateMeta(dir, rates);
  const buying = meta.buying;
  const rate = meta.rate;
  const networkFeeUsdt = Number(rates.commissionSettings?.network_fee_usdt || 0);
  const rawPayInput = normalizeCalcInput(payInput);
  const rawReceiveInput = normalizeCalcInput(receiveInput);
  const payInputNum = parseCalcInput(rawPayInput);
  const receiveInputNum = parseCalcInput(rawReceiveInput);
  const reversePayNum = activeInput === "receive"
    ? (
      buying
        ? window.MBEX.calculateBuyRubFromGrossUsdt(receiveInputNum, rate)
        : window.MBEX.calculateSellUsdtFromPayoutRub(receiveInputNum, rate, profile)
    )
    : 0;
  const rawPayNum = activeInput === "receive" ? reversePayNum : payInputNum;
  const payNum = buying
    ? window.MBEX.snapRubStepAmount(rawPayNum, 1000)
    : rawPayNum;
  const draftPayNum = roundCalcAmount(payNum, buying ? 0 : 2);

  const buyEstimate = buying
    ? window.MBEX.calculateBuyEstimate(payNum, rate, profile, referral, networkFeeUsdt)
    : null;
  const sellEstimate = !buying
    ? window.MBEX.calculateSellEstimate(payNum, rate, profile)
    : null;

  const receiveValue = activeInput === "receive"
    ? receiveInput
    : formatCalcInput(
      buying ? buyEstimate?.grossUsdt : sellEstimate?.payoutRub,
      buying ? 2 : 0,
    );
  const payValue = activeInput === "receive"
    ? formatCalcInput(payNum, buying ? 0 : 2)
    : payInput;

  const minSell = Number(rates.sellLimits?.min_usdt || 65);
  const maxSell = Number(rates.sellLimits?.max_usdt || 100000);
  const buyEnabled = rates.tradeAvailability?.buy_enabled !== false;
  const sellEnabled = rates.tradeAvailability?.sell_enabled !== false;
  const currentEnabled = buying ? buyEnabled : sellEnabled;
  const sumOk = buying
    ? rawPayNum > 0 && payNum >= 1000
    : payNum >= minSell && payNum <= maxSell;
  const canContinue = currentEnabled && sumOk && rawPayNum > 0;

  function onInput(event) {
    setActiveInput("pay");
    setReceiveInput("");
    setPayInput(event.target.value.replace(/[^\d.,]/g, ""));
  }

  function onReceiveInput(event) {
    setActiveInput("receive");
    setReceiveInput(event.target.value.replace(/[^\d.,]/g, ""));
  }

  function snapPayInput() {
    if (!buying || activeInput !== "pay" || payInputNum <= 0) {
      return;
    }
    setPayInput(formatCalcInput(window.MBEX.snapRubStepAmount(payInputNum, 1000), 0));
  }

  function onSwap() {
    if (activeInput === "receive") {
      setPayInput(formatCalcInput(payNum, buying ? 0 : 2));
      setReceiveInput("");
      setActiveInput("pay");
    }
    setDir(buying ? "sell" : "buy");
  }

  function disabledText() {
    if (buying && !buyEnabled) {
      return "Покупка USDT временно отключена в настройках Mini App.";
    }
    if (!buying && !sellEnabled) {
      return "Продажа USDT временно отключена в настройках Mini App.";
    }
    return "";
  }

  return (
    <div className="card card-pad calc-card">
      {!currentEnabled ? (
        <div className="status-note warn" style={{ marginBottom: 14 }}>
          {disabledText()}
        </div>
      ) : null}

      <div className="card-2 calc-field">
        <div className="between" style={{ marginBottom: 6 }}>
          <span className="field-lbl" style={{ margin: 0 }}>Вы платите</span>
          <span className="muted-3" style={{ fontSize: 11.5, fontWeight: 700, whiteSpace: "nowrap" }}>
            {buying ? "Мин. 1 000 ₽ · шаг 500 ₽" : `Мин. ${minSell} USDT`}
          </span>
        </div>
        <div className="amount-row">
          <input
            className="amount-input num"
            data-testid="calculator-pay-input"
            inputMode="decimal"
            placeholder="0"
            value={payValue}
            onChange={onInput}
            onBlur={snapPayInput}
          />
          <div className="cur-chip">
            <Coin kind={buying ? "rub" : "usdt"} />
            {buying ? "RUB" : "USDT"}
          </div>
        </div>
      </div>

      <div className="center" style={{ justifyContent: "center", margin: "-8px 0", position: "relative", zIndex: 2 }}>
        <div className="swapbtn" onClick={onSwap}>
          <Icons.swap size={20} sw={2} />
        </div>
      </div>

      <div className="card-2 calc-field calc-field-result">
        <div className="calc-result-head">
          <span className="field-lbl" style={{ margin: 0 }}>Вы получаете</span>
          <button
            type="button"
            className="calc-result-info"
            onClick={() => setIsReceiveNoticeOpen(true)}
            aria-label="Подробнее о предварительном расчёте"
            aria-haspopup="dialog"
          >
            <Icons.info size={16} />
          </button>
        </div>
        <div className="amount-row" style={{ marginTop: 6 }}>
          <input
            className="amount-input num calc-receive-input"
            inputMode="decimal"
            placeholder="0"
            value={receiveValue}
            onChange={onReceiveInput}
          />
          <div className="cur-chip">
            <Coin kind={buying ? "usdt" : "rub"} />
            {buying ? "USDT" : "RUB"}
          </div>
        </div>
      </div>

      <div className="calc-summary">
        <div className="between" style={{ gap: 10, alignItems: "flex-start" }}>
          <span className="num" style={{ fontSize: 13.5, fontWeight: 700, color: "var(--text-2)", whiteSpace: "nowrap" }}>
            1 USDT = {window.MBEX.fmtRub2(rate)} ₽
          </span>
        </div>

        <div className="mini-legend" style={{ marginTop: 12 }}>
          {buying ? (
            <>
              <div className="mini-legend-row">
                <span>≈ Предварительно</span>
                <strong>{window.MBEX.fmtUsdt(buyEstimate?.walletUsdt || 0)} USDT</strong>
              </div>
              <div className="mini-legend-row">
                <span>Комиссия</span>
                <strong>{window.MBEX.fmtUsdt(buyEstimate?.commissionUsdt || 0)} USDT / {window.MBEX.fmtPct(buyEstimate?.commissionPct || 0)}%</strong>
              </div>
              <div className="mini-legend-row">
                <span>Комиссия сети TRC-20</span>
                <strong>{window.MBEX.fmtUsdt(buyEstimate?.networkFeeUsdt || 0)} USDT</strong>
              </div>
            </>
          ) : (
            <>
              <div className="mini-legend-row">
                <span>≈ Предварительно</span>
                <strong>{window.MBEX.fmtRub(sellEstimate?.payoutRub || 0)} ₽</strong>
              </div>
              <div className="mini-legend-row">
                <span>Комиссия</span>
                <strong>{window.MBEX.fmtRub(sellEstimate?.commissionRub || 0)} ₽ / {window.MBEX.fmtPct(sellEstimate?.commissionPct || 0)}%</strong>
              </div>
            </>
          )}
        </div>
      </div>
      <button
        className="btn btn-primary home-create-btn"
        data-testid="open-create-order"
        disabled={!canContinue}
        onClick={() => {
          if (activeInput === "receive") {
            setPayInput(formatCalcInput(payNum, buying ? 0 : 2));
          }
          onCreate({
            dir,
            inputValue: draftPayNum,
            rate,
            buyEstimate,
            sellEstimate,
          });
        }}
      >
        {!currentEnabled
          ? "Направление недоступно"
          : (!sumOk && payNum > 0)
            ? (buying ? "Сумма ниже минимума" : "Сумма вне лимитов")
            : "Создать заявку"}
        <Icons.chevR size={18} sw={2.4} />
      </button>
      {isReceiveNoticeOpen ? (
        <CalculatorReceiveNotice onClose={() => setIsReceiveNoticeOpen(false)} />
      ) : null}
    </div>
  );
}

function normalizeCalcInput(value) {
  return String(value || "").replace(/\s/g, "").replace(",", ".");
}

function parseCalcInput(value) {
  const parsed = Number(normalizeCalcInput(value) || 0);
  return Number.isFinite(parsed) ? parsed : 0;
}

function formatCalcInput(value, maximumFractionDigits) {
  const num = Number(value || 0);
  if (!Number.isFinite(num) || num <= 0) {
    return "";
  }
  return num.toLocaleString("ru-RU", {
    maximumFractionDigits,
  });
}

function roundCalcAmount(value, fractionDigits) {
  const num = Number(value || 0);
  if (!Number.isFinite(num) || num <= 0) {
    return 0;
  }
  const factor = 10 ** fractionDigits;
  return Math.round(num * factor) / factor;
}

function ActiveOrderCard({ order, nowMs, onOpen }) {
  const statusMeta = window.MBEX.getStatusMeta(order, nowMs);
  const secondsLeft = window.MBEX.getOrderSecondsLeft(order, nowMs);
  const transfer = order.typeKey === "transfer";
  const buying = order.typeKey === "buy";
  const title = transfer ? "Перестановка RUB" : buying ? "Покупка USDT" : "Продажа USDT";
  const route = transfer ? [order.fromCity, order.toCity].filter(Boolean).join(" → ") : "";

  return (
    <div className="card" style={{ overflow: "hidden" }}>
      <div className="card-pad" style={{ paddingBottom: 12 }}>
        <div className="between" style={{ marginBottom: 12 }}>
          <Pill cls={statusMeta.pillClass} dot={statusMeta.pillDot}>{statusMeta.title}</Pill>
          <span className="num" style={{ fontSize: 13, fontWeight: 800, color: "var(--accent)" }}>
            <Icons.clock size={13} sw={2.2} style={{ verticalAlign: "-2px", marginRight: 4 }} />
            {secondsLeft > 0 ? window.MBEX.formatDuration(secondsLeft) : "00:00"}
          </span>
        </div>
        <div className="center" style={{ gap: 12 }}>
          <Coin kind={buying ? "usdt" : "rub"} />
          <div className="grow">
            <div style={{ fontWeight: 800, fontSize: 16 }}>
              {title}
            </div>
            <div className="muted" style={{ fontSize: 12.5 }}>
              {window.MBEX.orderDisplayCode(order)} · {route || statusMeta.subtitle}
            </div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div className="num" style={{ fontWeight: 800, fontSize: 16 }}>
              {window.MBEX.orderDisplayAmount(order)}
            </div>
            <div className="muted num" style={{ fontSize: 12.5 }}>
              {transfer
                ? "Маршрут"
                : (order.sumUsdt || order.depositAmountReceived) > 0
                ? `${window.MBEX.fmtUsdt(order.sumUsdt || order.depositAmountReceived)} USDT`
                : "Ожидаем сумму"}
            </div>
          </div>
        </div>
      </div>
      <div className="hr" />
      <div
        className="row"
        style={{ justifyContent: "center", color: "var(--accent)", fontWeight: 800, fontSize: 14.5, whiteSpace: "nowrap" }}
        onClick={onOpen}
      >
        Открыть статус <Icons.chevR size={15} style={{ marginLeft: 4 }} />
      </div>
    </div>
  );
}

function formatCbrDate(nowMs, offsetDays) {
  const baseMs = Number(nowMs) || Date.now();
  return new Date(baseMs + offsetDays * 24 * 60 * 60 * 1000).toLocaleDateString("ru-RU", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    timeZone: "Europe/Moscow",
  });
}

function CbrRateCard({ app }) {
  const rates = app.publicState.rates;
  const currentRate = Number(rates.cbr || 0);
  const previousRate = Number(rates.cbrYesterday || 0);
  const changePct = currentRate > 0 && previousRate > 0
    ? ((currentRate - previousRate) / previousRate) * 100
    : null;
  const changeTone = changePct > 0 ? "is-up" : changePct < 0 ? "is-down" : "is-flat";

  return (
    <section className="card cbr-rate-card" aria-label="Курс Центрального банка России">
      <div className="cbr-rate-card-head">
        <strong>Курс ЦБ РФ</strong>
        <span
          className="cbr-rate-card-info"
          title="Официальный курс доллара США к российскому рублю"
          aria-label="Официальный курс доллара США к российскому рублю"
        >
          <Icons.info size={17} sw={2} />
        </span>
      </div>

      <div className="cbr-rate-grid">
        <div className="cbr-rate-cell">
          <span>Вчера, {formatCbrDate(app.nowMs, -1)}</span>
          <div className="cbr-rate-value-row">
            <strong className="num">{previousRate > 0 ? `${window.MBEX.fmtRub2(previousRate)} ₽` : "—"}</strong>
          </div>
        </div>
        <div className="cbr-rate-cell">
          <span>Сегодня, {formatCbrDate(app.nowMs, 0)}</span>
          <div className="cbr-rate-value-row">
            <strong className="num">{currentRate > 0 ? `${window.MBEX.fmtRub2(currentRate)} ₽` : "—"}</strong>
            {changePct !== null ? (
              <em className={`cbr-rate-change ${changeTone}`}>
                {changePct > 0 ? <Icons.arrowUp size={12} sw={2.5} /> : null}
                {changePct < 0 ? <Icons.arrowDown size={12} sw={2.5} /> : null}
                {changePct > 0 ? "+" : ""}{changePct.toFixed(2)}%
              </em>
            ) : null}
          </div>
        </div>
      </div>
    </section>
  );
}

function ChartCard({ app }) {
  const rates = app.publicState.rates;
  const [timeframe, setTimeframe] = React.useState("MBEX");
  const data = timeframe === "Рынок" ? rates.marketSeries : rates.buySeries;
  const current = timeframe === "Рынок" ? Number(rates.marketSell || 0) : Number(rates.buy || 0);
  const first = data.length ? data[0] : current;
  const last = data.length ? data[data.length - 1] : current;
  const change = first > 0 ? ((last - first) / first) * 100 : 0;
  const up = change >= 0;

  return (
    <div className="card card-pad">
      <div className="between" style={{ marginBottom: 2 }}>
        <div>
          <div className="eyebrow">Курс USDT / RUB</div>
          <div className="center" style={{ gap: 8, marginTop: 5 }}>
            <span className="num" style={{ fontSize: 26, fontWeight: 700, letterSpacing: 0 }}>
              {window.MBEX.fmtRub2(current)} ₽
            </span>
            <Pill cls={up ? "pill-pos" : "pill-neg"}>
              {up ? <Icons.arrowUp size={12} sw={2.6} /> : <Icons.arrowDown size={12} sw={2.6} />}
              {Math.abs(change).toFixed(2)}%
            </Pill>
          </div>
        </div>
      </div>
      <div style={{ margin: "10px -4px 6px" }}>
        <AreaChart data={data} color={up ? "pos" : "acc"} h={116} />
      </div>
      <div style={{ display: "flex", gap: 6 }}>
        {["MBEX", "Рынок"].map((key) => (
          <div
            key={key}
            onClick={() => setTimeframe(key)}
            style={{
              flex: 1,
              textAlign: "center",
              padding: "7px 0",
              borderRadius: 9,
              fontSize: 12.5,
              fontWeight: 700,
              cursor: "pointer",
              background: timeframe === key ? "var(--accent-soft)" : "transparent",
              color: timeframe === key ? "var(--accent)" : "var(--text-3)",
            }}
          >
            {key}
          </div>
        ))}
      </div>
      <div className="hr" style={{ margin: "12px 0 4px" }} />
      <div className="between" style={{ padding: "8px 0 2px" }}>
        <span className="muted" style={{ fontSize: 13, whiteSpace: "nowrap" }}>Рынок Rapira</span>
        <span className="num" style={{ fontWeight: 700, fontSize: 14 }}>
          {window.MBEX.fmtRub2(rates.marketSell || 0)} ₽
        </span>
      </div>
      <div className="between" style={{ padding: "2px 0" }}>
        <span className="muted" style={{ fontSize: 13, whiteSpace: "nowrap" }}>Курс ЦБ РФ</span>
        <span className="num" style={{ fontWeight: 700, fontSize: 14 }}>
          {window.MBEX.fmtRub2(rates.cbr || 0)} ₽
        </span>
      </div>
    </div>
  );
}

function ReferralTeaser({ app, onClick }) {
  const referral = app.privateState.referral;
  const count = Number(referral?.refCount || 0);
  const balance = Number(referral?.refBalance || 0);
  const subtitle = count > 0
    ? `${count} рефералов · ${window.MBEX.fmtUsdt(balance)} USDT доступно`
    : "Другу скидка на первую сделку, вам — бонус с комиссии";
  return (
    <div
      className="card card-pad"
      onClick={onClick}
      style={{ cursor: "pointer", display: "flex", alignItems: "center", gap: 14 }}
    >
      <div className="row-ic accent" style={{ width: 56, height: 56, borderRadius: 16 }}>
        <Icons.gift size={40} />
      </div>
      <div className="grow">
        <div style={{ fontWeight: 800, fontSize: 15 }}>Реферальная программа</div>
        <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>{subtitle}</div>
      </div>
      <Icons.chevR className="chev" />
    </div>
  );
}

function HomeQuickLinks({ app, nav }) {
  const items = [
    {
      icon: <Icons.gift size={40} />,
      title: "Рефералка",
      sub: "Бонусы и ссылка",
      target: "referral",
    },
    {
      icon: <Icons.pin size={40} />,
      title: "Офисы",
      sub: "Адреса и контакты",
      target: "offices",
    },
    {
      icon: <Icons.support size={40} />,
      title: "Поддержка",
      sub: "Связаться с нами",
      target: "support",
    },
    {
      icon: <Icons.kyc size={40} />,
      title: "AML / KYC",
      sub: "Правила проверки",
      target: "aml",
    },
  ];

  return (
    <div className="home-services-grid">
      {items.map((item) => (
        <div
          key={item.target}
          className="card"
          onClick={() => nav(item.target)}
        >
          <span>{item.icon}</span>
          <strong>{item.title}</strong>
          <em>{item.sub}</em>
        </div>
      ))}
    </div>
  );
}

function HomeScreen({ dir, setDir, payInput, setPayInput, app, onCreate, onOpenOrder, nav }) {
  const active = app.activeOrders[0] || null;
  return (
    <div className="body">
      <div className="stack screen-enter">
        <RateHero dir={dir} app={app} />
        <DirectionSwitcher dir={dir} setDir={setDir} app={app} />
        <CalcCard
          dir={dir}
          setDir={setDir}
          payInput={payInput}
          setPayInput={setPayInput}
          app={app}
          onCreate={onCreate}
        />
        {!active ? <CbrRateCard app={app} /> : null}
        {app.authState.lastError ? (
          <div className="status-note warn">
            <div>{app.authState.lastError}</div>
            <button
              type="button"
              className="btn btn-ghost btn-sm"
              style={{ marginTop: 8 }}
              onClick={app.refreshOrders}
            >
              Обновить статус
            </button>
          </div>
        ) : null}
        {active ? (
          <div className="stack-sm">
            <div className="section-headline">
              <span>Активная заявка</span>
              <button type="button" onClick={() => onOpenOrder(active.id)}>Статус</button>
            </div>
            <ActiveOrderCard order={active} nowMs={app.nowMs} onOpen={() => onOpenOrder(active.id)} />
          </div>
        ) : null}
        {active ? <CbrRateCard app={app} /> : null}
        <div className="home-section-title">Сервисы</div>
        <HomeQuickLinks app={app} nav={nav} />
        <div className="center" style={{ justifyContent: "center", gap: 7, padding: "4px 0 2px", color: "var(--text-3)" }}>
          <Icons.shield size={14} />
          <span style={{ fontSize: 11.5, fontWeight: 600 }}>
            Курс и комиссия фиксируются в заявке по текущим правилам MBEX.
          </span>
        </div>
      </div>
    </div>
  );
}

window.HomeScreen = HomeScreen;
