function fmtBlockTime(unixSeconds) {
  return fmtTimeUTC(new Date(unixSeconds * 1000).toISOString());
}

function Explorer({ onNavigate }) {
  const { t } = useI18n();
  const [data, setData] = React.useState(null);
  const [loadError, setLoadError] = React.useState(null);

  function load() {
    setLoadError(null);
    fetch('/api/explorer/blocks?count=20')
      .then(async (r) => {
        const body = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(body.error || `Failed to load blocks (HTTP ${r.status}).`);
        setData(body);
      })
      .catch((e) => setLoadError(e.message || String(e)));
  }

  React.useEffect(() => { load(); }, []);

  if (loadError) {
    return (
      <div className="container py-48 text-center">
        <p style={{ color: 'var(--error)' }} className="mb-24">{loadError}</p>
        <button className="btn btn-secondary" onClick={load}>{t('common.retry')}</button>
      </div>
    );
  }
  if (!data) return <div className="container py-48" />;

  return (
    <div className="container py-48">
      <div className="mb-32">
        <div className="eyebrow mb-8">{t('explorer.eyebrow')}</div>
        <h1 className="h2 serif">{t('explorer.title')}</h1>
        <p className="ink-2 mt-16" style={{ fontSize: 16 }}>{t('explorer.hint', { n: data.latest })}</p>
      </div>

      <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '100px 1fr 90px 200px', gap: 0 }}>
          <div className="tiny" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>BLOCK</div>
          <div className="tiny" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>HASH</div>
          <div className="tiny" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>TXNS</div>
          <div className="tiny" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>TIME (UTC)</div>
          {data.blocks.map((b) => (
            <React.Fragment key={b.number}>
              <div
                className="mono small"
                style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)', cursor: 'pointer', color: 'var(--primary-active)' }}
                onClick={() => onNavigate('block:' + b.number)}
              >
                {b.number}
              </div>
              <div className="mono small" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>
                <ShortHash hash={b.hash} len={8} />
              </div>
              <div className="mono small" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>{b.txCount}</div>
              <div className="mono small ink-3" style={{ padding: '12px 16px', borderBottom: '1px solid var(--hairline)' }}>{fmtBlockTime(b.timestamp)}</div>
            </React.Fragment>
          ))}
        </div>
      </div>
    </div>
  );
}

function BlockDetail({ blockNumber, onNavigate }) {
  const { t } = useI18n();
  const [block, setBlock] = React.useState(null);
  const [loadError, setLoadError] = React.useState(null);

  function load() {
    setLoadError(null);
    setBlock(null);
    fetch(`/api/explorer/block/${blockNumber}`)
      .then(async (r) => {
        const body = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(body.error || `Failed to load block (HTTP ${r.status}).`);
        setBlock(body);
      })
      .catch((e) => setLoadError(e.message || String(e)));
  }

  React.useEffect(() => { load(); }, [blockNumber]);

  if (loadError) {
    return (
      <div className="container py-48 text-center">
        <p style={{ color: 'var(--error)' }} className="mb-24">{loadError}</p>
        <button className="btn btn-secondary" onClick={load}>{t('common.retry')}</button>
      </div>
    );
  }
  if (!block) return <div className="container py-48" />;

  return (
    <div className="container py-48">
      <div className="row gap-8 mb-24 tiny" style={{ textTransform: 'none', letterSpacing: 0.04 }}>
        <a onClick={() => onNavigate('explorer')} style={{ cursor: 'pointer' }}>{t('explorer.title')}</a>
        <span>›</span>
        <span className="ink-2">Block {block.number}</span>
      </div>

      <h1 className="h2 serif mb-32">Block {block.number}</h1>

      <div className="card mb-24" style={{ padding: 28 }}>
        <div className="col gap-16">
          <Row label="Hash"><span className="mono small" style={{ wordBreak: 'break-all' }}>{block.hash}</span></Row>
          <Row label="Parent hash"><span className="mono small" style={{ wordBreak: 'break-all' }}>{block.parentHash}</span></Row>
          <Row label="Timestamp"><span className="mono small">{fmtBlockTime(block.timestamp)}</span></Row>
          <Row label="Miner"><span className="mono small">{block.miner}</span></Row>
          <Row label="Gas used"><span className="mono small">{block.gasUsed} / {block.gasLimit}</span></Row>
        </div>
      </div>

      <h3 className="h3 serif mb-16">Transactions ({block.transactions.length})</h3>
      {block.transactions.length === 0 ? (
        <p className="ink-3 small">No transactions in this block.</p>
      ) : (
        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          {block.transactions.map((tx, i) => (
            <div
              key={tx.hash}
              className="row between"
              style={{ padding: '14px 16px', borderBottom: i < block.transactions.length - 1 ? '1px solid var(--hairline)' : 'none', cursor: 'pointer' }}
              onClick={() => onNavigate('tx:' + tx.hash)}
            >
              <span className="mono small" style={{ color: 'var(--primary-active)' }}><ShortHash hash={tx.hash} len={8} /></span>
              <span className="mono small ink-3">{tx.from.slice(0, 8)}… → {tx.to ? tx.to.slice(0, 8) + '…' : '(contract creation)'}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function TxDetail({ txHash, onNavigate }) {
  const { t } = useI18n();
  const [tx, setTx] = React.useState(null);
  const [loadError, setLoadError] = React.useState(null);

  function load() {
    setLoadError(null);
    setTx(null);
    fetch(`/api/explorer/tx/${txHash}`)
      .then(async (r) => {
        const body = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(body.error || `Failed to load transaction (HTTP ${r.status}).`);
        setTx(body);
      })
      .catch((e) => setLoadError(e.message || String(e)));
  }

  React.useEffect(() => { load(); }, [txHash]);

  if (loadError) {
    return (
      <div className="container py-48 text-center">
        <p style={{ color: 'var(--error)' }} className="mb-24">{loadError}</p>
        <button className="btn btn-secondary" onClick={load}>{t('common.retry')}</button>
      </div>
    );
  }
  if (!tx) return <div className="container py-48" />;

  return (
    <div className="container py-48">
      <div className="row gap-8 mb-24 tiny" style={{ textTransform: 'none', letterSpacing: 0.04 }}>
        <a onClick={() => onNavigate('explorer')} style={{ cursor: 'pointer' }}>{t('explorer.title')}</a>
        <span>›</span>
        <a onClick={() => onNavigate('block:' + tx.blockNumber)} style={{ cursor: 'pointer' }}>Block {tx.blockNumber}</a>
        <span>›</span>
        <span className="ink-2">Transaction</span>
      </div>

      <div className="row gap-12 mb-32" style={{ alignItems: 'center' }}>
        <h1 className="h2 serif">Transaction</h1>
        {tx.status === 1 && <span className="badge badge-verified"><span className="dot-verified" /> Success</span>}
        {tx.status === 0 && <span className="badge" style={{ color: 'var(--error)', borderColor: 'var(--error)' }}>Failed</span>}
      </div>

      <div className="card mb-24" style={{ padding: 28 }}>
        <div className="col gap-16">
          <Row label="Hash"><span className="mono small" style={{ wordBreak: 'break-all' }}>{tx.hash}</span></Row>
          <Row label="Block"><a className="mono small" style={{ cursor: 'pointer', color: 'var(--primary-active)' }} onClick={() => onNavigate('block:' + tx.blockNumber)}>{tx.blockNumber}</a></Row>
          <Row label="From"><span className="mono small" style={{ wordBreak: 'break-all' }}>{tx.from}</span></Row>
          <Row label="To"><span className="mono small" style={{ wordBreak: 'break-all' }}>{tx.to || '(contract creation)'}</span></Row>
          <Row label="Value"><span className="mono small">{tx.value === '0' ? '0' : window.ethers.formatEther(tx.value)} MATIC</span></Row>
          <Row label="Gas used"><span className="mono small">{tx.gasUsed} / {tx.gasLimit}</span></Row>
        </div>
      </div>

      {tx.logs.length > 0 && (
        <>
          <h3 className="h3 serif mb-16">Logs ({tx.logs.length})</h3>
          <div className="col gap-12">
            {tx.logs.map((log, i) => (
              <div key={i} className="card-flat" style={{ padding: 20 }}>
                {log.decoded ? (
                  <>
                    <div className="badge badge-seal mb-12">{log.decoded.name}</div>
                    <div className="col gap-8">
                      {Object.entries(log.decoded.args).map(([key, value]) => (
                        <Row key={key} label={key}>
                          <span className="mono small" style={{ wordBreak: 'break-all' }}>{String(value)}</span>
                        </Row>
                      ))}
                    </div>
                  </>
                ) : (
                  <div className="tiny ink-3">Undecoded log from {log.address}</div>
                )}
              </div>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function Row({ label, children }) {
  return (
    <div className="row between" style={{ gap: 24 }}>
      <span className="tiny" style={{ flexShrink: 0 }}>{label}</span>
      {children}
    </div>
  );
}

window.Explorer = Explorer;
window.BlockDetail = BlockDetail;
window.TxDetail = TxDetail;
