function normalizeUrl(value) {
  return String(value || '').trim();
}

function normalizeShineWsUrl(rawUrl) {
  const value = normalizeUrl(rawUrl);
  if (!value) return '';
  if (value.startsWith('ws://') || value.startsWith('wss://')) {
    try {
      const parsed = new URL(value);
      if (!parsed.pathname || parsed.pathname === '/') parsed.pathname = '/ws';
      return parsed.toString();
    } catch {
      return value;
    }
  }
  if (value.startsWith('http://') || value.startsWith('https://')) {
    try {
      const parsed = new URL(value);
      parsed.protocol = parsed.protocol === 'https:' ? 'wss:' : 'ws:';
      if (!parsed.pathname || parsed.pathname === '/') parsed.pathname = '/ws';
      return parsed.toString();
    } catch {
      return `${value.replace(/^http/, 'ws').replace(/\/$/, '')}/ws`;
    }
  }
  return value;
}

async function checkSolanaRpc(url) {
  const endpoint = normalizeUrl(url);
  if (!endpoint) return false;
  try {
    const resp = await fetch(endpoint, {
      method: 'POST',
      cache: 'no-store',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method: 'getVersion',
      }),
    });
    if (!resp.ok) return false;
    const json = await resp.json();
    return Boolean(json?.result?.['solana-core'] || json?.result);
  } catch {
    return false;
  }
}

async function checkArweave(url) {
  const base = normalizeUrl(url).replace(/\/+$/, '');
  if (!base) return false;
  try {
    const resp = await fetch(`${base}/info`, { method: 'GET', cache: 'no-store' });
    if (!resp.ok) return false;
    const json = await resp.json();
    return Boolean(json?.network);
  } catch {
    return false;
  }
}

function checkShineWs(url, timeoutMs = 7000) {
  const wsUrl = normalizeShineWsUrl(url);
  if (!wsUrl) return Promise.resolve(false);

  return new Promise((resolve) => {
    let done = false;
    const finish = (ok) => {
      if (done) return;
      done = true;
      window.clearTimeout(timer);
      try { ws.close(); } catch {}
      resolve(Boolean(ok));
    };

    const timer = window.setTimeout(() => finish(false), timeoutMs);
    let ws;
    try {
      ws = new WebSocket(wsUrl);
    } catch {
      finish(false);
      return;
    }

    ws.addEventListener('open', () => {
      try {
        ws.send(JSON.stringify({
          op: 'Ping',
          requestId: `check-${Date.now()}`,
          payload: { ts: Date.now() },
        }));
      } catch {
        finish(false);
      }
    }, { once: true });

    ws.addEventListener('message', () => finish(true), { once: true });
    ws.addEventListener('error', () => finish(false), { once: true });
    ws.addEventListener('close', () => finish(false), { once: true });
  });
}

export async function checkServerAvailabilityByKey(key, url) {
  if (key === 'solanaServer') {
    return (await checkSolanaRpc(url)) ? 'available' : 'unavailable';
  }
  if (key === 'shineServer') {
    return (await checkShineWs(url)) ? 'available' : 'unavailable';
  }
  if (key === 'arweaveServer') {
    return (await checkArweave(url)) ? 'available' : 'unavailable';
  }
  return 'unavailable';
}

