// F19. Полёт ракеты (финал курса в ch4) — Циолковский + гравитация + сопротивление.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

function init(secId){
  if (!B()) return false;
  const body = ''
    + '<div class="flag-sliders">'
      + '<label>Сухая масса $m_0$, т: <b id="F19-m0v">5</b><input type="range" id="F19-m0" min="1" max="20" step="0.5" value="5"></label>'
      + '<label>Топливо $m_f$, т: <b id="F19-mfv">95</b><input type="range" id="F19-mf" min="10" max="500" step="5" value="95"></label>'
      + '<label>$v_{газов}$, м/с: <b id="F19-uv">3000</b><input type="range" id="F19-u" min="1000" max="5000" step="100" value="3000"></label>'
      + '<label>Расход топлива, т/с: <b id="F19-qv">2</b><input type="range" id="F19-q" min="0.2" max="10" step="0.1" value="2"></label>'
    + '</div>'
    + '<canvas id="F19-cv" class="flag-canvas" width="700" height="420" style="height:420px"></canvas>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn primary" id="F19-go">ЗАПУСК!</button>'
      + '<button class="flag-btn" id="F19-reset">Сброс</button>'
    + '</div>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">Время</span><span class="val" id="F19-t">0 с</span></div>'
      + '<div class="flag-stat"><span class="lbl">Высота</span><span class="val" id="F19-h">0 м</span></div>'
      + '<div class="flag-stat"><span class="lbl">Скорость</span><span class="val" id="F19-v">0 м/с</span></div>'
      + '<div class="flag-stat"><span class="lbl">Топливо</span><span class="val" id="F19-fuel">100%</span></div>'
      + '<div class="flag-stat"><span class="lbl">Перегрузка</span><span class="val" id="F19-g">0 g</span></div>'
    + '</div>'
    + '<div class="flag-feedback" id="F19-fb"></div>';

  const card = B().makeCard(secId,
    'F19. Полёт ракеты <span class="flag-medal">МАГИСТР</span>',
    'Запусти ракету с Земли на орбиту 400 км (МКС). Физика: тяга по Циолковскому, сила тяжести g(h), сопротивление атмосферы. Финальный босс курса!',
    body);
  if (!card) return false;

  const cv = document.getElementById('F19-cv');
  const ctx = cv.getContext('2d');
  const W = cv.width, H = cv.height;

  let st = { t: 0, h: 0, v: 0, m: 0, mf: 0, running: false, ended: false, history: [] };

  function readSliders(){
    document.getElementById('F19-m0v').textContent = (+document.getElementById('F19-m0').value).toFixed(1);
    document.getElementById('F19-mfv').textContent = (+document.getElementById('F19-mf').value).toFixed(0);
    document.getElementById('F19-uv').textContent = (+document.getElementById('F19-u').value).toFixed(0);
    document.getElementById('F19-qv').textContent = (+document.getElementById('F19-q').value).toFixed(1);
  }

  function reset(){
    const m0 = +document.getElementById('F19-m0').value * 1000;  /* кг */
    const mf = +document.getElementById('F19-mf').value * 1000;
    st = { t: 0, h: 0, v: 0, m: m0 + mf, mf: mf, m0: m0, mf0: mf, running: false, ended: false, history: [] };
    document.getElementById('F19-go').textContent = 'ЗАПУСК!';
    document.getElementById('F19-fb').className = 'flag-feedback';
    draw();
  }

  function tick(dt){
    if (!st.running || st.ended) { draw(); return; }
    const u = +document.getElementById('F19-u').value;
    const q = +document.getElementById('F19-q').value * 1000;  /* кг/с */
    const G = 6.674e-11, M = 5.972e24, R = 6.371e6;
    const N = 4;
    const ddt = dt / N;
    for (let i = 0; i < N; i++){
      const dm = Math.min(st.mf, q * ddt);
      const thrust = (dm > 1e-3) ? q * u : 0;
      const g = G * M / Math.pow(R + st.h, 2);
      /* атм сопротивление: плотность падает с высотой, упрощённо */
      const rho = st.h < 80000 ? 1.225 * Math.exp(-st.h/8000) : 0;
      const drag = 0.3 * rho * st.v * Math.abs(st.v) * 5;  /* k*ρ*v²*A */
      const F_net = thrust - st.m * g - Math.sign(st.v) * drag;
      const a = F_net / st.m;
      st.v += a * ddt;
      st.h += st.v * ddt;
      st.mf = Math.max(0, st.mf - dm);
      st.m = st.m0 + st.mf;
      st.t += ddt;
      st.history.push({ t: st.t, h: st.h, v: st.v });
      if (st.history.length > 1000) st.history.shift();
      /* окончание */
      if (st.h < 0){ st.ended = true; st.running = false; document.getElementById('F19-go').textContent='ЗАПУСК!'; break; }
      if (st.t > 600){ st.ended = true; st.running = false; document.getElementById('F19-go').textContent='ЗАПУСК!'; break; }
    }
    /* stats */
    document.getElementById('F19-t').textContent = st.t.toFixed(1) + ' с';
    document.getElementById('F19-h').textContent = (st.h/1000).toFixed(1) + ' км';
    document.getElementById('F19-v').textContent = st.v.toFixed(0) + ' м/с';
    document.getElementById('F19-fuel').textContent = (st.mf/st.mf0*100).toFixed(0) + '%';
    /* перегрузка во время тяги */
    const u2 = +document.getElementById('F19-u').value;
    const q2 = +document.getElementById('F19-q').value * 1000;
    const thrust2 = (st.mf > 1e-3) ? q2 * u2 : 0;
    const G2 = 6.674e-11, M2 = 5.972e24, R2 = 6.371e6;
    const g2 = G2 * M2 / Math.pow(R2 + st.h, 2);
    const a2 = (thrust2 - st.m * g2) / st.m;
    document.getElementById('F19-g').textContent = ((a2/9.8) + 1).toFixed(2) + ' g';
    /* feedback */
    const fb = document.getElementById('F19-fb');
    if (st.ended && st.h < 1){
      fb.className = 'flag-feedback fail show';
      fb.innerHTML = '&#10007; КРАШ. Ракета упала на Землю — не хватило топлива/тяги.';
    } else if (st.h >= 400000 && Math.abs(st.v) < 100 && st.ended){
      fb.className = 'flag-feedback ok show';
      fb.innerHTML = '&#10003; УСПЕХ! Ракета на орбите МКС (400 км). Магистр Физики 9 — Вы!';
      try { localStorage.setItem('phys9_F19_success', '1'); if(window.addXp) window.addXp(150, 'F19-magistr'); } catch(e){}
    } else if (st.h > 400000){
      fb.className = 'flag-feedback warn show';
      fb.innerHTML = 'Высоко! Но нужна ещё горизонтальная скорость для орбиты ($\\sim 7.7$ км/с). Это упрощённая 1D модель.';
    }
    draw();
  }

  function draw(){
    const col = C();
    ctx.fillStyle = '#0f172a';  /* космос */
    ctx.fillRect(0, 0, W, H);
    /* звёзды */
    ctx.fillStyle = '#fff';
    for (let i = 0; i < 80; i++) ctx.fillRect((i*37+11)%W, (i*73+19)%H, 1, 1);
    /* Земля внизу */
    const earthY = H - 30;
    ctx.fillStyle = '#16a34a';
    ctx.fillRect(0, earthY, W, 30);
    ctx.fillStyle = col.forceGravity || '#2563eb';
    ctx.beginPath(); ctx.arc(W/2, earthY + 100, 80, 0, Math.PI*2); ctx.fill();
    /* шкала высоты по правому краю */
    ctx.fillStyle = '#fff';
    ctx.font = '10px Inter,sans-serif';
    const maxH = Math.max(450000, st.h * 1.1);
    for (let k = 0; k <= 4; k++){
      const h = maxH * k/4;
      const py = earthY - (h/maxH) * (earthY - 40);
      ctx.fillText((h/1000).toFixed(0) + ' км', W - 60, py + 3);
      ctx.strokeStyle = 'rgba(255,255,255,0.2)';
      ctx.beginPath(); ctx.moveTo(40, py); ctx.lineTo(W - 65, py); ctx.stroke();
    }
    /* 400 км — целевая орбита */
    const targetY = earthY - (400000/maxH) * (earthY - 40);
    ctx.strokeStyle = '#fbbf24';
    ctx.setLineDash([8, 5]);
    ctx.lineWidth = 2;
    ctx.beginPath(); ctx.moveTo(0, targetY); ctx.lineTo(W, targetY); ctx.stroke();
    ctx.setLineDash([]);
    ctx.fillStyle = '#fbbf24';
    ctx.font = 'bold 11px Inter,sans-serif';
    ctx.fillText('★ цель: 400 км (МКС)', 10, targetY - 4);
    /* Ракета */
    const rocketX = 100;
    const rocketY = earthY - (st.h/maxH) * (earthY - 40);
    ctx.save();
    ctx.translate(rocketX, rocketY);
    /* корпус */
    ctx.fillStyle = '#e5e7eb';
    ctx.beginPath();
    ctx.moveTo(0, -22);
    ctx.lineTo(7, -16);
    ctx.lineTo(7, 14);
    ctx.lineTo(-7, 14);
    ctx.lineTo(-7, -16);
    ctx.closePath();
    ctx.fill();
    ctx.strokeStyle = '#0f172a';
    ctx.stroke();
    /* окошко */
    ctx.fillStyle = '#0891b2';
    ctx.beginPath(); ctx.arc(0, -8, 3, 0, Math.PI*2); ctx.fill();
    /* плавники */
    ctx.fillStyle = '#dc2626';
    ctx.beginPath();
    ctx.moveTo(-7, 14); ctx.lineTo(-12, 22); ctx.lineTo(-7, 18); ctx.fill();
    ctx.beginPath();
    ctx.moveTo(7, 14); ctx.lineTo(12, 22); ctx.lineTo(7, 18); ctx.fill();
    /* выхлоп */
    if (st.running && st.mf > 0){
      ctx.fillStyle = '#fbbf24';
      ctx.beginPath();
      ctx.moveTo(-5, 18);
      ctx.lineTo(0, 18 + 10 + Math.random()*8);
      ctx.lineTo(5, 18);
      ctx.fill();
      ctx.fillStyle = '#dc2626';
      ctx.beginPath();
      ctx.moveTo(-3, 18);
      ctx.lineTo(0, 18 + 6 + Math.random()*4);
      ctx.lineTo(3, 18);
      ctx.fill();
    }
    ctx.restore();
    /* график высота(t) справа */
    if (st.history.length > 1){
      ctx.strokeStyle = '#fbbf24';
      ctx.lineWidth = 2;
      ctx.beginPath();
      for (let i = 0; i < st.history.length; i++){
        const p = st.history[i];
        const py = earthY - (p.h/maxH) * (earthY - 40);
        const px = 200 + (p.t/Math.max(60, st.t)) * (W - 290);
        if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
      }
      ctx.stroke();
    }
  }

  document.getElementById('F19-go').addEventListener('click', ()=>{
    if (st.ended) reset();
    st.running = !st.running;
    document.getElementById('F19-go').textContent = st.running ? 'ПАУЗА' : 'ЗАПУСК!';
  });
  document.getElementById('F19-reset').addEventListener('click', reset);
  ['F19-m0','F19-mf','F19-u','F19-q'].forEach(id => document.getElementById(id).addEventListener('input', ()=>{
    readSliders();
    if (!st.running) reset();
  }));

  readSliders();
  reset();
  B().startLoop('F19', cv, tick);
  return true;
}

if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F19', { init: init, cleanup: function(){} });
else document.addEventListener('DOMContentLoaded', ()=>{
  if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F19', { init: init, cleanup: function(){} });
});

})();
