function SectionsPanel({ offer, onChange, openCatalog }) {
  const existingKinds = new Set((offer.sections||[]).map(s => s.kind));
  const addSection = preset => {
    // Egna avsnitt (kind='custom') får alltid läggas till — annars hindra dubblett
    if (preset.id !== 'custom' && existingKinds.has(preset.id)) {
      alert(`Avsnittet "${preset.title}" finns redan i offerten. Bläddra ner för att redigera det.`);
      return;
    }
    if (preset.id === 'custom') {
      const title = prompt('Rubrik för det egna avsnittet:', 'Månadslicenser');
      if (!title) return;
      onChange({ sections: [...(offer.sections||[]), {
        id: crypto.randomUUID(), kind:'custom', title, body:'', isProductList:false
      }] });
      return;
    }
    // Smart placering: services direkt efter products, cost direkt efter services/products
    const newSec = makeSection(preset);
    const arr = [...(offer.sections||[])];
    const insertAfter = (kinds) => {
      for (let i = arr.length - 1; i >= 0; i--) {
        if (kinds.includes(arr[i].kind)) return i + 1;
      }
      return -1;
    };
    let pos = -1;
    if (preset.id === 'services') pos = insertAfter(['products']);
    else if (preset.id === 'cost') pos = insertAfter(['services','products']);
    else if (preset.id === 'finance') pos = insertAfter(['cost','services','products']);
    if (pos >= 0) arr.splice(pos, 0, newSec);
    else arr.push(newSec);
    onChange({ sections: arr });
  };
  const updateSection = (id, patch) => onChange({
    sections: offer.sections.map(s => s.id===id ? {...s, ...patch} : s)
  });
  const removeSection = id => onChange({ sections: offer.sections.filter(s => s.id!==id) });
  const move = (id, dir) => {
    const arr = [...offer.sections];
    const i = arr.findIndex(s => s.id===id);
    const j = i + dir;
    if (j<0 || j>=arr.length) return;
    [arr[i], arr[j]] = [arr[j], arr[i]];
    onChange({ sections: arr });
  };

  return (
    <section style={card}>
      <SectionHead eyebrow="Steg 2" title="Innehåll i offerten"
        right={
          <details style={{position:'relative'}}>
            <summary style={{...btn('secondary'), listStyle:'none'}}>
              <Icon name="plus" size={14}/> Lägg till avsnitt
            </summary>
            <div style={{
              position:'absolute', right:0, top:'calc(100% + 6px)', zIndex:50,
              background:'#fff', border:'1px solid var(--border)', borderRadius:6,
              boxShadow:'0 8px 24px rgba(0,54,95,.12)', padding:6, width:280,
              maxHeight:480, overflowY:'auto',
            }}>
              <button onClick={() => addSection({id:'custom', title:'Eget avsnitt', icon:'edit'})} style={{
                width:'100%', display:'flex', alignItems:'center', gap:10,
                padding:'10px 10px', background:'var(--ulab-cream)', border:'none',
                borderRadius:4, cursor:'pointer', textAlign:'left', marginBottom:6,
                fontFamily:'var(--font-sans)', fontSize:13, color:'var(--ulab-navy)', fontWeight:700,
              }}
              ><Icon name="plus" size={14} stroke="var(--ulab-coral)"/>Eget avsnitt med valfri rubrik…</button>
              <div style={{fontSize:10, fontWeight:600, letterSpacing:'.14em', textTransform:'uppercase', color:'var(--fg-muted)', padding:'4px 8px 4px'}}>Standardavsnitt</div>
              {SECTION_PRESETS.map(p => {
                const exists = existingKinds.has(p.id);
                return (
                <button key={p.id} onClick={() => addSection(p)} disabled={exists} style={{
                  width:'100%', display:'flex', alignItems:'center', gap:10,
                  padding:'8px 10px', background:'transparent', border:'none',
                  borderRadius:4, cursor: exists ? 'not-allowed' : 'pointer', textAlign:'left',
                  fontFamily:'var(--font-sans)', fontSize:13,
                  color: exists ? 'var(--fg-muted)' : 'var(--ulab-navy)',
                  opacity: exists ? 0.5 : 1,
                }}
                onMouseEnter={e => { if (!exists) e.currentTarget.style.background='var(--ulab-cream)'; }}
                onMouseLeave={e => e.currentTarget.style.background='transparent'}
                ><Icon name={p.icon} size={14} stroke="var(--ulab-blue)"/>{p.title}{exists && <span style={{marginLeft:'auto', fontSize:10, color:'var(--fg-muted)'}}>finns</span>}</button>
                );
              })}
            </div>
          </details>
        }/>

      {(!offer.sections || offer.sections.length===0) && (
        <div style={{padding:'18px 4px', color:'var(--fg-muted)', fontSize:14, textAlign:'center'}}>
          Lägg till t.ex. <i>Sammanfattning</i>, <i>Behov</i> och <i>Lösning</i> för att skriva en utförlig offert — eller hoppa direkt till produktraderna nedan.
        </div>
      )}

      <div style={{display:'flex', flexDirection:'column', gap:14}}>
        {(offer.sections||[]).map((s, i) => (
          <div key={s.id} style={{
            border:'1px solid var(--border)', borderRadius:6, padding:16, background:'#fff',
          }}>
            <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:10}}>
              <LocalInput value={s.title} onChange={v => updateSection(s.id, {title:v})} style={{
                ...inp, fontFamily:'var(--font-serif)', fontSize:18, fontWeight:500,
                border:'none', padding:'4px 0', background:'transparent',
              }}/>
              <div style={{display:'flex', gap:4, color:'var(--fg-muted)'}}>
                <button onClick={() => move(s.id, -1)} style={iconBtn} title="Flytta upp"><span style={{display:'inline-block', transform:'rotate(-90deg)'}}><Icon name="chevron" size={14} sw={2}/></span></button>
                <button onClick={() => move(s.id, 1)}  style={iconBtn} title="Flytta ned"><span style={{display:'inline-block', transform:'rotate(90deg)'}}><Icon name="chevron" size={14} sw={2}/></span></button>
                <button onClick={() => removeSection(s.id)} style={iconBtn} title="Ta bort"><Icon name="trash" size={14}/></button>
              </div>
            </div>
            {s.isProductList ? (
              <ProductLines offer={offer} onChange={onChange} openCatalog={openCatalog}/>
            ) : s.isServiceList ? (
              <ServiceLines offer={offer} onChange={onChange}/>
            ) : (
              <LocalTextarea value={s.body} onChange={v => updateSection(s.id, {body:v})}
                rows={Math.max(4, (s.body||'').split('\n').length+1)}
                placeholder={SECTION_PRESETS.find(p=>p.id===s.kind)?.placeholder || 'Skriv innehåll...'}
                style={{...inp, resize:'vertical', fontFamily:'var(--font-sans)', lineHeight:1.55}}/>
            )}
          </div>
        ))}
      </div>
    </section>
  );
}
const iconBtn = {
  background:'transparent', border:'1px solid var(--border)', borderRadius:4,
  padding:'4px 6px', cursor:'pointer', color:'var(--ulab-navy)',
};
window.SectionsPanel = SectionsPanel;

// (Förenklad) produktradslista som återanvänds inne i ett "Produkter"-avsnitt
function ProductLines({ offer, onChange, openCatalog }) {
  const update = (id, patch) => onChange({ lines: offer.lines.map(l => l.id===id ? {...l, ...patch} : l) });
  const remove = (id) => onChange({ lines: offer.lines.filter(l => l.id!==id) });
  const addBlank = () => {
    // Använd senaste kategorin om det finns rader, annars första katalog‑gruppen
    const lastCat = offer.lines.length > 0 ? offer.lines[offer.lines.length-1].cat : (CATALOG[0]?.cat || 'Tjänster');
    onChange({ lines: [...offer.lines, { id: crypto.randomUUID(), name:'', unit:'st', qty:1, price:0, cat:lastCat, desc:'' }]});
  };
  // Stabil ordning av kategorier (förstadykningsordning) — så grupperna inte hoppar runt vid rerender
  const catOrder = [];
  const groups = {};
  for (const l of offer.lines) {
    const c = l.cat || 'Övrigt';
    if (!(c in groups)) { groups[c] = []; catOrder.push(c); }
    groups[c].push(l);
  }

  // Hantera kategori‑byte per rad — uppdaterar bara den raden, inte alla i gruppen
  const renameLineCat = (id, newCat) => {
    onChange({ lines: offer.lines.map(l => l.id===id ? {...l, cat:newCat} : l) });
  };

  return (
    <div>
      <div style={{display:'flex', gap:8, marginBottom:10}}>
        <button onClick={openCatalog} style={btn('secondary')}><Icon name="plus" size={14}/> Från katalog</button>
        <button onClick={addBlank} style={btn('ghost')}><Icon name="edit" size={14}/> Egen rad</button>
      </div>
      {offer.lines.length===0 && (
        <div style={{padding:'14px 4px', fontSize:13, color:'var(--fg-muted)', textAlign:'center'}}>Inga rader — lägg till från katalog eller skapa egna.</div>
      )}
      {offer.lines.length>0 && (
        <div style={{display:'grid', gridTemplateColumns:'1fr 110px 70px 90px 100px 110px 32px', gap:8, padding:'10px 0 4px', borderTop:'1px solid var(--border)', fontSize:11, fontWeight:600, letterSpacing:'.14em', textTransform:'uppercase', color:'var(--ulab-blue)'}}>
          <span>Namn / beskrivning</span><span>Kategori</span><span style={{textAlign:'right'}}>Antal</span><span>Enhet</span><span style={{textAlign:'right'}}>À‑pris</span><span style={{textAlign:'right'}}>Summa</span><span></span>
        </div>
      )}
      {offer.lines.map(l => (
        <div key={l.id} style={{display:'grid', gridTemplateColumns:'1fr 110px 70px 90px 100px 110px 32px', gap:8, padding:'6px 0', alignItems:'flex-start', borderTop:'1px solid #f0ece2'}}>
          <div>
            <LocalInput value={l.name} onChange={v => update(l.id, {name:v})} style={cellInp} placeholder="Namn"/>
            <LocalInput value={l.desc||''} onChange={v => update(l.id, {desc:v})} style={{...cellInp, marginTop:4, fontSize:12, color:'var(--fg-muted)'}} placeholder="Beskrivning"/>
          </div>
          <LocalInput value={l.cat||''} onChange={v => renameLineCat(l.id, v)} style={{...cellInp, fontSize:12}} placeholder="Kategori"/>
          <input type="number" value={l.qty} onChange={e => update(l.id, {qty:+e.target.value||0})} style={{...cellInp, textAlign:'right'}}/>
          <LocalInput value={l.unit} onChange={v => update(l.id, {unit:v})} style={cellInp}/>
          <input type="number" value={l.price} onChange={e => update(l.id, {price:+e.target.value||0})} style={{...cellInp, textAlign:'right'}}/>
          <div style={{textAlign:'right', fontVariantNumeric:'tabular-nums', fontWeight:600, color:'var(--ulab-navy)', alignSelf:'center'}}>{fmtKr(l.qty*l.price)}</div>
          <button onClick={() => remove(l.id)} style={{background:'transparent', border:'none', cursor:'pointer', color:'var(--fg-muted)', alignSelf:'center'}}><Icon name="trash" size={16}/></button>
        </div>
      ))}
    </div>
  );
}
const cellInp = {
  fontFamily:'var(--font-sans)', fontSize:14, padding:'8px 10px',
  border:'1px solid var(--border)', borderRadius:4, background:'#fff',
  color:'var(--ulab-navy)', width:'100%', fontVariantNumeric:'tabular-nums',
};
window.ProductLines = ProductLines;

// Tjänster / månadskostnader — separat från produktrader
function ServiceLines({ offer, onChange }) {
  const services = offer.services || [];
  const update = (id, patch) => onChange({ services: services.map(l => l.id===id ? {...l, ...patch} : l) });
  const remove = (id) => onChange({ services: services.filter(l => l.id!==id) });
  const addBlank = () => onChange({ services: [...services, { id: crypto.randomUUID(), name:'', unit:'månad', qty:1, price:0, desc:'' }]});

  return (
    <div>
      <div style={{display:'flex', gap:8, marginBottom:10}}>
        <button onClick={addBlank} style={btn('secondary')}><Icon name="plus" size={14}/> Lägg till tjänst</button>
        <span style={{alignSelf:'center', fontSize:12, color:'var(--fg-muted)'}}>Återkommande månadskostnader visas separat i offerten.</span>
      </div>
      {services.length===0 && (
        <div style={{padding:'14px 4px', fontSize:13, color:'var(--fg-muted)', textAlign:'center'}}>Inga tjänster — lägg till t.ex. drift, supportavtal, M365‑licenser.</div>
      )}
      {services.length>0 && (
        <div style={{display:'grid', gridTemplateColumns:'1fr 70px 100px 110px 110px 32px', gap:8, padding:'10px 0 4px', borderTop:'1px solid var(--border)', fontSize:11, fontWeight:600, letterSpacing:'.14em', textTransform:'uppercase', color:'var(--ulab-blue)'}}>
          <span>Namn / beskrivning</span><span style={{textAlign:'right'}}>Antal</span><span>Period</span><span style={{textAlign:'right'}}>À‑pris/period</span><span style={{textAlign:'right'}}>Summa/period</span><span></span>
        </div>
      )}
      {services.map(l => (
        <div key={l.id} style={{display:'grid', gridTemplateColumns:'1fr 70px 100px 110px 110px 32px', gap:8, padding:'6px 0', alignItems:'flex-start', borderTop:'1px solid #f0ece2'}}>
          <div>
            <LocalInput value={l.name} onChange={v => update(l.id, {name:v})} style={cellInp} placeholder="Namn på tjänst"/>
            <LocalInput value={l.desc||''} onChange={v => update(l.id, {desc:v})} style={{...cellInp, marginTop:4, fontSize:12, color:'var(--fg-muted)'}} placeholder="Beskrivning"/>
          </div>
          <input type="number" value={l.qty} onChange={e => update(l.id, {qty:+e.target.value||0})} style={{...cellInp, textAlign:'right'}}/>
          <LocalInput value={l.unit} onChange={v => update(l.id, {unit:v})} style={cellInp} placeholder="månad / år"/>
          <input type="number" value={l.price} onChange={e => update(l.id, {price:+e.target.value||0})} style={{...cellInp, textAlign:'right'}}/>
          <div style={{textAlign:'right', fontVariantNumeric:'tabular-nums', fontWeight:600, color:'var(--ulab-navy)', alignSelf:'center'}}>{fmtKr(l.qty*l.price)}</div>
          <button onClick={() => remove(l.id)} style={{background:'transparent', border:'none', cursor:'pointer', color:'var(--fg-muted)', alignSelf:'center'}}><Icon name="trash" size={16}/></button>
        </div>
      ))}
    </div>
  );
}
window.ServiceLines = ServiceLines;

// Behåll TotalsPanel
function TotalsPanel({ offer, onChange }) {
  const sub = offer.lines.reduce((s,l) => s + l.qty*l.price, 0);
  const disc = sub * (offer.discount || 0) / 100;
  const net = sub - disc;
  const vat = net * 0.25;
  const total = net + vat;
  const services = offer.services || [];
  const monthlyServiceTotal = services.reduce((s,l) => s + (l.qty||0)*(l.price||0), 0);
  return (
    <section style={card}>
      <SectionHead eyebrow="Steg 3" title="Pris & villkor"/>
      <div style={{display:'grid', gridTemplateColumns:'1fr 320px', gap:32}}>
        <div>
          <label style={{fontSize:12, fontWeight:600, color:'var(--ulab-navy)', display:'block', marginBottom:6}}>Pris‑modell</label>
          <select value={offer.pricingMode||'kontant'} onChange={e => onChange({pricingMode:e.target.value})} style={{...inp, maxWidth:240}}>
            <option value="kontant">Kontant (engångsköp)</option>
            <option value="hyra">Finansierat (hyra/månad)</option>
            <option value="bada">Visa båda alternativen</option>
          </select>
          {(offer.pricingMode==='hyra' || offer.pricingMode==='bada') && (
            <div style={{display:'flex', gap:10, marginTop:10}}>
              <div><label style={{fontSize:12, fontWeight:600, color:'var(--ulab-navy)', display:'block', marginBottom:6}}>Avtalstid (mån)</label><input type="number" value={offer.term||48} onChange={e=>onChange({term:+e.target.value})} style={{...inp, maxWidth:120}}/></div>
              <div><label style={{fontSize:12, fontWeight:600, color:'var(--ulab-navy)', display:'block', marginBottom:6}}>Restvärde %</label><input type="number" value={offer.residual||10} onChange={e=>onChange({residual:+e.target.value})} style={{...inp, maxWidth:120}}/></div>
              <div><label style={{fontSize:12, fontWeight:600, color:'var(--ulab-navy)', display:'block', marginBottom:6}}>Finansiär</label><input value={offer.financier||'De Lage Landen'} onChange={e=>onChange({financier:e.target.value})} style={{...inp, maxWidth:160}}/></div>
            </div>
          )}
          <label style={{fontSize:12, fontWeight:600, color:'var(--ulab-navy)', display:'block', margin:'14px 0 6px'}}>Rabatt (%)</label>
          <input type="number" value={offer.discount||0} onChange={e => onChange({discount:+e.target.value||0})} style={{...inp, maxWidth:120}}/>
        </div>
        <div style={{background:'var(--ulab-cream)', borderRadius:6, padding:20, fontVariantNumeric:'tabular-nums'}}>
          <Row label="Summa" v={fmtKr(sub)}/>
          {disc>0 && <Row label={`Rabatt ${offer.discount}%`} v={'– '+fmtKr(disc)}/>}
          <Row label="Netto" v={fmtKr(net)}/>
          <Row label="Moms 25%" v={fmtKr(vat)}/>
          <div style={{height:1, background:'var(--border-strong)', margin:'10px 0'}}/>
          <Row big label="Att betala" v={fmtKr(total)}/>
          {offer.pricingMode==='hyra' && offer.term>0 && (
            <div style={{marginTop:10, fontSize:13, color:'var(--ulab-navy)'}}>≈ <b>{fmtKr(net/offer.term)}</b> / mån i {offer.term} mån</div>
          )}
          {offer.pricingMode==='bada' && offer.term>0 && (
            <div style={{marginTop:10, fontSize:13, color:'var(--ulab-navy)'}}>Kontant: <b>{fmtKr(total)}</b><br/>eller hyra: <b>{fmtKr(net/offer.term)}</b>/mån i {offer.term} mån</div>
          )}
          {services.length>0 && (
            <div style={{marginTop:14, paddingTop:12, borderTop:'1px dashed var(--border-strong)'}}>
              <div style={{fontSize:10, fontWeight:600, letterSpacing:'.18em', textTransform:'uppercase', color:'var(--ulab-coral)', marginBottom:6}}>Månadskostnader</div>
              {services.map(l => (
                <div key={l.id} style={{display:'flex', justifyContent:'space-between', fontSize:13, color:'var(--ulab-navy)', padding:'2px 0'}}>
                  <span>{l.name || '—'}{l.qty>1 && <span style={{color:'var(--fg-muted)'}}> × {l.qty}</span>}</span>
                  <span>{fmtKr((l.qty||0)*(l.price||0))}/{l.unit||'mån'}</span>
                </div>
              ))}
              <div style={{height:1, background:'var(--border-strong)', margin:'6px 0'}}/>
              <Row big label="Per månad" v={fmtKr(monthlyServiceTotal)}/>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}
function Row({label, v, big}) {
  return (
    <div style={{display:'flex', justifyContent:'space-between', padding:'4px 0', fontSize: big?16:14, fontWeight: big?700:500, color:'var(--ulab-navy)'}}>
      <span>{label}</span><span>{v}</span>
    </div>
  );
}
window.TotalsPanel = TotalsPanel;
