/* global React, Icon, Coin, fmt, parseNum, API */
const { useState, useEffect } = React;

// Asset list comes from server config (Configurações tab populates OTC_ASSETS).
// `name` is best-effort; we surface the ticker if no friendly name is known.
const ASSET_NAMES = {
  BTC: "Bitcoin", ETH: "Ethereum", USDT: "Tether", USDC: "USD Coin",
  SOL: "Solana", MATIC: "Polygon", LTC: "Litecoin", BCH: "Bitcoin Cash",
};
function configuredCoins() {
  const cfg = (typeof window !== "undefined" && window.OTC_CONFIG) || {};
  const list = Array.isArray(cfg.assets) ? cfg.assets : ["BTC", "ETH", "USDT", "USDC"];
  return list.map((t) => ({ ticker: t, name: ASSET_NAMES[t] || t }));
}

const DepositarView = ({ onShowToast }) => {
  const COINS = configuredCoins();
  const [coin, setCoin] = useState(COINS[0]?.ticker || "USDT");
  const [qty, setQty] = useState("");
  const [origin, setOrigin] = useState("");
  const [addr, setAddr] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setAddr("");
    API.depositAddress(coin).then((r) => {
      if (cancelled) return;
      const real = r?.payload?.addresses?.[0]?.hash;
      setAddr(real || "");
      setLoading(false);
    });
    return () => { cancelled = true; };
  }, [coin]);

  const copy = () => {
    if (!addr) return;
    navigator.clipboard?.writeText(addr).catch(() => {});
    onShowToast && onShowToast("Endereço copiado", "check");
  };
  return (
    <div className="card">
      <div className="card-pad">
        <h2 className="card-h2">Depositar Criptomoedas</h2>
        <p className="card-sub">Selecione a moeda e copie o endereço para realizar o depósito</p>

        <label className="label">Selecione a Moeda</label>
        <div className="coin-tiles mb-20">
          {COINS.map(c => (
            <button key={c.ticker} className={`coin-tile ${coin === c.ticker ? "active" : ""}`} onClick={() => setCoin(c.ticker)}>{c.ticker}</button>
          ))}
        </div>

        <label className="label">Endereço de Depósito ({coin}) {loading && <span style={{fontWeight: 400, color: "var(--ink-400)"}}>(buscando na MB…)</span>}</label>
        <div className="addr-row mb-20">
          <div className="addr">{loading ? "Carregando…" : (addr || "—")}</div>
          <button className="copy-btn" onClick={copy}><Icon.Copy /> Copiar</button>
        </div>

        <label className="label">Quantidade Esperada ({coin})</label>
        <input className="input mb-12" placeholder="0.00150000" value={qty} onChange={e => setQty(e.target.value)} />
        <div style={{fontSize: 11.5, color: "var(--ink-400)", marginBottom: 20}}>Informe o valor que você está enviando (opcional)</div>

        <label className="label">Origem do Depósito (opcional)</label>
        <input className="input mb-20" placeholder="Carteira Externa Binance" value={origin} onChange={e => setOrigin(e.target.value)} />

        <div className="summary mb-20">
          <div className="row-between"><span className="l">Quantidade</span><span className="v">{qty || "0.00000000"} {coin}</span></div>
          <div className="row-between"><span className="l">Origem</span><span className="v">{origin || "—"}</span></div>
        </div>

        <button className="btn btn-primary btn-block" onClick={() => onShowToast && onShowToast("Depósito registrado. Aguardando confirmações.", "check")}>
          Confirmar Depósito
        </button>

        <div className="info info-amber mt-16">
          <span className="info-icon"><Icon.Alert /></span>
          <div>
            <b>Atenção</b>
            Envie apenas {coin} para este endereço. Envios de outras moedas resultarão em perda permanente.
          </div>
        </div>
      </div>
    </div>
  );
};

const SacarView = ({ onShowToast, onConfirm }) => {
  const COINS = configuredCoins();
  const [coin, setCoin] = useState(COINS[0]?.ticker || "BTC");
  const [addr, setAddr] = useState("");
  const [qty, setQty] = useState("");
  const [feeInfo, setFeeInfo] = useState(null);
  const [networks, setNetworks] = useState([]);
  const [network, setNetwork] = useState("");
  const [walletBalance, setWalletBalance] = useState(null); // {amount, currency} or null
  const cfg = (typeof window !== "undefined" && window.OTC_CONFIG) || {};

  useEffect(() => {
    let cancelled = false;
    API.networks(coin).then((r) => {
      if (cancelled) return;
      const list = Array.isArray(r.networks) ? r.networks : (Array.isArray(r.body) ? r.body : []);
      setNetworks(list);
      if (list.length === 1) setNetwork(list[0].network);
      else setNetwork("");
    });
    return () => { cancelled = true; };
  }, [coin]);

  useEffect(() => {
    if (!coin) return;
    let cancelled = false;
    API.fees(coin, network || undefined).then((r) => {
      if (cancelled) return;
      setFeeInfo(r?.payload || null);
    });
    return () => { cancelled = true; };
  }, [coin, network]);

  // Fetches the live ledger balance for the configured wallet so "Disponível" is accurate.
  useEffect(() => {
    if (!cfg.defaultWalletId) { setWalletBalance(null); return; }
    let cancelled = false;
    API.ledger(cfg.defaultWalletId).then((r) => {
      if (cancelled) return;
      const row = (r?.balances || []).find((b) => b.asset_symbol === coin);
      setWalletBalance(row ? row.amount : "0");
    });
    return () => { cancelled = true; };
  }, [coin, cfg.defaultWalletId]);

  const fee = feeInfo?.withdrawal_fee ?? null;
  const q = parseNum(qty);
  const receive = fee != null ? Math.max(0, q - Number(fee)) : null;

  const submit = async () => {
    if (!addr || !qty || (networks.length > 0 && !network)) {
      onShowToast && onShowToast("Preencha endereço, rede e quantidade", "info");
      return;
    }
    const res = await API.withdrawCrypto({
      asset: coin, address: addr, qty, network: network || undefined,
      txFee: feeInfo?.withdrawal_fee,
    });
    if (res.ok) {
      onShowToast && onShowToast(`Saque enviado · #${res.withdrawal?.id || "—"}`, "check");
      onConfirm && onConfirm();
    } else {
      onShowToast && onShowToast(res.error || "Falha ao sacar", "info");
    }
  };

  return (
    <div className="card">
      <div className="card-pad">
        <h2 className="card-h2">Sacar Criptomoedas</h2>
        <p className="card-sub">Selecione a moeda e insira o endereço de destino</p>

        <label className="label">Selecione a Moeda</label>
        <div className="coin-tiles mb-20">
          {COINS.map(c => (
            <button key={c.ticker} className={`coin-tile ${coin === c.ticker ? "active" : ""}`} onClick={() => setCoin(c.ticker)}>{c.ticker}</button>
          ))}
        </div>

        <label className="label">Endereço de Destino</label>
        <input className="input mb-20" placeholder="bc1qar0srrr7xfkvy516431ydnw9re59gtzzwf5mdq" value={addr} onChange={e => setAddr(e.target.value)} />

        <label className="label">Quantidade ({coin})</label>
        <div style={{position: "relative"}}>
          <input className="input" placeholder="0.00250000" value={qty} onChange={e => setQty(e.target.value)} />
          <button
            style={{position: "absolute", right: 16, top: "50%", transform: "translateY(-50%)", fontWeight: 700, fontSize: 12, color: "var(--brand-700)"}}
            onClick={() => walletBalance != null && setQty(String(walletBalance))}
            disabled={walletBalance == null}
          >Máximo</button>
        </div>
        <div style={{fontSize: 11.5, color: "var(--ink-500)", marginTop: 6, marginBottom: 20}}>
          Disponível: <b>{walletBalance == null ? "—" : `${walletBalance} ${coin}`}</b>
        </div>

        <div className="card" style={{boxShadow: "none", marginBottom: 20}}>
          <div className="card-pad" style={{padding: 18}}>
            <div style={{fontWeight: 700, fontSize: 14, marginBottom: 12}}>Resumo do Saque</div>
            <div className="row-between" style={{padding: "6px 0", fontSize: 13}}>
              <span style={{color: "var(--ink-500)"}}>Quantidade</span>
              <span className="num"><b>{qty || "0,00000000"} {coin}</b></span>
            </div>
            <div className="row-between" style={{padding: "6px 0", fontSize: 13}}>
              <span style={{color: "var(--ink-500)"}}>Taxa de Rede</span>
              <span className="num" style={{color: "var(--red)"}}>{fee != null ? `− ${fee} ${coin}` : "— (consulte MB)"}</span>
            </div>
            <div className="divider"></div>
            <div className="row-between" style={{padding: "6px 0", fontSize: 14}}>
              <span style={{fontWeight: 700}}>Você receberá</span>
              <span className="num" style={{fontWeight: 700, color: "var(--green-text)"}}>
                {receive != null ? `${fmt(receive, coin === "USDT" || coin === "USDC" ? 2 : 8)} ${coin}` : "—"}
              </span>
            </div>
          </div>
        </div>

        {networks.length > 1 && (
          <>
            <label className="label">Rede</label>
            <div className="coin-tiles mb-20">
              {networks.map((n) => (
                <button key={n.network} className={`coin-tile ${network === n.network ? "active" : ""}`} onClick={() => setNetwork(n.network)}>{n.network}</button>
              ))}
            </div>
          </>
        )}

        <button className="btn btn-primary btn-block" onClick={() => { onConfirm && onConfirm(submit); }}>Confirmar Saque</button>

        <div className="info info-amber mt-16">
          <span className="info-icon"><Icon.Alert /></span>
          <div>
            <b>Atenção</b>
            Verifique cuidadosamente o endereço de destino. Transações de criptomoedas são irreversíveis.
          </div>
        </div>
      </div>
    </div>
  );
};

const ComprarView = ({ onShowToast }) => {
  const COINS = configuredCoins();
  const [coin, setCoin] = useState(COINS[0]?.ticker || "BTC");
  const [amt, setAmt] = useState("");
  const [quotes, setQuotes] = useState({});
  const [submitting, setSubmitting] = useState(false);

  useEffect(() => {
    let cancelled = false;
    const load = async () => {
      try {
        const data = await API.quotes(COINS.map(c => c.ticker));
        if (cancelled) return;
        const map = {};
        (data.quotes || []).forEach(q => { map[q.asset] = q; });
        setQuotes(map);
      } catch (_) { /* keep UI usable without quote */ }
    };
    load();
    const t = setInterval(load, 10_000);
    return () => { cancelled = true; clearInterval(t); };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const q = quotes[coin];
  const ourBuyPrice = q ? Number(q.our_buy_price) : null;
  const spreadPct = q ? (q.spread_bps / 100) : null;
  const brl = parseNum(amt);
  const expectedQty = ourBuyPrice && brl ? brl / ourBuyPrice : 0;

  const submit = async () => {
    if (submitting || !brl) return;
    setSubmitting(true);
    try {
      const res = await API.buy({ assetSymbol: coin, brlAmountCents: Math.round(brl * 100) });
      if (res.ok) {
        onShowToast && onShowToast(`Ordem enviada · ${res.order?.status || "registrada"}`, "check");
        setAmt("");
      } else {
        onShowToast && onShowToast(res.error || "Falha ao enviar ordem", "info");
      }
    } catch (_) {
      onShowToast && onShowToast("Erro de rede", "info");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="card"><div className="card-pad">
      <h2 className="card-h2">Comprar Criptomoedas</h2>
      <p className="card-sub">Compre cripto pagando em Reais (BRL)</p>
      <label className="label">Ativo a comprar</label>
      <div className="coin-tile-from mb-20" style={{gridTemplateColumns: "repeat(4, 1fr)"}}>
        {COINS.map(c => {
          const cq = quotes[c.ticker];
          const open = Number(cq?.source?.open || 0);
          const last = Number(cq?.source?.last || 0);
          const ch = open > 0 ? +(((last / open) - 1) * 100).toFixed(2) : null;
          return (
            <button key={c.ticker} className={`coin-tile ${coin === c.ticker ? "active" : ""}`} onClick={() => setCoin(c.ticker)}>
              <div className="top"><Coin ticker={c.ticker} size="sm" /><div><div className="label">{c.ticker}</div><div className="ticker">{c.name}</div></div></div>
              {ch != null
                ? <div className={`change ${ch >= 0 ? "up" : "down"}`}>{ch >= 0 ? "+" : ""}{ch.toFixed(2)}%</div>
                : <div className="change" style={{color: "var(--ink-400)"}}>—</div>}
            </button>
          );
        })}
      </div>
      <label className="label">Valor em Reais (BRL)</label>
      <input className="input input-lg mb-20" placeholder="R$ 0,00" value={amt} onChange={e => setAmt(e.target.value)} />
      <div className="summary mb-20">
        <div className="row-between"><span className="l">Você paga</span><span className="v">R$ {amt || "0,00"}</span></div>
        <div className="row-between"><span className="l">Cotação</span><span className="v">1 {coin} = R$ {ourBuyPrice ? fmt(ourBuyPrice, 2) : "—"}</span></div>
        <div className="row-between"><span className="l">Taxa</span><span className="v">{spreadPct != null ? `${spreadPct.toFixed(2)}%` : "—"}</span></div>
        <div className="row-between total"><span className="l">Você recebe</span><span className="v">≈ {fmt(expectedQty, 8)} {coin}</span></div>
      </div>
      <button className="btn btn-primary btn-block" disabled={submitting || !brl} onClick={submit}>
        {submitting ? "Enviando…" : "Confirmar Compra"}
      </button>
    </div></div>
  );
};

const VenderView = ({ onShowToast }) => {
  const COINS = configuredCoins();
  const [coin, setCoin] = useState(COINS[0]?.ticker || "BTC");
  const [qty, setQty] = useState("");
  const [quotes, setQuotes] = useState({});
  const [submitting, setSubmitting] = useState(false);

  useEffect(() => {
    let cancelled = false;
    const load = async () => {
      const data = await API.quotes(COINS.map(c => c.ticker));
      if (cancelled) return;
      const map = {};
      (data.quotes || []).forEach(q => { map[q.asset] = q; });
      setQuotes(map);
    };
    load();
    const t = setInterval(load, 10_000);
    return () => { cancelled = true; clearInterval(t); };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const q = quotes[coin];
  const ourSellPrice = q ? Number(q.our_sell_price) : null;
  const spreadPct = q ? (q.spread_bps / 100) : null;
  const cryptoQty = parseNum(qty);
  const expectedBrl = ourSellPrice && cryptoQty ? cryptoQty * ourSellPrice : 0;

  const submit = async () => {
    if (submitting || !cryptoQty) return;
    setSubmitting(true);
    try {
      const res = await API.sell({ assetSymbol: coin, cryptoQty });
      if (res.ok) {
        onShowToast && onShowToast(`Venda enviada · ${res.order?.status || "registrada"}`, "check");
        setQty("");
      } else {
        onShowToast && onShowToast(res.error || "Falha ao vender", "info");
      }
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="card"><div className="card-pad">
      <h2 className="card-h2">Vender Criptomoedas</h2>
      <p className="card-sub">Venda cripto e receba em Reais (BRL)</p>
      <label className="label">Ativo a vender</label>
      <div className="coin-tile-from mb-20" style={{gridTemplateColumns: "repeat(4, 1fr)"}}>
        {COINS.map(c => {
          const cq = quotes[c.ticker];
          const open = Number(cq?.source?.open || 0);
          const last = Number(cq?.source?.last || 0);
          const ch = open > 0 ? +(((last / open) - 1) * 100).toFixed(2) : null;
          return (
            <button key={c.ticker} className={`coin-tile ${coin === c.ticker ? "active" : ""}`} onClick={() => setCoin(c.ticker)}>
              <div className="top"><Coin ticker={c.ticker} size="sm" /><div><div className="label">{c.ticker}</div><div className="ticker">{c.name}</div></div></div>
              {ch != null
                ? <div className={`change ${ch >= 0 ? "up" : "down"}`}>{ch >= 0 ? "+" : ""}{ch.toFixed(2)}%</div>
                : <div className="change" style={{color: "var(--ink-400)"}}>—</div>}
            </button>
          );
        })}
      </div>
      <label className="label">Quantidade ({coin})</label>
      <input className="input input-lg mb-20" placeholder="0,00000000" value={qty} onChange={e => setQty(e.target.value.replace(/[^\d,]/g, ""))} />
      <div className="summary mb-20">
        <div className="row-between"><span className="l">Cotação Bid</span><span className="v">R$ {ourSellPrice ? fmt(ourSellPrice, 2) : "—"}</span></div>
        <div className="row-between"><span className="l">Taxa</span><span className="v">{spreadPct != null ? `${spreadPct.toFixed(2)}%` : "—"}</span></div>
        <div className="row-between total"><span className="l">Você recebe</span><span className="v">R$ {fmt(expectedBrl, 2)}</span></div>
      </div>
      <button className="btn btn-primary btn-block" disabled={submitting || !cryptoQty} onClick={submit}>
        {submitting ? "Enviando…" : "Confirmar Venda"}
      </button>
    </div></div>
  );
};

const EnviarView = ({ onShowToast }) => {
  const COINS = configuredCoins();
  const [asset, setAsset] = useState(COINS[0]?.ticker || "USDT");
  const [networks, setNetworks] = useState([]);
  const [network, setNetwork] = useState("");
  const [address, setAddress] = useState("");
  const [qty, setQty] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [openAsset, setOpenAsset] = useState(false);
  const [openNetwork, setOpenNetwork] = useState(false);

  useEffect(() => {
    if (!asset) { setNetworks([]); setNetwork(""); return; }
    let cancelled = false;
    API.networks(asset).then((r) => {
      if (cancelled) return;
      const list = Array.isArray(r.networks) ? r.networks : (Array.isArray(r.body) ? r.body : []);
      setNetworks(list);
      if (list.length === 1) setNetwork(list[0].network);
      else if (!list.find((n) => n.network === network)) setNetwork("");
    });
    return () => { cancelled = true; };
  }, [asset]);

  const submit = async () => {
    if (!asset || !address || !qty || !network) {
      onShowToast && onShowToast("Preencha ativo, rede, endereço e quantidade", "info");
      return;
    }
    setSubmitting(true);
    try {
      const res = await API.withdrawCrypto({ asset, address, qty, network });
      if (res.ok) {
        onShowToast && onShowToast("Saque enviado · aguardando confirmação", "check");
        setAddress(""); setQty("");
      } else {
        onShowToast && onShowToast(res.error || "Falha ao enviar", "info");
      }
    } finally {
      setSubmitting(false);
    }
  };

  const ASSETS = COINS.map((c) => c.ticker);

  return (
    <div className="card"><div className="card-pad">
      <h2 className="card-h2">Enviar Criptomoedas</h2>
      <p className="card-sub">Transfira criptomoedas para outra carteira</p>

      <label className="label">Ativo</label>
      <button className="select mb-20" onClick={() => setOpenAsset(!openAsset)}>
        <div className="row"><Coin ticker={asset} size="sm" /><b>{asset}</b></div>
        <Icon.ChevronDown />
      </button>
      {openAsset && (
        <div className="coin-tiles mb-20">
          {ASSETS.map((a) => (
            <button key={a} className={`coin-tile ${asset === a ? "active" : ""}`} onClick={() => { setAsset(a); setOpenAsset(false); }}>{a}</button>
          ))}
        </div>
      )}

      <label className="label">Rede</label>
      <button className={`select ${networks.length === 0 ? "disabled" : ""} mb-20`} onClick={() => networks.length > 0 && setOpenNetwork(!openNetwork)}>
        <span className={network ? "" : "placeholder"}>{network || (networks.length ? "Selecione a rede" : "Selecione um ativo primeiro")}</span>
        <Icon.ChevronDown />
      </button>
      {openNetwork && networks.length > 0 && (
        <div className="mb-20">
          {networks.map((n) => (
            <button key={n.network} className={`coin-tile ${network === n.network ? "active" : ""}`} style={{textAlign: "left", display: "block", width: "100%", marginBottom: 6}} onClick={() => { setNetwork(n.network); setOpenNetwork(false); }}>
              <div style={{fontWeight: 700}}>{n.network}</div>
              <div style={{fontSize: 11, color: "var(--ink-400)"}}>{n.coin}</div>
            </button>
          ))}
        </div>
      )}

      <label className="label">Endereço de destino</label>
      <input className="input mb-20" placeholder="bc1qar0srrr7xfkvy516431ydnw9re59gtzzwf5mdq" value={address} onChange={(e) => setAddress(e.target.value)} />

      <label className="label">Valor da transferência</label>
      <input className="input mb-20" placeholder="0.00000000" value={qty} onChange={(e) => setQty(e.target.value.replace(/[^\d.,]/g, ""))} />

      <button className="btn btn-primary btn-block" disabled={submitting || !asset || !network || !address || !qty} onClick={submit}>
        {submitting ? "Enviando…" : "Continuar"}
      </button>

      <div className="info info-amber mt-16">
        <span className="info-icon"><Icon.Alert /></span>
        <div>
          <b>Atenção</b>
          O endereço destino precisa estar pré-cadastrado como confiável no painel da Mercado Bitcoin (2FA + IP autorizado).
        </div>
      </div>
    </div></div>
  );
};

const ReceberView = ({ onShowToast }) => {
  const COINS = configuredCoins();
  const [coin, setCoin] = useState(null);
  const [addr, setAddr] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!coin) { setAddr(""); return; }
    let cancelled = false;
    setLoading(true);
    setAddr("");
    API.depositAddress(coin).then((r) => {
      if (cancelled) return;
      const real = r?.payload?.addresses?.[0]?.hash;
      setAddr(real || "");
      setLoading(false);
    });
    return () => { cancelled = true; };
  }, [coin]);

  const copy = () => {
    if (!addr) return;
    navigator.clipboard?.writeText(addr).catch(() => {});
    onShowToast && onShowToast("Endereço copiado", "check");
  };

  return (
    <div>
      <div className="card mb-16"><div className="card-pad">
        <h2 className="card-h2">Receber Cripto</h2>
        <p className="card-sub">Compartilhe seu endereço para receber criptomoedas</p>
        <label className="label">Ativo</label>
        <div className="coin-tiles mb-20">
          {COINS.map(c => (
            <button key={c.ticker} className={`coin-tile ${coin === c.ticker ? "active" : ""}`} onClick={() => setCoin(c.ticker)}>{c.ticker}</button>
          ))}
        </div>
        {coin && (
          <>
            <div style={{display: "grid", gridTemplateColumns: "200px 1fr", gap: 24, alignItems: "center"}}>
              <div className="qr"></div>
              <div>
                <label className="label">Endereço {coin}</label>
                <div className="addr-row" style={{marginBottom: 12}}>
                  <div className="addr">{loading ? "Carregando…" : (addr || "—")}</div>
                  <button className="copy-btn" onClick={copy}><Icon.Copy /> Copiar</button>
                </div>
                <div style={{fontSize: 12, color: "var(--ink-500)"}}>Aceite apenas {coin} neste endereço.</div>
              </div>
            </div>
          </>
        )}
      </div></div>

      <div className="card"><div className="card-pad">
        <div style={{fontWeight: 700, fontSize: 15, marginBottom: 16}}>Movimentações</div>
        <div className="empty">
          <div className="empty-ic"><div style={{width: 16, height: 16, background: "var(--ink-300)"}}></div></div>
          <p>Nenhum depósito recente</p>
          <button className="btn btn-primary" style={{height: 38, padding: "0 18px"}}>Ver todo o histórico</button>
        </div>
      </div></div>
    </div>
  );
};

Object.assign(window, { DepositarView, SacarView, ComprarView, VenderView, EnviarView, ReceberView });
