(function(){
  var rootId = 'virtualStudioModal';
  var mounted = false;
  var drag = null;
  var state = {
    projectId: '',
    selectedId: null,
    sources: [
      { id:'cam1', name:'Guest 1', color:'rgba(59,130,246,.18)' },
      { id:'cam2', name:'Guest 2', color:'rgba(16,185,129,.18)' },
      { id:'cam3', name:'Host', color:'rgba(245,158,11,.18)' },
      { id:'cam4', name:'Slides', color:'rgba(168,85,247,.18)' }
    ],
    boxes: [],
    saved: []
  };

  function storageKey(){ return 'cp_virtual_layout_' + (state.projectId || 'default'); }
  function body(){ return document.getElementById('virtualStudioBody'); }
  function stage(){ return document.getElementById('vsmStage'); }
  function status(){ return document.getElementById('vsmStatus'); }

  function defaults(){
    return [
      { id:'box1', sourceId:'cam3', name:'Host', x:5, y:5, w:58, h:90 },
      { id:'box2', sourceId:'cam1', name:'Guest 1', x:66, y:6, w:29, h:42 },
      { id:'box3', sourceId:'cam2', name:'Guest 2', x:66, y:52, w:29, h:42 }
    ];
  }

  function open(payload){
    payload = payload || {};
    state.projectId = payload.projectId || '';
    mount();
    load();
    render();
    FeatureModal.open(rootId);
  }
  function close(){ FeatureModal.close(rootId); }

  function mount(){
    if(mounted) return;
    mounted = true;
    render();
    bindStatic();
  }

  function bindStatic(){
    document.getElementById('vsmBtnPresetTwo')?.addEventListener('click', function(){ applyPreset('two-up'); });
    document.getElementById('vsmBtnPresetPip')?.addEventListener('click', function(){ applyPreset('pip'); });
    document.getElementById('vsmBtnSave')?.addEventListener('click', save);
    document.getElementById('vsmBtnReset')?.addEventListener('click', function(){ state.boxes = defaults(); state.selectedId = state.boxes[0]?.id || null; render(); });
  }

  function load(){
    try {
      var raw = localStorage.getItem(storageKey());
      if(raw){
        var parsed = JSON.parse(raw);
        if(Array.isArray(parsed.boxes)) state.boxes = parsed.boxes;
        if(Array.isArray(parsed.saved)) state.saved = parsed.saved;
      }
    } catch(_){ }
    if(!state.boxes.length) state.boxes = defaults();
    if(!state.selectedId && state.boxes[0]) state.selectedId = state.boxes[0].id;
  }

  function save(){
    try {
      localStorage.setItem(storageKey(), JSON.stringify({ boxes: state.boxes, saved: state.saved }));
      status() && (status().textContent = 'Layout saved locally for project ' + (state.projectId || 'default'));
    } catch(_){
      status() && (status().textContent = 'Save failed');
    }
  }

  function applyPreset(name){
    if(name === 'two-up'){
      state.boxes = [
        { id:'box1', sourceId:'cam1', name:'Guest 1', x:3, y:8, w:45, h:84 },
        { id:'box2', sourceId:'cam2', name:'Guest 2', x:52, y:8, w:45, h:84 }
      ];
    } else if(name === 'pip'){
      state.boxes = [
        { id:'box1', sourceId:'cam4', name:'Slides', x:3, y:5, w:94, h:90 },
        { id:'box2', sourceId:'cam3', name:'Host', x:68, y:62, w:26, h:28 }
      ];
    }
    state.selectedId = state.boxes[0]?.id || null;
    render();
  }

  function render(){
    if(!body()) return;
    var active = current();
    body().innerHTML = [
      '<div class="vsm-sidebar">',
        '<div class="vsm-layout-list">',
          '<div class="vsm-mini">Sources</div>',
          state.sources.map(function(s){ return '<div class="vsm-item" data-add-source="'+s.id+'"><b>'+esc(s.name)+'</b><div>'+esc(s.id)+'</div></div>'; }).join(''),
        '</div>',
      '</div>',
      '<div class="vsm-stage-wrap">',
        '<div class="vsm-stage" id="vsmStage">',
          '<div class="vsm-grid"></div>',
          state.boxes.map(boxHtml).join(''),
        '</div>',
      '</div>',
      '<div class="vsm-inspector"><div class="vsm-inspector-inner">',
        active ? (
          '<div class="vsm-field"><label>Label</label><input id="vsmName" value="'+escAttr(active.name || '')+'"></div>'+
          '<div class="vsm-field"><label>Source</label><select id="vsmSource">'+state.sources.map(function(s){ return '<option value="'+escAttr(s.id)+'" '+(s.id===active.sourceId?'selected':'')+'>'+esc(s.name)+'</option>'; }).join('')+'</select></div>'+
          '<div class="vsm-field"><label>X (%)</label><input id="vsmX" type="number" min="0" max="100" step="0.1" value="'+num(active.x)+'"></div>'+
          '<div class="vsm-field"><label>Y (%)</label><input id="vsmY" type="number" min="0" max="100" step="0.1" value="'+num(active.y)+'"></div>'+
          '<div class="vsm-field"><label>W (%)</label><input id="vsmW" type="number" min="1" max="100" step="0.1" value="'+num(active.w)+'"></div>'+
          '<div class="vsm-field"><label>H (%)</label><input id="vsmH" type="number" min="1" max="100" step="0.1" value="'+num(active.h)+'"></div>'+
          '<div style="display:flex;gap:8px"><button class="featureBtn" id="vsmDuplicate">Duplicate</button><button class="featureBtn" id="vsmDelete">Delete</button></div>'
        ) : '<div class="vsm-mini">Select a box on the stage to edit it.</div>',
      '</div></div>'
    ].join('');
    bindDynamic();
    status() && (status().textContent = 'Drag boxes on stage, resize from lower-right handle, save when ready');
  }

  function bindDynamic(){
    body().querySelectorAll('[data-add-source]').forEach(function(el){
      el.addEventListener('click', function(){ addBox(this.getAttribute('data-add-source')); });
    });
    body().querySelectorAll('.vsm-box').forEach(function(el){
      el.addEventListener('mousedown', onBoxMouseDown);
      el.addEventListener('click', function(ev){ ev.stopPropagation(); state.selectedId = this.getAttribute('data-box-id'); render(); });
    });
    stage()?.addEventListener('click', function(){ state.selectedId = null; render(); }, { once:true });
    hookInspector();
  }

  function hookInspector(){
    bindInput('vsmName', function(v){ var x=current(); if(x){ x.name = v; render(); } });
    bindInput('vsmSource', function(v){ var x=current(); if(x){ x.sourceId = v; render(); } }, 'change');
    bindNum('vsmX', 'x'); bindNum('vsmY', 'y'); bindNum('vsmW', 'w'); bindNum('vsmH', 'h');
    document.getElementById('vsmDuplicate')?.addEventListener('click', duplicateCurrent);
    document.getElementById('vsmDelete')?.addEventListener('click', deleteCurrent);
  }

  function bindInput(id, fn, evt){ var el=document.getElementById(id); if(el) el.addEventListener(evt||'input', function(){ fn(this.value); }); }
  function bindNum(id, key){ var el=document.getElementById(id); if(el) el.addEventListener('input', function(){ var x=current(); if(x){ x[key] = clamp(parseFloat(this.value)||0, key==='w'||key==='h'?1:0, 100); syncBox(x); renderStageOnly(); } }); }

  function boxHtml(b){
    var src = state.sources.find(function(s){ return s.id===b.sourceId; }) || { name:b.sourceId, color:'rgba(255,255,255,.08)' };
    return '<div class="vsm-box'+(b.id===state.selectedId?' active':'')+'" data-box-id="'+b.id+'" style="left:'+num(b.x)+'%;top:'+num(b.y)+'%;width:'+num(b.w)+'%;height:'+num(b.h)+'%;background:'+src.color+'">'+
      '<div class="vsm-box-label">'+esc(b.name || src.name)+'</div><div class="vsm-box-fill"></div><div class="vsm-handle" data-resize="1"></div></div>';
  }

  function renderStageOnly(){
    var s = stage(); if(!s) return;
    s.querySelectorAll('.vsm-box').forEach(function(n){ n.remove(); });
    s.insertAdjacentHTML('beforeend', state.boxes.map(boxHtml).join(''));
    s.querySelectorAll('.vsm-box').forEach(function(el){
      el.addEventListener('mousedown', onBoxMouseDown);
      el.addEventListener('click', function(ev){ ev.stopPropagation(); state.selectedId = this.getAttribute('data-box-id'); render(); });
    });
  }

  function addBox(sourceId){
    var src = state.sources.find(function(s){ return s.id===sourceId; }) || { name:sourceId };
    var id = 'box' + Math.random().toString(36).slice(2,8);
    state.boxes.push({ id:id, sourceId:sourceId, name:src.name, x:10, y:10, w:30, h:30 });
    state.selectedId = id;
    render();
  }
  function current(){ return state.boxes.find(function(b){ return b.id===state.selectedId; }) || null; }
  function duplicateCurrent(){ var x=current(); if(!x) return; var c=JSON.parse(JSON.stringify(x)); c.id='box'+Math.random().toString(36).slice(2,8); c.x=clamp(x.x+3,0,96); c.y=clamp(x.y+3,0,96); state.boxes.push(c); state.selectedId=c.id; render(); }
  function deleteCurrent(){ if(!state.selectedId) return; state.boxes = state.boxes.filter(function(b){ return b.id!==state.selectedId; }); state.selectedId = state.boxes[0]?.id || null; render(); }

  function onBoxMouseDown(ev){
    var boxEl = ev.currentTarget;
    var id = boxEl.getAttribute('data-box-id');
    state.selectedId = id;
    var b = current();
    if(!b) return;
    var st = stage(); if(!st) return;
    var rect = st.getBoundingClientRect();
    drag = {
      id:id,
      mode: ev.target && ev.target.hasAttribute('data-resize') ? 'resize' : 'move',
      startX: ev.clientX,
      startY: ev.clientY,
      box: { x:b.x, y:b.y, w:b.w, h:b.h },
      rect: rect
    };
    ev.preventDefault();
    renderStageOnly();
  }

  document.addEventListener('mousemove', function(ev){
    if(!drag) return;
    var b = state.boxes.find(function(x){ return x.id===drag.id; });
    if(!b) return;
    var dx = ((ev.clientX - drag.startX) / drag.rect.width) * 100;
    var dy = ((ev.clientY - drag.startY) / drag.rect.height) * 100;
    if(drag.mode === 'move'){
      b.x = clamp(drag.box.x + dx, 0, 100 - b.w);
      b.y = clamp(drag.box.y + dy, 0, 100 - b.h);
    } else {
      b.w = clamp(drag.box.w + dx, 4, 100 - b.x);
      b.h = clamp(drag.box.h + dy, 4, 100 - b.y);
    }
    renderStageOnly();
  });
  document.addEventListener('mouseup', function(){ if(drag){ drag=null; render(); } });

  function syncBox(b){ b.x=clamp(b.x,0,100-b.w); b.y=clamp(b.y,0,100-b.h); b.w=clamp(b.w,4,100-b.x); b.h=clamp(b.h,4,100-b.y); }
  function clamp(v,min,max){ return Math.max(min, Math.min(max, v)); }
  function num(v){ return (Math.round((parseFloat(v)||0)*10)/10).toString(); }
  function esc(v){ return String(v==null?'':v).replace(/[&<>"]/g, function(c){ return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'})[c]; }); }
  function escAttr(v){ return esc(v).replace(/'/g,'&#39;'); }

  window.VirtualStudio = { open: open, close: close, mount: mount, save: save, applyPreset: applyPreset };
})();
