// F9. Конструктор моста (§28 в ch3) — drag грузов, расчёт реакций опор.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

function init(secId){
  if (!B()) return false;
  const body = ''
    + '<div style="margin-bottom:8px;font-size:.85rem;color:var(--muted)">Перетащи грузы с верхней палитры на балку. Реакции опор $N_1$, $N_2$ рассчитываются автоматически.</div>'
    + '<div class="flag-controls" id="F9-palette">'
      + '<div class="flag-btn" data-mass="50" style="cursor:grab">50 кг</div>'
      + '<div class="flag-btn" data-mass="100" style="cursor:grab">100 кг</div>'
      + '<div class="flag-btn" data-mass="200" style="cursor:grab">200 кг</div>'
      + '<div class="flag-btn" data-mass="500" style="cursor:grab">500 кг</div>'
      + '<button class="flag-btn danger" id="F9-clear">Убрать все</button>'
      + '<button class="flag-btn" id="F9-test">Тест: автомобиль (1000 кг)</button>'
    + '</div>'
    + '<canvas id="F9-cv" class="flag-canvas" width="700" height="380" style="height:380px"></canvas>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">Грузов на балке</span><span class="val" id="F9-n">0</span></div>'
      + '<div class="flag-stat"><span class="lbl">Σ масс</span><span class="val" id="F9-m">0 кг</span></div>'
      + '<div class="flag-stat"><span class="lbl">$N_1$ (левая опора)</span><span class="val" id="F9-n1">0 Н</span></div>'
      + '<div class="flag-stat"><span class="lbl">$N_2$ (правая опора)</span><span class="val" id="F9-n2">0 Н</span></div>'
    + '</div>'
    + '<div class="flag-feedback" id="F9-fb"></div>';

  const card = B().makeCard(secId,
    'F9. Конструктор моста',
    'Через систему: $\\Sigma F = 0$, $\\Sigma M = 0$. Реакции опор $N_1, N_2$ балансируют все грузы. Лимит балки — 8000 Н на каждую опору.',
    body);
  if (!card) return false;

  const cv = document.getElementById('F9-cv');
  const ctx = cv.getContext('2d');
  const W = cv.width, H = cv.height;
  const beamY = 180, beamH = 16;
  const supL = 70, supR = W - 70;
  const beamLen = supR - supL;

  let loads = [];  /* {x, mass} */
  let broken = false;
  let dragging = null;  /* {mass, x, y} */

  function compute(){
    if (loads.length === 0) return { N1: 0, N2: 0, sum: 0, brokenSide: null };
    const g = 9.8;
    const L = supR - supL;
    /* Σ M вокруг левой опоры (supL): N2 * L - Σ(m*g*(x - supL)) = 0 */
    let sumMass = 0, sumMoment = 0;
    loads.forEach(l => {
      sumMass += l.mass;
      sumMoment += l.mass * g * (l.x - supL);
    });
    const N2 = sumMoment / L;
    const N1 = sumMass * g - N2;
    return { N1, N2, sum: sumMass*g, brokenSide: (N1 > 8000) ? 'left' : (N2 > 8000) ? 'right' : null };
  }

  function update(){
    const r = compute();
    document.getElementById('F9-n').textContent = loads.length;
    document.getElementById('F9-m').textContent = loads.reduce((s,l)=>s+l.mass,0) + ' кг';
    document.getElementById('F9-n1').textContent = r.N1.toFixed(0) + ' Н';
    document.getElementById('F9-n2').textContent = r.N2.toFixed(0) + ' Н';
    broken = !!r.brokenSide;
    const fb = document.getElementById('F9-fb');
    if (broken){
      fb.className = 'flag-feedback fail show';
      fb.innerHTML = '&#10007; МОСТ СЛОМАН! ' + (r.brokenSide === 'left' ? 'Левая' : 'Правая') + ' опора перегружена ('+(r.brokenSide==='left'?r.N1:r.N2).toFixed(0)+' Н > 8000 Н).';
    } else if (loads.length > 0){
      fb.className = 'flag-feedback ok show';
      fb.innerHTML = '&#10003; Балка выдерживает. Σ реакций = '+(r.N1+r.N2).toFixed(0)+' Н = $\\Sigma m g$ = '+r.sum.toFixed(0)+' Н.';
      try { if(window.renderMathInElement) window.renderMathInElement(fb, { delimiters:[{left:'$',right:'$',display:false}], throwOnError:false }); } catch(e){}
    } else {
      fb.className = 'flag-feedback';
    }
    draw();
  }

  function getPos(e){
    const rect = cv.getBoundingClientRect();
    const sx = cv.width / rect.width, sy = cv.height / rect.height;
    const x = ((e.touches ? e.touches[0].clientX : e.clientX) - rect.left) * sx;
    const y = ((e.touches ? e.touches[0].clientY : e.clientY) - rect.top) * sy;
    return { x, y };
  }

  function draw(){
    const col = C();
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(0, 0, W, H);
    /* земля */
    ctx.fillStyle = col.surface || '#a16207';
    ctx.fillRect(0, H - 30, W, 30);
    /* опоры */
    ctx.fillStyle = col.body || '#475569';
    ctx.beginPath();
    ctx.moveTo(supL, beamY + beamH);
    ctx.lineTo(supL - 22, H - 30);
    ctx.lineTo(supL + 22, H - 30);
    ctx.closePath(); ctx.fill();
    ctx.beginPath();
    ctx.moveTo(supR, beamY + beamH);
    ctx.lineTo(supR - 22, H - 30);
    ctx.lineTo(supR + 22, H - 30);
    ctx.closePath(); ctx.fill();
    /* балка */
    const tilt = broken ? 0 : 0;
    ctx.fillStyle = broken ? col.fail : col.bodyAccent || '#1e293b';
    if (broken){
      const r = compute();
      const breakX = r.brokenSide === 'left' ? supL + beamLen*0.3 : supL + beamLen*0.7;
      ctx.fillStyle = col.bodyAccent || '#1e293b';
      ctx.fillRect(supL - 30, beamY, breakX - supL + 30, beamH);
      ctx.save();
      ctx.translate(breakX + 30, beamY + beamH);
      ctx.rotate(0.3);
      ctx.fillRect(0, -beamH, supR - breakX + 30, beamH);
      ctx.restore();
    } else {
      ctx.fillRect(supL - 30, beamY, beamLen + 60, beamH);
    }
    /* подписи опор */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.font = 'bold 13px Inter,sans-serif';
    const r = compute();
    ctx.fillText('N₁ = '+r.N1.toFixed(0)+' Н', supL - 50, H - 8);
    ctx.fillText('N₂ = '+r.N2.toFixed(0)+' Н', supR - 50, H - 8);
    /* стрелки реакций */
    if (!broken && loads.length > 0){
      B().arrow(ctx, supL, H - 35, supL, beamY + beamH + 2, col.force || '#10b981', 2.5);
      B().arrow(ctx, supR, H - 35, supR, beamY + beamH + 2, col.force || '#10b981', 2.5);
    }
    /* грузы */
    loads.forEach(l => {
      const size = Math.min(36, 14 + Math.sqrt(l.mass) * 0.8);
      ctx.fillStyle = col.forceGravity || '#2563eb';
      ctx.fillRect(l.x - size/2, beamY - size, size, size);
      ctx.strokeStyle = col.bodyAccent || '#1e293b';
      ctx.lineWidth = 1.5;
      ctx.strokeRect(l.x - size/2, beamY - size, size, size);
      ctx.fillStyle = '#fff';
      ctx.font = 'bold 11px Inter,sans-serif';
      ctx.textAlign = 'center';
      ctx.fillText(l.mass+' кг', l.x, beamY - size/2 + 4);
      ctx.textAlign = 'left';
    });
    /* dragging shadow */
    if (dragging){
      const size = Math.min(36, 14 + Math.sqrt(dragging.mass) * 0.8);
      ctx.globalAlpha = 0.6;
      ctx.fillStyle = col.forceGravity || '#2563eb';
      ctx.fillRect(dragging.x - size/2, dragging.y - size/2, size, size);
      ctx.globalAlpha = 1;
    }
  }

  /* DRAG from palette */
  card.querySelectorAll('[data-mass]').forEach(btn => {
    btn.addEventListener('mousedown', e => {
      const mass = +btn.dataset.mass;
      const onMove = ev => {
        const p = getPos(ev);
        dragging = { mass, x: p.x, y: p.y };
        draw();
      };
      const onUp = ev => {
        document.removeEventListener('mousemove', onMove);
        document.removeEventListener('mouseup', onUp);
        const p = getPos(ev);
        if (p.y > beamY - 50 && p.y < beamY + 50 && p.x > supL - 20 && p.x < supR + 20){
          loads.push({ x: p.x, mass });
        }
        dragging = null;
        update();
      };
      document.addEventListener('mousemove', onMove);
      document.addEventListener('mouseup', onUp);
    });
  });

  /* Click on canvas to remove load */
  cv.addEventListener('click', e => {
    const p = getPos(e);
    for (let i = loads.length - 1; i >= 0; i--){
      if (Math.abs(loads[i].x - p.x) < 20 && p.y > beamY - 40 && p.y < beamY + 5){
        loads.splice(i, 1);
        update();
        return;
      }
    }
  });

  document.getElementById('F9-clear').addEventListener('click', () => { loads = []; update(); });
  document.getElementById('F9-test').addEventListener('click', () => {
    loads.push({ x: supL + beamLen/2, mass: 1000 });
    update();
  });

  update();
  draw();
  return true;
}

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

})();
