/* global React, Icon, CopyBtn, pushHistory, useT, useLocale, getRegion */

// ---------- Tool page shell ----------
function ToolPage({ icon, title, lede, children, sidebar }) {
  const t = useT();
  return (
    <div className="page">
      <section className="hero" style={{ paddingTop: 40, paddingBottom: 0 }}>
        <div className="container">
          <span className="row" style={{ gap: 10, color: 'var(--accent)' }}>
            {icon}<span className="eyebrow" style={{ color: 'var(--accent)' }}>{t('tools.eyebrow')}</span>
          </span>
          <h1 style={{ fontSize: 'clamp(28px, 3.4vw, 40px)', marginTop: 8 }}>{title}</h1>
          <p className="lede">{lede}</p>
        </div>
      </section>
      <section className="block" style={{ paddingTop: 24 }}>
        <div className="container">
          <div className="grid-2">
            <div className="stack-lg">{children}</div>
            <div className="stack-lg">{sidebar}</div>
          </div>
        </div>
      </section>
    </div>
  );
}

function Sidebar({ tips }) {
  const t = useT();
  return (
    <>
      <div className="ad-slot h-square">{t('tools.adSlot')}<br/>300×250</div>
      <div className="card card-pad">
        <div className="eyebrow" style={{ marginBottom: 10 }}>{t('tools.tipsTitle')}</div>
        <ul style={{ margin: 0, paddingLeft: 18, color: 'var(--text-2)', fontSize: 14, lineHeight: 1.7 }}>
          {tips.map((tip, i) => <li key={i}>{tip}</li>)}
        </ul>
      </div>
      <VPNMini/>
    </>
  );
}

function VPNMini() {
  const t = useT();
  return (
    <div className="vpn-card" style={{ flexDirection: 'column', alignItems: 'stretch' }}>
      <div className="vpn-affiliate-tag">{t('vpn.tag')}</div>
      <div className="row" style={{ gap: 12 }}>
        <div className="ic"><Icon.shield/></div>
        <div style={{ flex: 1 }}>
          <div className="t">{t('vpn.mTitle')}</div>
          <div className="s">{t('vpn.mDesc')}</div>
        </div>
      </div>
      <a href="#" className="btn btn-primary" style={{ justifyContent: 'center', marginTop: 4 }}>{t('vpn.mCta')}</a>
    </div>
  );
}

// ---------- DNS Lookup ----------
function DNSPage() {
  const t = useT();
  const [domain, setDomain]   = useState('globo.com');
  const [type, setType]       = useState('A');
  const [results, setResults] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError]     = useState(null);

  const types = ['A', 'AAAA', 'MX', 'TXT', 'NS', 'CNAME'];

  const lookup = async (d = domain, ty = type) => {
    if (!d) return;
    setLoading(true); setResults(null); setError(null);
    try {
      const res = await fetch(`/api/dns?domain=${encodeURIComponent(d.trim())}&type=${encodeURIComponent(ty)}`);
      const json = await res.json();
      if (!res.ok) throw new Error(json.message || 'Falha na consulta');
      setResults(json.records);
      pushHistory({ kind: 'DNS', q: `${d} (${ty})` });
    } catch (err) {
      setError(err.message || 'Erro');
      setResults([]);
    }
    setLoading(false);
  };

  useEffect(() => { lookup(); /* eslint-disable-next-line */ }, []);

  const tips = t('tools.dns.tips') || [];
  const countLabel = results && results.length === 1
    ? t('tools.dns.countOne', { n: 1 })
    : t('tools.dns.count',    { n: results?.length || 0 });

  return (
    <ToolPage icon={<Icon.dns/>} title={t('tools.dns.title')} lede={t('tools.dns.lede')} sidebar={<Sidebar tips={tips}/>}>
      <div className="card card-pad-lg">
        <label className="eyebrow" style={{ display: 'block', marginBottom: 8 }}>{t('tools.dns.domainLabel')}</label>
        <div className="input-wrap" style={{ marginBottom: 16 }}>
          <input className="input" value={domain}
            onChange={e => setDomain(e.target.value.trim())}
            placeholder={t('tools.dns.placeholder')}
            onKeyDown={e => e.key === 'Enter' && lookup()}/>
          <button className="btn btn-primary" onClick={() => lookup()}>
            {loading ? t('tools.btn.loading') : t('tools.btn.go')}
          </button>
        </div>
        <div className="row" style={{ flexWrap: 'wrap', gap: 6 }}>
          {types.map(ty => (
            <button key={ty}
              className={'btn btn-sm' + (type === ty ? ' btn-primary' : '')}
              onClick={() => { setType(ty); lookup(domain, ty); }}>{ty}</button>
          ))}
        </div>
      </div>

      <div className="card" style={{ overflow: 'hidden' }}>
        <div className="card-pad" style={{ borderBottom: '1px solid var(--border)' }}>
          <div className="between">
            <div>
              <div className="eyebrow">{t('tools.dns.results')}</div>
              <div style={{ marginTop: 4, fontFamily: 'var(--font-mono)', fontSize: 14 }}>
                {domain} <span style={{ color: 'var(--text-3)' }}>·</span> {type}
              </div>
            </div>
            {results && !error && <span className="chip green"><Icon.check/> {countLabel}</span>}
            {error && <span className="chip red">Erro</span>}
          </div>
        </div>
        {loading && <div className="card-pad"><span className="skeleton" style={{ width: '60%' }}/></div>}
        {error   && <div className="card-pad" style={{ color: 'var(--danger)', fontSize: 14 }}>{error}</div>}
        {!loading && results && results.length === 0 && !error && (
          <div className="card-pad" style={{ color: 'var(--text-3)', fontSize: 14 }}>
            {t('tools.dns.empty', { type })}
          </div>
        )}
        {!loading && results && results.length > 0 && (
          <table className="table">
            <thead><tr>
              <th>{t('tools.dns.thType')}</th>
              <th>{t('tools.dns.thName')}</th>
              <th>{t('tools.dns.thValue')}</th>
              <th>{t('tools.dns.thTtl')}</th>
              <th></th>
            </tr></thead>
            <tbody>
              {results.map((r, i) => (
                <tr key={i}>
                  <td><span className="chip">{r.type}</span></td>
                  <td className="mono">{r.name}</td>
                  <td className="mono" style={{ color: 'var(--accent)' }}>{r.value}</td>
                  <td className="mono" style={{ color: 'var(--text-3)' }}>{r.ttl}s</td>
                  <td><CopyBtn value={r.value} label={t('common.copy')}/></td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </ToolPage>
  );
}

// ---------- Ping ----------
function PingPage() {
  const t = useT();
  const [host, setHost]       = useState('globo.com');
  const [running, setRunning] = useState(false);
  const [lines, setLines]     = useState([]);
  const [stats, setStats]     = useState(null);
  const termRef = useRef(null);
  const stopRef = useRef(false);

  useEffect(() => { if (termRef.current) termRef.current.scrollTop = termRef.current.scrollHeight; }, [lines]);

  const start = async () => {
    if (running || !host) return;
    setRunning(true); setLines([]); setStats(null); stopRef.current = false;
    pushHistory({ kind: 'Ping', q: host });
    const seed = [...host].reduce((a, c) => a + c.charCodeAt(0), 0);
    const ip   = `${20 + (seed % 200)}.${(seed * 3) % 255}.${(seed * 7) % 255}.${(seed * 11) % 255}`;
    const prepend = (l) => setLines(prev => [...prev, l]);
    prepend({ k: 'dim', t: `$ ping ${host}` });
    await wait(350);
    prepend({ k: 'out', t: `PING ${host} (${ip}) 56(84) bytes of data.` });

    const times = [];
    for (let i = 1; i <= 8; i++) {
      if (stopRef.current) break;
      await wait(380 + Math.random() * 220);
      const lost = Math.random() < 0.05;
      if (lost) prepend({ k: 'err', t: `Sem resposta de ${ip}: timeout (icmp_seq=${i})` });
      else {
        const time = 18 + Math.random() * 14 + Math.sin(i) * 2;
        times.push(time);
        prepend({ k: 'out', t: `64 bytes de ${ip}: icmp_seq=${i} ttl=56 time=${time.toFixed(1)} ms` });
      }
    }
    if (!stopRef.current) {
      const sent = 8, recv = times.length;
      const min  = times.length ? Math.min(...times) : 0;
      const max  = times.length ? Math.max(...times) : 0;
      const avg  = times.length ? times.reduce((a, b) => a + b, 0) / times.length : 0;
      const mdev = times.length ? Math.sqrt(times.reduce((a, b) => a + (b - avg) ** 2, 0) / times.length) : 0;
      prepend({ k: 'dim', t: '' });
      prepend({ k: 'ok',  t: `--- ${host} statistics ---` });
      prepend({ k: 'out', t: `${sent} packets transmitted, ${recv} received, ${((1 - recv/sent)*100).toFixed(0)}% loss, time ${sent}s` });
      prepend({ k: 'out', t: `rtt min/avg/max/mdev = ${min.toFixed(1)}/${avg.toFixed(1)}/${max.toFixed(1)}/${mdev.toFixed(1)} ms` });
      setStats({ host, ip, sent, recv, loss: ((1 - recv/sent)*100), min, avg, max, mdev });
    }
    setRunning(false);
  };
  const stop = () => { stopRef.current = true; setRunning(false); };

  const tips = t('tools.ping.tips') || [];

  return (
    <ToolPage icon={<Icon.ping/>} title={t('tools.ping.title')} lede={t('tools.ping.lede')} sidebar={<Sidebar tips={tips}/>}>
      <div className="card card-pad-lg">
        <label className="eyebrow" style={{ display: 'block', marginBottom: 8 }}>{t('tools.ping.hostLabel')}</label>
        <div className="input-wrap">
          <input className="input" value={host} onChange={e => setHost(e.target.value.trim())}
            placeholder={t('tools.ping.placeholder')} disabled={running}
            onKeyDown={e => e.key === 'Enter' && start()}/>
          {!running ? <button className="btn btn-primary" onClick={start}>{t('tools.ping.start')}</button>
                    : <button className="btn" onClick={stop}>{t('tools.ping.stop')}</button>}
        </div>
      </div>

      <div className="terminal">
        <div className="terminal-bar">
          <span className="dots"><i/><i/><i/></span>
          <span>ping — {host}</span>
          {running && <span style={{ marginLeft: 'auto' }} className="row"><span className="dot green"/> {t('tools.ping.running')}</span>}
        </div>
        <div className="terminal-body" ref={termRef}>
          {lines.length === 0 && !running && <span className="t-dim">{t('tools.ping.ready')}</span>}
          {lines.map((l, i) => (
            <div key={i} className="terminal-line">
              {l.k === 'dim' && <span className="t-dim">{l.t}</span>}
              {l.k === 'out' && <span>{l.t}</span>}
              {l.k === 'ok'  && <span className="t-ok">{l.t}</span>}
              {l.k === 'err' && <span className="t-err">{l.t}</span>}
            </div>
          ))}
          {running && <div className="terminal-line"><span className="t-prompt">▌</span></div>}
        </div>
      </div>

      <div>
        <div className="eyebrow" style={{ marginBottom: 10 }}>{t('tools.ping.statsTitle')}</div>
        <div className="stats-grid">
          <Stat k={t('tools.ping.min')}  v={stats ? stats.min.toFixed(1)  : '—'} u="ms"/>
          <Stat k={t('tools.ping.avg')}  v={stats ? stats.avg.toFixed(1)  : '—'} u="ms" hl/>
          <Stat k={t('tools.ping.max')}  v={stats ? stats.max.toFixed(1)  : '—'} u="ms"/>
          <Stat k={t('tools.ping.loss')} v={stats ? stats.loss.toFixed(0) : '—'} u="%"/>
        </div>
      </div>

      {stats && <PingInterpretation stats={stats}/>}
    </ToolPage>
  );
}

function Stat({ k, v, u, hl }) {
  return (
    <div className="stat" style={hl ? { borderColor: 'var(--accent)' } : undefined}>
      <div className="k">{k}</div>
      <div className="v" style={hl ? { color: 'var(--accent)' } : undefined}>{v}<span className="u">{u}</span></div>
    </div>
  );
}

function PingInterpretation({ stats }) {
  const t = useT();
  const lat = stats.avg, jit = stats.mdev, loss = stats.loss;

  const latKey  = lat < 30 ? 'excellent' : lat < 60 ? 'veryGood' : lat < 100 ? 'ok' : lat < 200 ? 'high' : 'veryHigh';
  const jitKey  = jit < 5 ? 'stable' : jit < 15 ? 'slightly' : 'unstable';
  const lossKey = loss === 0 ? 'none' : loss < 2 ? 'min' : loss < 10 ? 'mod' : 'high';

  const tone = (key, type) => {
    if (type === 'lat')  return ['excellent','veryGood'].includes(key) ? 'green' : ['ok','high'].includes(key) ? 'amber' : 'red';
    if (type === 'jit')  return key === 'stable' ? 'green' : key === 'slightly' ? 'amber' : 'red';
    return key === 'none' ? 'green' : key === 'high' ? 'red' : 'amber';
  };

  const latTone = tone(latKey, 'lat');
  const jitTone = tone(jitKey, 'jit');
  const lossTone = tone(lossKey, 'loss');
  const tones = [latTone, jitTone, lossTone];
  const overallKey = tones.includes('red') ? 'problems' : tones.includes('amber') ? 'okay' : 'healthy';
  const overallTone = overallKey === 'problems' ? 'red' : overallKey === 'okay' ? 'amber' : 'green';

  const [latLabel, latText]   = t(`tools.ping.latTier.${latKey}`)   || ['', ''];
  const [jitLabel, jitText]   = t(`tools.ping.jitTier.${jitKey}`)   || ['', ''];
  const [lossLabel, lossText] = t(`tools.ping.lossTier.${lossKey}`) || ['', ''];
  const [overallLabel, overallTextRaw] = t(`tools.ping.overall.${overallKey}`) || ['', ''];
  const overallText = overallTextRaw.replace('{host}', stats.host);

  const ranges = t('tools.ping.ranges') || [];
  const rangeTones = ['green', 'green', 'amber', 'red'];

  return (
    <div className="card card-pad-lg fade-in">
      <div className="eyebrow" style={{ marginBottom: 8 }}>{t('tools.ping.meaning')}</div>
      <div className="row" style={{ gap: 10, marginBottom: 6 }}>
        <span className={'chip ' + overallTone}><span className={'dot ' + overallTone}/> {overallLabel}</span>
      </div>
      <p style={{ margin: '0 0 20px', color: 'var(--text-2)' }}>{overallText}</p>

      <div className="stack" style={{ gap: 12 }}>
        <Verdict tone={latTone}  title={t('tools.ping.verdictH.lat',  { label: latLabel,  avg:  stats.avg.toFixed(1)  })} text={latText}/>
        <Verdict tone={jitTone}  title={t('tools.ping.verdictH.jit',  { label: jitLabel,  mdev: stats.mdev.toFixed(1) })} text={jitText}/>
        <Verdict tone={lossTone} title={t('tools.ping.verdictH.loss', { label: lossLabel, loss: stats.loss.toFixed(0) })} text={lossText}/>
      </div>

      <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <div className="eyebrow" style={{ marginBottom: 10 }}>{t('tools.ping.latencyRef')}</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8, fontSize: 12 }}>
          {ranges.map((r, i) => <RangeRef key={i} tone={rangeTones[i]} range={r.range} use={r.use}/>)}
        </div>
      </div>
    </div>
  );
}

function Verdict({ tone, title, text }) {
  return (
    <div style={{
      display: 'flex', gap: 12, padding: '12px 14px',
      background: 'var(--bg-2)', border: '1px solid var(--border)', borderRadius: 10,
      borderLeft: `3px solid var(--${tone === 'green' ? 'accent' : tone === 'amber' ? 'warn' : 'danger'})`,
    }}>
      <span className={'dot ' + tone} style={{ marginTop: 6, flex: 'none' }}/>
      <div>
        <div style={{ fontWeight: 500, fontSize: 14 }}>{title}</div>
        <div style={{ fontSize: 13, color: 'var(--text-2)', marginTop: 2, lineHeight: 1.55 }}>{text}</div>
      </div>
    </div>
  );
}

function RangeRef({ tone, range, use }) {
  return (
    <div style={{ padding: '10px 12px', background: 'var(--bg-2)', border: '1px solid var(--border)', borderRadius: 8 }}>
      <div className="row" style={{ gap: 6, marginBottom: 4 }}>
        <span className={'dot ' + tone}/>
        <span className="mono" style={{ fontSize: 12, fontWeight: 500 }}>{range}</span>
      </div>
      <div style={{ color: 'var(--text-3)', fontSize: 11 }}>{use}</div>
    </div>
  );
}

function wait(ms) { return new Promise(r => setTimeout(r, ms)); }

// ---------- WHOIS ----------
function WhoisPage() {
  const t = useT();
  const [domain, setDomain]   = useState('globo.com');
  const [data, setData]       = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError]     = useState(null);

  const lookup = async (d = domain) => {
    if (!d) return;
    setLoading(true); setData(null); setError(null);
    try {
      const res = await fetch(`/api/whois?domain=${encodeURIComponent(d.trim())}`);
      const json = await res.json();
      if (!res.ok) throw new Error(json.message || 'WHOIS error');
      setData(json);
      pushHistory({ kind: 'WHOIS', q: d });
    } catch (err) {
      setError(err.message || 'Error');
    }
    setLoading(false);
  };

  useEffect(() => { lookup(); /* eslint-disable-next-line */ }, []);

  const tips = t('tools.whois.tips') || [];

  return (
    <ToolPage icon={<Icon.whois/>} title={t('tools.whois.title')} lede={t('tools.whois.lede')} sidebar={<Sidebar tips={tips}/>}>
      <div className="card card-pad-lg">
        <label className="eyebrow" style={{ display: 'block', marginBottom: 8 }}>{t('tools.whois.domainLabel')}</label>
        <div className="input-wrap">
          <input className="input" value={domain} onChange={e => setDomain(e.target.value.trim())}
            placeholder={t('tools.whois.placeholder')}
            onKeyDown={e => e.key === 'Enter' && lookup()}/>
          <button className="btn btn-primary" onClick={() => lookup()}>
            {loading ? t('tools.btn.loading') : t('tools.btn.go')}
          </button>
        </div>
      </div>

      {loading && <div className="card card-pad"><span className="skeleton" style={{ width: '60%' }}/></div>}
      {error   && <div className="card card-pad" style={{ color: 'var(--danger)', fontSize: 14 }}>{error}</div>}

      {data && (
        <div className="card">
          <div className="card-pad" style={{ borderBottom: '1px solid var(--border)' }}>
            <div className="between">
              <div>
                <div className="eyebrow">{t('tools.whois.domain')}</div>
                <div className="row" style={{ gap: 8, marginTop: 4 }}>
                  <span className="mono" style={{ fontSize: 18, color: 'var(--accent)' }}>{data.domain}</span>
                  <span className={'chip ' + (data.daysLeft > 60 ? 'green' : data.daysLeft > 14 ? 'amber' : 'red')}>
                    {t('tools.whois.expiresIn', { days: data.daysLeft })}
                  </span>
                </div>
              </div>
              <CopyBtn value={JSON.stringify(data.fields, null, 2)} label={t('common.copy')}/>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0 }}>
            {data.fields.map((f, i) => (
              <div key={i} style={{ padding: '14px 18px', borderBottom: i < data.fields.length - 2 ? '1px solid var(--border)' : 0, borderRight: i % 2 === 0 ? '1px solid var(--border)' : 0 }}>
                <div className="k" style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--text-3)' }}>{f.k}</div>
                <div className={'v ' + (f.mono ? 'mono' : '')} style={{ marginTop: 4, fontSize: 14, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.v}</div>
              </div>
            ))}
          </div>
          {data.raw && (
            <div className="card-pad" style={{ borderTop: '1px solid var(--border)' }}>
              <div className="eyebrow" style={{ marginBottom: 8 }}>{t('tools.whois.rawTitle')}</div>
              <pre className="mono" style={{ margin: 0, fontSize: 12, color: 'var(--text-2)', whiteSpace: 'pre-wrap', lineHeight: 1.6, maxHeight: 300, overflowY: 'auto' }}>{data.raw}</pre>
            </div>
          )}
        </div>
      )}
    </ToolPage>
  );
}

// ---------- Speed Test ----------
function SpeedPage() {
  const t = useT();
  const [phase, setPhase]       = useState('idle');
  const [ping, setPing]         = useState(0);
  const [down, setDown]         = useState(0);
  const [up, setUp]             = useState(0);
  const [progress, setProgress] = useState(0);

  const start = async () => {
    setPhase('ping'); setPing(0); setDown(0); setUp(0); setProgress(0);
    pushHistory({ kind: 'Speed', q: 'started' });
    for (let i = 0; i <= 100; i += 10) { setProgress(i); setPing(8 + Math.random() * 10); await wait(60); }
    setPing(12 + Math.random() * 6);
    setPhase('down'); setProgress(0);
    let target = 280 + Math.random() * 180;
    for (let i = 0; i <= 100; i += 4) { setProgress(i); setDown(target * (0.5 + Math.sin(i / 18) * 0.1) * (i / 100 + 0.5)); await wait(50); }
    setDown(target);
    setPhase('up'); setProgress(0);
    let upTarget = target * (0.2 + Math.random() * 0.3);
    for (let i = 0; i <= 100; i += 4) { setProgress(i); setUp(upTarget * (0.5 + Math.cos(i / 18) * 0.1) * (i / 100 + 0.5)); await wait(50); }
    setUp(upTarget);
    setPhase('done');
  };

  const current = phase === 'down' ? down : phase === 'up' ? up : phase === 'ping' ? ping : down;
  const max     = phase === 'ping' ? 50 : 600;
  const labelKey = phase === 'ping' ? 'ping' : phase === 'down' ? 'download' : phase === 'up' ? 'upload' : 'download';
  const label   = t(`tools.speed.labels.${labelKey}`);
  const unit    = phase === 'ping' ? 'ms' : 'Mbps';
  const phaseName = phase !== 'idle' && phase !== 'done' ? t('tools.speed.' + (phase === 'down' ? 'download' : phase === 'up' ? 'upload' : 'ping')) : '';

  const tips = t('tools.speed.tips') || [];

  return (
    <ToolPage icon={<Icon.speed/>} title={t('tools.speed.title')} lede={t('tools.speed.lede')} sidebar={<Sidebar tips={tips}/>}>
      <div className="card card-pad-lg" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 24 }}>
        <Gauge value={current} max={max} label={label} unit={unit}/>
        <div className="progress" style={{ width: '100%', maxWidth: 380 }}>
          <i style={{ width: `${phase === 'idle' || phase === 'done' ? 0 : progress}%` }}/>
        </div>
        {phase === 'idle' && <button className="btn btn-primary btn-lg" onClick={start}><Icon.zap/> {t('tools.speed.start')}</button>}
        {phase !== 'idle' && phase !== 'done' && <span className="chip green"><span className="dot green"/> {t('tools.speed.measuring', { phase: phaseName.toLowerCase() })}</span>}
        {phase === 'done' && <button className="btn" onClick={start}>{t('tools.speed.again')}</button>}
      </div>

      <div className="stats-grid" style={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
        <Stat k={t('tools.speed.ping')}     v={ping ? ping.toFixed(0) : '—'} u="ms"/>
        <Stat k={t('tools.speed.download')} v={down ? down.toFixed(1) : '—'} u="Mbps" hl/>
        <Stat k={t('tools.speed.upload')}   v={up   ? up.toFixed(1)   : '—'} u="Mbps"/>
      </div>

      <div className="card card-pad">
        <div className="eyebrow" style={{ marginBottom: 10 }}>{t('tools.speed.serverTitle')}</div>
        <div className="between">
          <div>
            <div style={{ fontWeight: 500 }}>São Paulo · BR</div>
            <div style={{ fontSize: 13, color: 'var(--text-3)' }}>NIC.br · IX.br Metro</div>
          </div>
          <span className="chip green"><span className="dot green"/> {t('tools.speed.distance', { ms: 4 })}</span>
        </div>
      </div>
    </ToolPage>
  );
}

function Gauge({ value, max, label, unit }) {
  const pct = Math.max(0, Math.min(1, (value || 0) / max));
  const r = 130, cx = 150, cy = 150;
  const arcLen = Math.PI * r;
  const trackPath = `M ${cx - r} ${cy} A ${r} ${r} 0 0 1 ${cx + r} ${cy}`;
  return (
    <div className="gauge">
      <svg viewBox="0 0 300 165">
        <path d={trackPath} fill="none" stroke="var(--bg-2)" strokeWidth="14" strokeLinecap="round"/>
        <path d={trackPath} fill="none" stroke="var(--accent)" strokeWidth="14" strokeLinecap="round"
          strokeDasharray={arcLen} strokeDashoffset={arcLen * (1 - pct)}
          style={{ transition: 'stroke-dashoffset 120ms linear' }}/>
        {Array.from({ length: 11 }).map((_, i) => {
          const a = ((-180 + i * 18) * Math.PI) / 180;
          return <line key={i}
            x1={cx + (r - 22) * Math.cos(a)} y1={cy + (r - 22) * Math.sin(a)}
            x2={cx + (r - 30) * Math.cos(a)} y2={cy + (r - 30) * Math.sin(a)}
            stroke="var(--text-3)" strokeWidth="1.2" opacity="0.4"/>;
        })}
      </svg>
      <div className="gauge-readout">
        <div className="label">{label}</div>
        <div className="num">{value ? value.toFixed(value < 100 ? 1 : 0) : '0'}</div>
        <div className="unit">{unit}</div>
      </div>
    </div>
  );
}

// ---------- Reverse DNS ----------
function ReversePage() {
  const t = useT();
  const [ip, setIp]         = useState('8.8.8.8');
  const [data, setData]     = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError]   = useState(null);

  const lookup = async (addr = ip) => {
    if (!addr) return;
    setLoading(true); setData(null); setError(null);
    try {
      const res = await fetch(`/api/reverse?ip=${encodeURIComponent(addr.trim())}`);
      const json = await res.json();
      if (!res.ok) throw new Error(json.message || 'Error');
      setData(json);
      pushHistory({ kind: 'rDNS', q: addr });
    } catch (err) {
      setError(err.message || 'Error');
    }
    setLoading(false);
  };

  useEffect(() => { lookup(); /* eslint-disable-next-line */ }, []);

  const tips = t('tools.reverse.tips') || [];

  return (
    <ToolPage icon={<Icon.reverse/>} title={t('tools.reverse.title')} lede={t('tools.reverse.lede')} sidebar={<Sidebar tips={tips}/>}>
      <div className="card card-pad-lg">
        <label className="eyebrow" style={{ display: 'block', marginBottom: 8 }}>{t('tools.reverse.ipLabel')}</label>
        <div className="input-wrap">
          <input className="input" value={ip} onChange={e => setIp(e.target.value.trim())}
            placeholder={t('tools.reverse.placeholder')}
            onKeyDown={e => e.key === 'Enter' && lookup()}/>
          <button className="btn btn-primary" onClick={() => lookup()}>
            {loading ? t('tools.btn.loading') : t('tools.btn.go')}
          </button>
        </div>
      </div>

      {loading && <div className="card card-pad"><span className="skeleton" style={{ width: '60%' }}/></div>}
      {error   && <div className="card card-pad" style={{ color: 'var(--danger)', fontSize: 14 }}>{error}</div>}

      {data && (
        <div className="card">
          <div className="card-pad">
            <div className="ip-row" style={{ marginBottom: 12 }}>
              <div>
                <div className="label">{t('tools.reverse.ipTitle')}</div>
                <div className="value">{data.ip}</div>
              </div>
              <CopyBtn value={data.ip} label={t('common.copy')}/>
            </div>
            <div className="ip-row" style={{ marginBottom: 12 }}>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div className="label">{t('tools.reverse.ptrTitle')}</div>
                <div className="value mono" style={{ fontSize: 16 }}>{data.ptr}</div>
              </div>
              <CopyBtn value={data.ptr} label={t('common.copy')}/>
            </div>
            <div className="row" style={{ gap: 8, flexWrap: 'wrap' }}>
              <span className={'chip ' + (data.match ? 'green' : 'red')}>
                {data.match ? <Icon.check/> : '✕'} {data.match ? t('tools.reverse.valid') : t('tools.reverse.invalid')}
              </span>
              {data.asn !== '—' && <span className="chip mono">{data.asn}</span>}
              {data.org !== '—' && <span className="chip">{data.org}</span>}
            </div>
          </div>
        </div>
      )}
    </ToolPage>
  );
}

Object.assign(window, { DNSPage, PingPage, WhoisPage, SpeedPage, ReversePage });
