// Расчёт окон видимости: КА↔станция (для сброса) и КА↔наземная точка (для съёмки).
// В реальной системе это запрос к внешнему сервису; здесь — локальная модель
// на орбитальной геометрии (orbit.jsx). Возвращает интервалы [start,end] в мс.
const RE = 6371;

function gcDistDeg(lat1, lon1, lat2, lon2) {
  const a1 = lat1 * DEG, a2 = lat2 * DEG;
  const dLon = (lon2 - lon1) * DEG;
  const c = Math.sin(a1) * Math.sin(a2) + Math.cos(a1) * Math.cos(a2) * Math.cos(dLon);
  return Math.acos(Math.max(-1, Math.min(1, c))) * RAD;
}

// Центральный угол доступа для минимального угла места (станция приёма).
function accessAngleDeg(h, minElevDeg) {
  const e = (minElevDeg || 5) * DEG;
  const ratio = RE / (RE + h);
  return (Math.acos(ratio * Math.cos(e)) - e) * RAD;
}

// Общий сканер: возвращает интервалы, где расстояние ≤ thresholdDeg.
function scanWindows(p, lat, lon, t0, t1, thresholdDeg, stepMs) {
  const step = stepMs || 30000;
  const out = [];
  let inWin = false, segStart = 0, best = 0;
  for (let t = t0; t <= t1; t += step) {
    const s = subPoint(p, t);
    const d = gcDistDeg(s.lat, s.lon, lat, lon);
    const vis = d <= thresholdDeg;
    if (vis && !inWin) { inWin = true; segStart = t; best = thresholdDeg - d; }
    else if (vis && inWin) { best = Math.max(best, thresholdDeg - d); }
    else if (!vis && inWin) {
      inWin = false;
      out.push({ start: segStart, end: t, quality: best / thresholdDeg });
    }
  }
  if (inWin) out.push({ start: segStart, end: t1, quality: best / thresholdDeg });
  // отбросить слишком короткие (< 40 c)
  return out.filter((w) => w.end - w.start >= 40000);
}

// Окна видимости станции данным КА (для сброса). Возвращает [{start,end,quality}].
function stationPasses(p, station, t0, t1) {
  const thr = accessAngleDeg(p.h, 5);
  return scanWindows(p, station.lat, station.lon, t0, t1, thr, 30000);
}

// Окна видимости наземной точки (для съёмки). Угол меньше: ограничен агильностью
// (отклонение от надира) аппарата. ~6–7° центрального угла.
function targetPasses(p, lat, lon, t0, t1) {
  const thr = 6.5;
  return scanWindows(p, lat, lon, t0, t1, thr, 20000);
}

Object.assign(window, { gcDistDeg, accessAngleDeg, scanWindows, stationPasses, targetPasses });
