// F18. Магистр-симулятор (final5 в ch5) — конструктор сценария движения тела.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

const STAGE_TYPES = {
  uniform: { name: 'Равномерное', color: '#0891b2' },
  accel:   { name: 'Равноуск.',   color: '#ea580c' },
  fall:    { name: 'Своб. падение', color: '#2563eb' },
  stop:    { name: 'Стоп / покой',  color: '#475569' }
};

function init(secId){
  if (!B()) return false;
  let typeBtns = '';
  for (const t in STAGE_TYPES){
    const s = STAGE_TYPES[t];
    typeBtns += '<button class="flag-btn" data-add="'+t+'" style="border-color:'+s.color+';color:'+s.color+'">+ '+s.name+'</button>';
  }
  const body = ''
    + '<div style="margin-bottom:8px;font-size:.85rem;color:var(--muted)">Собери цепочку этапов движения как LEGO. Программа рассчитает $x(t)$, $v(t)$, $a(t)$.</div>'
    + '<div class="flag-controls" id="F18-toolbox">'
      + typeBtns
      + '<button class="flag-btn danger" id="F18-clear">Очистить</button>'
      + '<button class="flag-btn" id="F18-preset">Шаблон: разгон+торможение</button>'
    + '</div>'
    + '<div id="F18-stages" style="display:flex;flex-wrap:wrap;gap:8px;padding:10px;background:var(--sec-acc-soft,#dbeafe);border-radius:11px;min-height:60px;margin:10px 0"></div>'
    + '<canvas id="F18-cv" class="flag-canvas" width="700" height="440" style="height:440px"></canvas>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">Этапов</span><span class="val" id="F18-n">0</span></div>'
      + '<div class="flag-stat"><span class="lbl">Общая длительность</span><span class="val" id="F18-tt">0 с</span></div>'
      + '<div class="flag-stat"><span class="lbl">Итог $x$</span><span class="val" id="F18-xt">0 м</span></div>'
      + '<div class="flag-stat"><span class="lbl">Итог $v$</span><span class="val" id="F18-vt">0 м/с</span></div>'
    + '</div>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn primary" id="F18-save">Сохранить сценарий</button>'
      + '<button class="flag-btn" id="F18-load">Загрузить мой</button>'
    + '</div>'
    + '<div class="flag-feedback" id="F18-fb"></div>';

  const card = B().makeCard(secId,
    'F18. Магистр-симулятор <span class="flag-medal">КОНСТРУКТОР</span>',
    'Финальный конструктор сценариев. Каждый этап — кусок движения. Программа считает $x(t)$, $v(t)$, $a(t)$ и проверяет согласованность.',
    body);
  if (!card) return false;

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

  let stages = [];  /* {type, duration, param} */

  function makeStageCard(idx){
    const s = stages[idx];
    const type = STAGE_TYPES[s.type];
    const paramLabel = {
      uniform: 'v, м/с',
      accel:   'a, м/с²',
      fall:    '— (g)',
      stop:    '—'
    }[s.type];
    const div = document.createElement('div');
    div.style.cssText = 'background:var(--card);border:2px solid '+type.color+';border-radius:9px;padding:8px 10px;display:flex;gap:8px;align-items:center;font-size:.85rem';
    div.innerHTML = ''
      + '<span style="font-weight:800;color:'+type.color+'">' + (idx+1) + '. ' + type.name + '</span>'
      + '<label>$\\Delta t$ с: <input type="number" min="0.5" max="60" step="0.5" value="'+s.duration+'" style="width:60px;padding:3px 6px;border:1px solid var(--border);border-radius:5px" data-i="'+idx+'" data-f="duration"></label>'
      + (paramLabel === '—' || paramLabel === '— (g)' ? '<span style="color:var(--muted)">'+paramLabel+'</span>' :
         '<label>'+paramLabel+': <input type="number" step="0.5" value="'+s.param+'" style="width:70px;padding:3px 6px;border:1px solid var(--border);border-radius:5px" data-i="'+idx+'" data-f="param"></label>')
      + '<button data-rm="'+idx+'" style="background:transparent;border:1px solid #dc2626;color:#dc2626;border-radius:5px;padding:2px 8px;cursor:pointer;font-weight:700">×</button>';
    return div;
  }

  function refreshStages(){
    const host = document.getElementById('F18-stages');
    host.innerHTML = '';
    if (stages.length === 0){
      host.innerHTML = '<span style="color:var(--muted);font-size:.85rem;align-self:center">Добавь этапы кнопками сверху…</span>';
    } else {
      stages.forEach((s, i) => host.appendChild(makeStageCard(i)));
    }
    host.querySelectorAll('input').forEach(inp => {
      inp.addEventListener('input', e => {
        const i = +e.target.dataset.i, f = e.target.dataset.f;
        const val = +e.target.value;
        if (!isNaN(val)) { stages[i][f] = val; recalculate(); }
      });
    });
    host.querySelectorAll('[data-rm]').forEach(btn => {
      btn.addEventListener('click', e => {
        const i = +e.target.dataset.rm;
        stages.splice(i, 1);
        refreshStages();
        recalculate();
      });
    });
    try { if(window.renderMathInElement) window.renderMathInElement(host, { delimiters:[{left:'$',right:'$',display:false}], throwOnError:false }); } catch(e){}
    recalculate();
  }

  function simulate(){
    /* Возвращает массив точек {t, x, v, a} */
    const pts = [];
    let t = 0, x = 0, v = 0, a = 0;
    pts.push({ t, x, v, a: 0 });
    for (const s of stages){
      const dt_step = 0.05;
      const end = t + s.duration;
      while (t < end - 1e-6){
        const step = Math.min(dt_step, end - t);
        if (s.type === 'uniform') { a = 0; v = s.param; }
        else if (s.type === 'accel') { a = s.param; }
        else if (s.type === 'fall') { a = -9.8; }
        else if (s.type === 'stop') { a = 0; v = 0; }
        v += a * step;
        x += v * step;
        t += step;
        pts.push({ t, x, v, a });
      }
    }
    return pts;
  }

  function recalculate(){
    const pts = simulate();
    const last = pts[pts.length-1];
    document.getElementById('F18-n').textContent = stages.length;
    document.getElementById('F18-tt').textContent = last.t.toFixed(1) + ' с';
    document.getElementById('F18-xt').textContent = last.x.toFixed(2) + ' м';
    document.getElementById('F18-vt').textContent = last.v.toFixed(2) + ' м/с';
    /* проверки */
    const fb = document.getElementById('F18-fb');
    if (stages.length === 0){
      fb.className = 'flag-feedback';
    } else {
      /* для разрывов: проверяем согласованность v между этапами */
      let warning = '';
      for (let i = 0; i < stages.length - 1; i++){
        const a = stages[i], b = stages[i+1];
        /* в реальности v сохраняется при переходе. Если b.type=uniform с фикс. v, может быть разрыв */
        if (b.type === 'uniform'){
          /* считаем v на конце a */
          let v_end = 0;
          if (a.type === 'uniform') v_end = a.param;
          else if (a.type === 'stop') v_end = 0;
          /* для accel и fall нужно знать v на начало a — пропускаем для упрощения */
          if (Math.abs(v_end - b.param) > 0.1){
            warning = '⚠ После этапа '+(i+1)+' скорость '+v_end.toFixed(1)+' м/с, но '+(i+2)+'-й этап задаёт '+b.param.toFixed(1)+' м/с — это рывок.';
            break;
          }
        }
      }
      if (warning){
        fb.className = 'flag-feedback warn show';
        fb.innerHTML = warning;
      } else {
        fb.className = 'flag-feedback ok show';
        fb.innerHTML = '&#10003; Сценарий согласован. Этапов: '+stages.length+', итог: x = '+last.x.toFixed(1)+' м, v = '+last.v.toFixed(1)+' м/с.';
      }
    }
    draw(pts);
  }

  function draw(pts){
    const col = C();
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(0, 0, W, H);
    if (pts.length < 2){
      ctx.fillStyle = col.textMuted || '#64748b';
      ctx.font = '15px Inter,sans-serif';
      ctx.fillText('Добавь этапы движения — увидь графики x(t), v(t), a(t)', 90, H/2);
      return;
    }
    /* 3 графика горизонтально */
    const tMax = pts[pts.length-1].t || 1;
    let xMin = 0, xMax = 0, vMin = 0, vMax = 0, aMin = 0, aMax = 0;
    for (const p of pts){
      xMin = Math.min(xMin, p.x); xMax = Math.max(xMax, p.x);
      vMin = Math.min(vMin, p.v); vMax = Math.max(vMax, p.v);
      aMin = Math.min(aMin, p.a); aMax = Math.max(aMax, p.a);
    }
    if (xMax - xMin < 0.5) xMax = xMin + 1;
    if (vMax - vMin < 0.5) vMax = vMin + 1;
    if (aMax - aMin < 0.5) aMax = aMin + 1;
    function plot(yOff, hOff, vals, vMin0, vMax0, color, label){
      ctx.fillStyle = col.bgSubtle || '#f8fafc';
      ctx.fillRect(40, yOff, W - 60, hOff);
      ctx.strokeStyle = col.axis || '#1e293b';
      ctx.lineWidth = 1.5;
      ctx.strokeRect(40, yOff, W - 60, hOff);
      /* zero-line */
      const zeroY = yOff + hOff - (0 - vMin0)/(vMax0 - vMin0) * hOff;
      ctx.strokeStyle = col.grid || '#e5e7eb';
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.moveTo(40, zeroY); ctx.lineTo(W - 20, zeroY);
      ctx.stroke();
      /* линия */
      ctx.strokeStyle = color;
      ctx.lineWidth = 2.5;
      ctx.beginPath();
      for (let i = 0; i < pts.length; i++){
        const t = pts[i].t;
        const v = vals[i];
        const px = 40 + (t / tMax) * (W - 60);
        const py = yOff + hOff - (v - vMin0)/(vMax0 - vMin0) * hOff;
        if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
      }
      ctx.stroke();
      /* label */
      ctx.fillStyle = color;
      ctx.font = 'bold 13px Inter,sans-serif';
      ctx.fillText(label, 8, yOff + 16);
      ctx.fillStyle = col.textMuted || '#64748b';
      ctx.font = '10px Inter,sans-serif';
      ctx.fillText(vMax0.toFixed(1), 8, yOff + 12);
      ctx.fillText(vMin0.toFixed(1), 8, yOff + hOff - 2);
    }
    const blockH = 130, gap = 10;
    plot(10,  blockH, pts.map(p => p.x), xMin, xMax, col.displacement || '#2563eb', 'x(t), м');
    plot(10 + blockH + gap, blockH, pts.map(p => p.v), vMin, vMax, col.velocity || '#0891b2', 'v(t), м/с');
    plot(10 + 2*(blockH + gap), blockH, pts.map(p => p.a), aMin, aMax, col.acceleration || '#ea580c', 'a(t), м/с²');
    /* x-axis label */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.font = '11px Inter,sans-serif';
    ctx.fillText('t = '+tMax.toFixed(1)+' с', W - 70, H - 4);
  }

  card.querySelectorAll('[data-add]').forEach(btn => {
    btn.addEventListener('click', () => {
      const type = btn.dataset.add;
      const def = { uniform: 5, accel: 1, fall: 0, stop: 0 }[type];
      stages.push({ type, duration: 3, param: def });
      refreshStages();
    });
  });
  document.getElementById('F18-clear').addEventListener('click', () => { stages = []; refreshStages(); });
  document.getElementById('F18-preset').addEventListener('click', () => {
    stages = [
      { type:'accel',   duration:5, param: 2 },
      { type:'uniform', duration:8, param:10 },
      { type:'accel',   duration:4, param:-2.5 }
    ];
    refreshStages();
  });
  document.getElementById('F18-save').addEventListener('click', () => {
    try {
      localStorage.setItem('phys9_F18_scenario', JSON.stringify(stages));
      const fb = document.getElementById('F18-fb');
      fb.className = 'flag-feedback ok show';
      fb.innerHTML = '&#10003; Сценарий сохранён в браузере.';
    } catch(e){}
  });
  document.getElementById('F18-load').addEventListener('click', () => {
    try {
      const s = JSON.parse(localStorage.getItem('phys9_F18_scenario') || 'null');
      if (Array.isArray(s)) { stages = s; refreshStages(); }
    } catch(e){}
  });

  refreshStages();
  draw([{t:0,x:0,v:0,a:0}]);
  return true;
}

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

})();
