/* ============================================================
   ADMIN — Listino batterie nuove + Zone di consegna + Listino STR
   Versione con persistenza completa Supabase
   ============================================================ */

/* ---- Listino batterie: matrice voltaggio × amperaggio ----- */
function AdminListino({ listino, setListino, toast }) {
  const vp = useViewport();
  const [edit, setEdit] = useState(null);
  const inputRef = useRef(null);
  // Eseguo focus+select SOLO quando si apre una cella nuova (cambia key),
  // non ad ogni keystroke (che alterava edit e rifocava resettando la posizione del cursore)
  useEffect(()=>{
    if(edit && inputRef.current){
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [edit?.key]);

  const usedAmps = BATT_AMP.filter(a => BATT_VOLT.some(v => (battKey(v,a) in listino)));

  // Persistenza su battery_prices: upsert se valore, delete se rimosso
  const persistCell = async (voltaggio, amperaggio, newVal) => {
    if (!window.SF_CONFIG.useSupabase) return;
    const sb = window.DataAPI.client();
    if (!sb) return;
    try {
      if (newVal == null) {
        // Rimosso → delete
        const { error } = await sb.from('battery_prices')
          .delete()
          .match({ voltaggio, amperaggio });
        if (error) throw error;
      } else if (newVal === SR) {
        const { error } = await sb.from('battery_prices')
          .upsert({ voltaggio, amperaggio, prezzo: null, su_richiesta: true },
                  { onConflict: 'voltaggio,amperaggio' });
        if (error) throw error;
      } else {
        const { error } = await sb.from('battery_prices')
          .upsert({ voltaggio, amperaggio, prezzo: newVal, su_richiesta: false },
                  { onConflict: 'voltaggio,amperaggio' });
        if (error) throw error;
      }
    } catch (e) {
      console.error('persist battery cell', e);
      toast('Errore salvataggio: ' + (e?.message || 'sconosciuto'));
    }
  };

  const commit = async () => {
    if (!edit) return;
    const raw = edit.val.trim();
    const [v, a] = edit.key.split('|');
    let newVal;
    if (raw === '') newVal = null;
    else if (/^sr$|^su richiesta$/i.test(raw)) newVal = SR;
    else {
      const num = parseFloat(raw.replace(/[^\d.,]/g,'').replace(',','.'));
      newVal = isNaN(num) ? null : num;
    }

    setListino(prev => {
      const n = { ...prev };
      if (newVal == null) delete n[edit.key];
      else n[edit.key] = newVal;
      return n;
    });
    setEdit(null);
    await persistCell(v, a, newVal);
    toast('Listino aggiornato');
  };

  const cellVal = (v,a) => listino[battKey(v,a)];

  return (
    <>
      <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', marginBottom:14, gap:12, flexWrap:'wrap' }}>
        <div style={{ minWidth:0, flex:1 }}>
          <h2 style={{ margin:0, fontFamily:'var(--font-display)', fontSize: vp.isMobile?17:19, fontWeight:800 }}>Listino batterie nuove</h2>
          <div style={{ fontSize:12.5, color:'var(--ink-3)', marginTop:2 }}>
            {vp.isMobile ? 'Righe = V · colonne = Ah · tap una cella per il prezzo' : 'Righe = voltaggio · colonne = amperaggio · clicca una cella per impostare il prezzo. La simulazione batteria del prodotto legge da qui.'}
          </div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:9, fontSize:12, color:'var(--ink-3)', fontWeight:600, background:'var(--surface-2)', border:'1px solid var(--line)', padding:'7px 12px', borderRadius:99 }}>
          <span style={{ display:'inline-flex', alignItems:'center', gap:6 }}><span style={{ width:12, height:12, borderRadius:3, background:'var(--red-tint)', border:'1px solid var(--red-tint-2)' }} /> SR = su richiesta</span>
        </div>
      </div>

      <div style={{ background:'var(--surface)', border:'1px solid var(--line)', borderRadius:'var(--r-lg)', overflow:'hidden', boxShadow:'var(--sh-1)' }}>
        <div className="scroll" style={{ overflowX:'auto' }}>
          <table style={{ borderCollapse:'separate', borderSpacing:0, minWidth:'max-content', width:'100%' }}>
            <thead>
              <tr>
                <th style={{ position:'sticky', left:0, zIndex:2, background:'var(--surface-2)', padding:'12px 14px', textAlign:'left',
                  fontSize:11, fontWeight:800, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.04em', borderBottom:'1px solid var(--line)', borderRight:'1px solid var(--line)', minWidth:96 }}>
                  V / Ah
                </th>
                {usedAmps.map(a => (
                  <th key={a} style={{ padding:'12px 10px', fontSize:12, fontWeight:800, color:'var(--ink-2)', background:'var(--surface-2)', borderBottom:'1px solid var(--line)', whiteSpace:'nowrap', minWidth:78 }}>
                    {a}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {BATT_VOLT.map(v => (
                <tr key={v}>
                  <th style={{ position:'sticky', left:0, zIndex:1, background:'var(--surface)', padding:'10px 14px', textAlign:'left',
                    fontSize:13.5, fontWeight:800, color:'var(--red)', borderBottom:'1px solid var(--line-2)', borderRight:'1px solid var(--line)', whiteSpace:'nowrap' }}>
                    {v}
                  </th>
                  {usedAmps.map(a => {
                    const key = battKey(v,a);
                    const val = cellVal(v,a);
                    const isEditing = edit && edit.key===key;
                    const has = val!=null;
                    const isSR = val===SR;
                    return (
                      <td key={a} onClick={()=>!isEditing && setEdit({ key, val: isSR?'SR':(has?String(val):'') })}
                        style={{ padding:0, borderBottom:'1px solid var(--line-2)', borderLeft:'1px solid var(--line-2)', cursor:'pointer',
                          background: isSR?'var(--red-tint)':'transparent', textAlign:'center' }}>
                        {isEditing ? (
                          <input ref={inputRef} value={edit.val} onChange={e=>setEdit({...edit, val:e.target.value})}
                            onBlur={commit} onKeyDown={e=>{ if(e.key==='Enter') commit(); if(e.key==='Escape') setEdit(null); }}
                            style={{ width:74, padding:'9px 6px', border:'2px solid var(--red)', borderRadius:6, textAlign:'center', fontSize:13, fontWeight:700, outline:'none', background:'var(--surface)', color:'var(--ink)' }} />
                        ) : (
                          <div style={{ padding:'10px 8px', fontSize:13, fontWeight: has?700:400, color: isSR?'var(--red)':(has?'var(--ink)':'var(--ink-4)') }}
                            title="Clicca per modificare">
                            {isSR ? 'SR' : (has ? val.toLocaleString('it-IT') : '·')}
                          </div>
                        )}
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      <div style={{ marginTop:14, fontSize:12.5, color:'var(--ink-4)', display:'flex', alignItems:'center', gap:8 }}>
        <Icon name="battery" size={15} /> Prezzi in € IVA esclusa. Lascia vuota una cella e premi Invio per rimuovere il valore; scrivi "SR" per "su richiesta".
      </div>
    </>
  );
}

/* ---- Zone di consegna: CRUD ------------------------------- */
function AdminZone({ zone, setZone, toast }) {
  const vp = useViewport();
  const [hover, setHover] = useState(null);
  const [editing, setEditing] = useState(undefined);
  const [confirm, setConfirm] = useState(null);
  const [q, setQ] = useState('');

  const list = q ? zone.filter(z=>z.nome.toLowerCase().includes(q.toLowerCase())) : zone;

  const save = async (z) => {
    const isNew = !zone.some(x => x.id === z.id);
    const dbRow = {
      nome: z.nome,
      km: z.km ?? null,
      tariffa: z.tariffa === SR ? null : z.tariffa,
      su_richiesta: z.tariffa === SR,
    };

    if (window.SF_CONFIG.useSupabase) {
      try {
        if (isNew) {
          const row = await window.DataAPI.insert('delivery_zones', dbRow);
          z = { ...z, id: row.id };
        } else {
          await window.DataAPI.update('delivery_zones', z.id, dbRow);
        }
      } catch (e) {
        console.error('save zona', e);
        toast('Errore salvataggio: ' + (e?.message || 'sconosciuto'));
        return;
      }
    }

    setZone(prev => {
      const exists = prev.some(x=>x.id===z.id);
      const next = exists ? prev.map(x=>x.id===z.id?z:x) : [...prev, z];
      return next.sort((a,b)=>((a.tariffa??Infinity)-(b.tariffa??Infinity))||a.nome.localeCompare(b.nome));
    });
    setEditing(undefined);
    toast(isNew ? 'Zona aggiunta' : 'Zona aggiornata');
  };

  const remove = async (z) => {
    if (window.SF_CONFIG.useSupabase) {
      try {
        await window.DataAPI.remove('delivery_zones', z.id);
      } catch (e) {
        console.error('remove zona', e);
        toast('Errore eliminazione: ' + (e?.message || 'sconosciuto'));
        return;
      }
    }
    setZone(prev=>prev.filter(x=>x.id!==z.id));
    setConfirm(null);
    toast(`Zona "${z.nome}" eliminata`);
  };

  return (
    <>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:14, gap:12, flexWrap:'wrap' }}>
        <div style={{ minWidth:0, flex:1 }}>
          <h2 style={{ margin:0, fontFamily:'var(--font-display)', fontSize: vp.isMobile?17:19, fontWeight:800 }}>Zone di consegna</h2>
          <div style={{ fontSize: vp.isMobile?12.5:13, color:'var(--ink-3)', marginTop:2 }}>{zone.length} zone{!vp.isMobile && ' · nome e tariffa di trasporto'}</div>
        </div>
        <div style={{ display:'flex', gap:8, width: vp.isMobile?'100%':'auto' }}>
          <div style={{ position:'relative', flex: vp.isMobile?1:'none' }}>
            <Icon name="search" size={17} style={{ position:'absolute', left:12, top:'50%', transform:'translateY(-50%)', color:'var(--ink-4)' }} />
            <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Cerca…"
              style={{ width: vp.isMobile?'100%':210, padding:'9px 12px 9px 36px', fontSize:13.5, borderRadius:'var(--r-md)', border:'1.5px solid var(--line)', background:'var(--surface-2)', outline:'none' }} />
          </div>
          <Btn icon="plus" size={vp.isMobile?'sm':'md'} onClick={()=>setEditing(null)}>{vp.isMobile?'Nuova':'Nuova zona'}</Btn>
        </div>
      </div>

      {vp.isMobile ? (
        /* MOBILE: card list, tap = edit */
        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
          {list.length===0 && <div style={{ padding:'40px 0', textAlign:'center', color:'var(--ink-3)', fontWeight:600 }}>Nessuna zona</div>}
          {list.map(z => (
            <div key={z.id} onClick={()=>setEditing(z)}
              style={{ background:'var(--surface)', border:'1px solid var(--line)', borderRadius:'var(--r-lg)',
                padding:'12px 14px', boxShadow:'var(--sh-1)', cursor:'pointer',
                display:'flex', alignItems:'center', gap:12 }}>
              <span style={{ width:34, height:34, borderRadius:8, flexShrink:0, background:'var(--red-tint)', color:'var(--red)', display:'flex', alignItems:'center', justifyContent:'center' }}>
                <Icon name="pin" size={17} />
              </span>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:14, fontWeight:800, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{z.nome}</div>
                <div style={{ fontSize:12, color:'var(--ink-3)', marginTop:2 }}>{z.km!=null?z.km+' km':'—'}</div>
              </div>
              <div style={{ fontFamily:'var(--font-display)', fontSize:15, fontWeight:800, color: z.tariffa===SR?'var(--ink-4)':'var(--ink)', textAlign:'right', flexShrink:0 }}>
                {z.tariffa===SR?'SR':(z.tariffa!=null?fmtEur(z.tariffa):'—')}
              </div>
            </div>
          ))}
          <button onClick={()=>setEditing(null)}
            style={{ padding:'12px', color:'var(--red)', fontSize:13, fontWeight:700, background:'var(--red-tint)',
              border:'1.5px dashed var(--red-tint-2)', borderRadius:'var(--r-lg)',
              display:'flex', alignItems:'center', justifyContent:'center', gap:8 }}>
            <Icon name="plus" size={16} /> Aggiungi zona
          </button>
        </div>
      ) : (
      <div style={{ background:'var(--surface)', border:'1px solid var(--line)', borderRadius:'var(--r-lg)', overflow:'hidden', boxShadow:'var(--sh-1)' }}>
        <div style={{ display:'grid', gridTemplateColumns:'minmax(0,2fr) minmax(0,1fr) minmax(0,1.1fr) 86px', gap:14, padding:'13px 20px', background:'var(--surface-2)',
          borderBottom:'1px solid var(--line)', fontSize:11, fontWeight:800, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.04em' }}>
          <span>Zona</span><span>Distanza</span><span>Tariffa trasporto</span><span style={{ textAlign:'right' }}>Azioni</span>
        </div>
        <div className="scroll" style={{ maxHeight:'calc(100vh - 320px)', overflowY:'auto' }}>
          {list.length===0 && <div style={{ padding:'50px 0', textAlign:'center', color:'var(--ink-3)', fontWeight:600 }}>Nessuna zona</div>}
          {list.map((z,i) => (
            <div key={z.id} onMouseEnter={()=>setHover(z.id)} onMouseLeave={()=>setHover(null)}
              style={{ display:'grid', gridTemplateColumns:'minmax(0,2fr) minmax(0,1fr) minmax(0,1.1fr) 86px', gap:14, padding:'12px 20px', alignItems:'center',
                borderBottom: i<list.length-1?'1px solid var(--line-2)':'none', background: hover===z.id?'var(--surface-2)':'transparent' }}>
              <div style={{ display:'flex', alignItems:'center', gap:10, minWidth:0 }}>
                <span style={{ width:30, height:30, borderRadius:8, flexShrink:0, background:'var(--red-tint)', color:'var(--red)', display:'flex', alignItems:'center', justifyContent:'center' }}>
                  <Icon name="pin" size={16} />
                </span>
                <span style={{ fontSize:14, fontWeight:700, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{z.nome}</span>
              </div>
              <span style={{ fontSize:13, color:'var(--ink-2)', fontWeight:600 }}>{z.km!=null?z.km+' km':'—'}</span>
              <span style={{ fontFamily:'var(--font-display)', fontSize:16, fontWeight:800, color: z.tariffa===SR?'var(--ink-4)':'var(--ink)' }}>{z.tariffa===SR?'Su richiesta':(z.tariffa!=null?fmtEur(z.tariffa):'—')}</span>
              <div style={{ display:'flex', gap:6, justifySelf:'end', opacity: hover===z.id?1:0, transition:'opacity .12s' }}>
                <button onClick={()=>setEditing(z)} title="Modifica" style={iconBtn}><Icon name="edit" size={15} /></button>
                <button onClick={()=>setConfirm(z)} title="Elimina" style={{ ...iconBtn, color:'var(--red)', borderColor:'var(--red-tint-2)' }}><Icon name="x" size={15} /></button>
              </div>
            </div>
          ))}
          <button onClick={()=>setEditing(null)} style={{ width:'100%', display:'flex', alignItems:'center', gap:10, padding:'14px 20px',
            color:'var(--ink-3)', fontSize:13.5, fontWeight:700, borderTop:'1px dashed var(--line)', background:'var(--surface-2)' }}
            onMouseEnter={e=>e.currentTarget.style.color='var(--red)'} onMouseLeave={e=>e.currentTarget.style.color='var(--ink-3)'}>
            <Icon name="plus" size={17} /> Aggiungi zona
          </button>
        </div>
      </div>
      )}

      {editing!==undefined && <ZoneEditModal zona={editing} onClose={()=>setEditing(undefined)} onSave={save} />}
      {confirm && <ConfirmDialog title="Eliminare la zona?"
        message={<>Stai per eliminare la zona <b>{confirm.nome}</b>. Non sarà più selezionabile nelle prenotazioni.</>}
        confirmLabel="Elimina zona" onConfirm={()=>remove(confirm)} onClose={()=>setConfirm(null)} />}
    </>
  );
}

function ZoneEditModal({ zona, onClose, onSave }) {
  const isNew = zona===null;
  const [nome, setNome] = useState(zona?.nome || '');
  const [km, setKm] = useState(zona?.km!=null?String(zona.km):'');
  const [tariffa, setTariffa] = useState(zona?.tariffa===SR?'SR':(zona?.tariffa!=null?String(zona.tariffa):''));
  const submit = () => {
    if(!nome.trim() || tariffa==='') return;
    const t = tariffa.trim();
    const isSr = /^sr$|^su richiesta$/i.test(t);
    onSave({
      id: zona?.id,
      nome:nome.trim(),
      km: km===''?null:parseInt(km),
      tariffa: isSr ? SR : parseFloat(t.replace(',','.')),
    });
  };
  return (
    <ModalShell onClose={onClose} width={460} title={isNew?'Nuova zona di consegna':'Modifica zona'} subtitle={isNew?'Nome zona e tariffa di trasporto':zona.nome}>
      <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
        <Field label="Nome zona" required>
          <input value={nome} onChange={e=>setNome(e.target.value)} placeholder="es. Modena" style={inputStyle} autoFocus />
        </Field>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1.3fr', gap:14 }}>
          <Field label="Distanza (km)">
            <input value={km} onChange={e=>setKm(e.target.value.replace(/[^\d]/g,''))} placeholder="opz." style={inputStyle} />
          </Field>
          <Field label="Tariffa trasporto (€)" required>
            <input value={tariffa} onChange={e=>setTariffa(e.target.value)} placeholder="es. 220 oppure SR" style={inputStyle} />
          </Field>
        </div>
      </div>
      <div style={{ display:'flex', gap:12, marginTop:22 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={submit} disabled={!nome.trim()||tariffa===''}>{isNew?'Crea zona':'Salva'}</Btn>
      </div>
    </ModalShell>
  );
}

Object.assign(window, { AdminListino, AdminZone, ZoneEditModal });

/* ============================================================
   LISTINO STR — modale + admin editabile con persistenza
   ============================================================ */
function strPrice(v){ return v===SR ? 'Su richiesta' : (v!=null ? fmtEur(v) : '—'); }

function StrListinoModal({ listino, onClose }) {
  const rows = listino || LISTINO_STR_INIT;
  return (
    <ModalShell onClose={onClose} width={620} title="Listino STR — Noleggio breve termine"
      subtitle="Tariffe indicative · giornaliero (min. 3 giorni) e mensile">
      <div style={{ border:'1px solid var(--line)', borderRadius:'var(--r-md)', overflow:'hidden' }}>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 130px 130px', gap:0, padding:'10px 16px', background:'var(--surface-2)', borderBottom:'1px solid var(--line)',
          fontSize:11, fontWeight:800, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.04em' }}>
          <span>Tipologia</span><span style={{ textAlign:'right' }}>€ / giorno</span><span style={{ textAlign:'right' }}>€ / mese</span>
        </div>
        {rows.map(r => r.tipo==='gruppo' ? (
          <div key={r.id} style={{ padding:'10px 16px 6px', fontSize:11.5, fontWeight:800, color:'var(--red)', textTransform:'uppercase', letterSpacing:'.05em', background:'var(--red-tint)' }}>{r.nome}</div>
        ) : (
          <div key={r.id} style={{ display:'grid', gridTemplateColumns:'1fr 130px 130px', gap:0, padding:'10px 16px', borderBottom:'1px solid var(--line-2)', alignItems:'center', fontSize:13.5 }}>
            <span style={{ fontWeight:600 }}>{r.nome}</span>
            <span style={{ textAlign:'right', fontWeight:700, color: r.giorno===SR?'var(--ink-4)':'var(--ink)' }}>{strPrice(r.giorno)}</span>
            <span style={{ textAlign:'right', fontWeight:700, color: r.mese===SR?'var(--ink-4)':'var(--ink)' }}>{strPrice(r.mese)}</span>
          </div>
        ))}
      </div>
      <div style={{ marginTop:14, fontSize:12, color:'var(--ink-4)', display:'flex', alignItems:'center', gap:8 }}>
        <Icon name="clock" size={14} /> Prezzi € IVA esclusa. Noleggio minimo 3 giorni. Trasporto e accessori a parte.
      </div>
    </ModalShell>
  );
}

// Ricarica TUTTO il listino STR da Supabase (groups + prices) dopo modifica
async function reloadStr() {
  if (!window.SF_CONFIG.useSupabase) return null;
  const sb = window.DataAPI;
  const [groups, prices] = await Promise.all([
    sb.list('str_groups'),
    sb.list('str_prices'),
  ]);
  const merged = [];
  (groups || []).sort((a,b) => (a.ordine||0) - (b.ordine||0)).forEach(g => {
    merged.push({ id: g.id, tipo: 'gruppo', nome: g.nome });
    (prices || []).filter(p => p.group_id === g.id).sort((a,b) => (a.ordine||0) - (b.ordine||0))
      .forEach(p => merged.push({
        id: p.id, nome: p.nome,
        giorno: p.giorno_sr ? SR : p.giorno,
        mese: p.mese_sr ? SR : p.mese,
      }));
  });
  return merged;
}

function AdminStr({ listino, setListino, toast }) {
  const rows = listino || LISTINO_STR_INIT;
  const [hover, setHover] = useState(null);
  const [rowModal, setRowModal] = useState(undefined);
  const [groupModal, setGroupModal] = useState(undefined);
  const [confirm, setConfirm] = useState(null);

  const groups = rows.filter(r=>r.tipo==='gruppo');

  const childrenOf = (gid) => {
    const out = []; let inGroup = false;
    for (const r of rows) {
      if (r.tipo==='gruppo') { inGroup = r.id===gid; continue; }
      if (inGroup) out.push(r);
    }
    return out;
  };

  const saveRow = async (data) => {
    // data: {id?, nome, gruppo, giorno, mese}
    const isEdit = !!data.id && rows.some(r=>r.id===data.id);
    if (!window.SF_CONFIG.useSupabase) {
      // Solo aggiornamento locale
      if (isEdit) {
        let next = rows.map(r=>r.id===data.id ? { ...r, nome:data.nome, giorno:data.giorno, mese:data.mese } : r);
        setListino(next);
      } else {
        const row = { id:'str'+Date.now(), nome:data.nome, giorno:data.giorno, mese:data.mese };
        setListino(insertIntoGroup(rows, row, data.gruppo));
      }
      setRowModal(undefined);
      toast(isEdit ? 'Voce aggiornata' : 'Voce aggiunta');
      return;
    }

    try {
      const dbRow = {
        group_id: data.gruppo || null,
        nome: data.nome,
        giorno: data.giorno === SR ? null : data.giorno,
        mese: data.mese === SR ? null : data.mese,
        giorno_sr: data.giorno === SR,
        mese_sr: data.mese === SR,
      };
      if (isEdit) {
        await window.DataAPI.update('str_prices', data.id, dbRow);
      } else {
        // Calcolo ordine: ultimo dei prezzi del gruppo + 10
        const allPrices = await window.DataAPI.list('str_prices');
        const ordini = (allPrices || []).filter(p => p.group_id === data.gruppo).map(p => p.ordine || 0);
        const nextOrd = ordini.length ? Math.max(...ordini) + 10 : 10;
        await window.DataAPI.insert('str_prices', { ...dbRow, ordine: nextOrd });
      }
      const merged = await reloadStr();
      if (merged) setListino(merged);
    } catch (e) {
      console.error('saveRow str', e);
      toast('Errore salvataggio: ' + (e?.message || 'sconosciuto'));
      return;
    }
    setRowModal(undefined);
    toast(isEdit ? 'Voce aggiornata' : 'Voce aggiunta al listino STR');
  };

  const saveGroup = async (data) => {
    const isEdit = !!data.id && rows.some(r=>r.id===data.id);

    if (!window.SF_CONFIG.useSupabase) {
      if (isEdit) {
        setListino(rows.map(r=>r.id===data.id?{...r, nome:data.nome}:r));
      } else {
        setListino([...rows, { id:'g'+Date.now(), tipo:'gruppo', nome:data.nome }]);
      }
      setGroupModal(undefined);
      toast(isEdit ? 'Gruppo rinominato' : 'Gruppo aggiunto');
      return;
    }

    try {
      if (isEdit) {
        await window.DataAPI.update('str_groups', data.id, { nome: data.nome });
      } else {
        const allGroups = await window.DataAPI.list('str_groups');
        const ordini = (allGroups || []).map(g => g.ordine || 0);
        const nextOrd = ordini.length ? Math.max(...ordini) + 10 : 10;
        await window.DataAPI.insert('str_groups', { nome: data.nome, ordine: nextOrd });
      }
      const merged = await reloadStr();
      if (merged) setListino(merged);
    } catch (e) {
      console.error('saveGroup str', e);
      toast('Errore salvataggio: ' + (e?.message || 'sconosciuto'));
      return;
    }
    setGroupModal(undefined);
    toast(isEdit ? 'Gruppo rinominato' : 'Gruppo aggiunto');
  };

  const removeRow = async (r) => {
    if (window.SF_CONFIG.useSupabase) {
      try { await window.DataAPI.remove('str_prices', r.id); }
      catch (e) { console.error(e); toast('Errore eliminazione'); return; }
    }
    setListino(rows.filter(x=>x.id!==r.id));
    setConfirm(null);
    toast('Voce rimossa');
  };

  const removeGroup = async (g) => {
    if (window.SF_CONFIG.useSupabase) {
      try {
        // Prima elimina tutti i prezzi del gruppo, poi il gruppo
        const sb = window.DataAPI.client();
        await sb.from('str_prices').delete().eq('group_id', g.id);
        await window.DataAPI.remove('str_groups', g.id);
      } catch (e) { console.error(e); toast('Errore eliminazione'); return; }
    }
    const childIds = childrenOf(g.id).map(c=>c.id);
    setListino(rows.filter(x=>x.id!==g.id && !childIds.includes(x.id)));
    setConfirm(null);
    toast('Gruppo e relative voci rimossi');
  };

  return (
    <>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:16, gap:16, flexWrap:'wrap' }}>
        <div>
          <h2 style={{ margin:0, fontFamily:'var(--font-display)', fontSize:19, fontWeight:800 }}>Listino STR</h2>
          <div style={{ fontSize:13, color:'var(--ink-3)', marginTop:2 }}>Noleggio breve termine · organizzato per macrocategoria. Visibile dal pulsante "Listino STR" nelle schede prodotto.</div>
        </div>
        <div style={{ display:'flex', gap:10 }}>
          <Btn variant="ghost" icon="plus" onClick={()=>setGroupModal(null)}>Nuova macrocategoria</Btn>
          <Btn icon="plus" onClick={()=>setRowModal({ row:null, gruppo: groups[0]?.id || '' })}>Nuova voce</Btn>
        </div>
      </div>

      <div style={{ background:'var(--surface)', border:'1px solid var(--line)', borderRadius:'var(--r-lg)', overflow:'hidden', boxShadow:'var(--sh-1)' }}>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 140px 140px 96px', gap:0, padding:'12px 18px', background:'var(--surface-2)', borderBottom:'1px solid var(--line)',
          fontSize:11, fontWeight:800, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.04em', alignItems:'center' }}>
          <span>Tipologia</span><span style={{ textAlign:'right' }}>€ / giorno</span><span style={{ textAlign:'right' }}>€ / mese</span><span style={{ textAlign:'right' }}>Azioni</span>
        </div>
        {rows.map((r,i)=> r.tipo==='gruppo' ? (
          <div key={r.id} onMouseEnter={()=>setHover(r.id)} onMouseLeave={()=>setHover(null)}
            style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'11px 18px', background:'var(--red-tint)', borderBottom:'1px solid var(--line-2)' }}>
            <span style={{ fontSize:11.5, fontWeight:800, color:'var(--red)', textTransform:'uppercase', letterSpacing:'.05em' }}>{r.nome}</span>
            <div style={{ display:'flex', gap:6, opacity:hover===r.id?1:0, transition:'.12s' }}>
              <button onClick={()=>setGroupModal({ id:r.id, nome:r.nome })} title="Rinomina macrocategoria" style={{ width:28, height:28, borderRadius:7, border:'1.5px solid var(--red-tint-2)', color:'var(--red)', display:'flex', alignItems:'center', justifyContent:'center' }}><Icon name="edit" size={14} /></button>
              <button onClick={()=>setConfirm({ kind:'group', item:r })} title="Elimina macrocategoria" style={{ width:28, height:28, borderRadius:7, border:'1.5px solid var(--red-tint-2)', color:'var(--red)', display:'flex', alignItems:'center', justifyContent:'center' }}><Icon name="x" size={14} /></button>
            </div>
          </div>
        ) : (
          <div key={r.id} onMouseEnter={()=>setHover(r.id)} onMouseLeave={()=>setHover(null)}
            style={{ display:'grid', gridTemplateColumns:'1fr 140px 140px 96px', gap:0, padding:'11px 18px', borderBottom: i<rows.length-1?'1px solid var(--line-2)':'none', alignItems:'center', background:hover===r.id?'var(--surface-2)':'transparent' }}>
            <span style={{ fontSize:13.5, fontWeight:600, color:'var(--ink)' }}>{r.nome}</span>
            <span style={{ textAlign:'right', fontWeight:700, fontSize:13.5, color: r.giorno===SR?'var(--ink-4)':(r.giorno!=null?'var(--ink)':'var(--ink-4)') }}>{strPrice(r.giorno)}</span>
            <span style={{ textAlign:'right', fontWeight:700, fontSize:13.5, color: r.mese===SR?'var(--ink-4)':(r.mese!=null?'var(--ink)':'var(--ink-4)') }}>{strPrice(r.mese)}</span>
            <div style={{ display:'flex', gap:6, justifyContent:'flex-end', opacity:hover===r.id?1:0, transition:'.12s' }}>
              <button onClick={()=>setRowModal({ row:r, gruppo: groupIdOfRow(rows, r.id) })} title="Modifica" style={iconBtn}><Icon name="edit" size={15} /></button>
              <button onClick={()=>setConfirm({ kind:'row', item:r })} title="Elimina" style={{ ...iconBtn, color:'var(--red)', borderColor:'var(--red-tint-2)' }}><Icon name="x" size={15} /></button>
            </div>
          </div>
        ))}
        <button onClick={()=>setRowModal({ row:null, gruppo: groups[0]?.id || '' })} style={{ width:'100%', display:'flex', alignItems:'center', gap:10, padding:'13px 18px', color:'var(--ink-3)', fontSize:13.5, fontWeight:700, borderTop:'1px dashed var(--line)', background:'var(--surface-2)' }}
          onMouseEnter={e=>e.currentTarget.style.color='var(--red)'} onMouseLeave={e=>e.currentTarget.style.color='var(--ink-3)'}>
          <Icon name="plus" size={17} /> Aggiungi voce
        </button>
      </div>
      <div style={{ marginTop:14, fontSize:12.5, color:'var(--ink-4)', display:'flex', alignItems:'center', gap:8 }}>
        <Icon name="clock" size={15} /> Modifica una voce con la matita. Nella scheda voce puoi impostare "Su richiesta" o lasciare un prezzo vuoto.
      </div>

      {rowModal!==undefined && <StrRowModal data={rowModal} groups={groups} onClose={()=>setRowModal(undefined)} onSave={saveRow} />}
      {groupModal!==undefined && <StrGroupModal data={groupModal} onClose={()=>setGroupModal(undefined)} onSave={saveGroup} />}
      {confirm && <ConfirmDialog
        title={confirm.kind==='group'?'Eliminare la macrocategoria?':'Eliminare la voce?'}
        message={confirm.kind==='group'
          ? <>Stai per eliminare <b>{confirm.item.nome}</b> e tutte le voci al suo interno.</>
          : <>Stai per eliminare la voce <b>{confirm.item.nome}</b> dal listino STR.</>}
        confirmLabel={confirm.kind==='group'?'Elimina macrocategoria':'Elimina voce'}
        onConfirm={()=>confirm.kind==='group'?removeGroup(confirm.item):removeRow(confirm.item)} onClose={()=>setConfirm(null)} />}
    </>
  );
}

function groupIdOfRow(rows, id){
  let g='';
  for (const r of rows){ if(r.tipo==='gruppo') g=r.id; if(r.id===id) return g; }
  return '';
}
function insertIntoGroup(rows, row, gid){
  if (!gid) return [...rows, row];
  const out=[]; let placed=false; let inTarget=false;
  for (let i=0;i<rows.length;i++){
    const r=rows[i];
    if (r.tipo==='gruppo'){
      if (inTarget && !placed){ out.push(row); placed=true; }
      inTarget = r.id===gid;
      out.push(r);
      continue;
    }
    out.push(r);
  }
  if (inTarget && !placed){ out.push(row); placed=true; }
  if (!placed) out.push(row);
  return out;
}

function StrRowModal({ data, groups, onClose, onSave }) {
  const isNew = !data.row;
  const r = data.row || {};
  const [nome, setNome] = useState(r.nome || '');
  const [gruppo, setGruppo] = useState(data.gruppo || '');
  const valOf = (v)=> v===SR?'SR':(v!=null?String(v):'');
  const [giorno, setGiorno] = useState(valOf(r.giorno));
  const [mese, setMese] = useState(valOf(r.mese));
  const parse = (s)=>{ const t=s.trim(); if(/^sr$|^su richiesta$/i.test(t)) return SR; if(t==='') return null; const n=parseFloat(t.replace(/[^\d.,]/g,'').replace(',','.')); return isNaN(n)?null:n; };
  const submit = ()=>{ if(!nome.trim()) return; onSave({ id:r.id, nome:nome.trim(), gruppo, giorno:parse(giorno), mese:parse(mese) }); };
  return (
    <ModalShell onClose={onClose} width={480} title={isNew?'Nuova voce listino STR':'Modifica voce'} subtitle={isNew?'Tipologia, macrocategoria e tariffe':r.nome}>
      <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
        <Field label="Tipologia" required>
          <input value={nome} onChange={e=>setNome(e.target.value)} placeholder="es. CBE 10-15 ton" style={inputStyle} autoFocus />
        </Field>
        <Field label="Macrocategoria">
          <div style={{ position:'relative' }}>
            <select value={gruppo} onChange={e=>setGruppo(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:34 }}>
              <option value="">— Senza macrocategoria —</option>
              {groups.map(g=><option key={g.id} value={g.id}>{g.nome}</option>)}
            </select>
            <Icon name="chevDown" size={16} style={{ position:'absolute', right:12, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
          </div>
        </Field>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
          <Field label="€ / giorno">
            <input value={giorno} onChange={e=>setGiorno(e.target.value)} placeholder="es. 55 o SR" style={inputStyle} />
          </Field>
          <Field label="€ / mese">
            <input value={mese} onChange={e=>setMese(e.target.value)} placeholder="es. 700 o SR" style={inputStyle} />
          </Field>
        </div>
        <div style={{ fontSize:12, color:'var(--ink-4)', display:'flex', alignItems:'center', gap:7 }}>
          <Icon name="clock" size={13} /> Scrivi "SR" per "su richiesta", lascia vuoto per nessun prezzo.
        </div>
      </div>
      <div style={{ display:'flex', gap:12, marginTop:22 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={submit} disabled={!nome.trim()}>{isNew?'Aggiungi voce':'Salva'}</Btn>
      </div>
    </ModalShell>
  );
}

function StrGroupModal({ data, onClose, onSave }) {
  const isNew = !data;
  const [nome, setNome] = useState(data?.nome || '');
  const submit = ()=>{ if(!nome.trim()) return; onSave({ id:data?.id, nome:nome.trim() }); };
  return (
    <ModalShell onClose={onClose} width={440} title={isNew?'Nuova macrocategoria':'Rinomina macrocategoria'} subtitle={isNew?'Raggruppa le voci del listino STR':data.nome}>
      <Field label="Nome macrocategoria" required>
        <input value={nome} onChange={e=>setNome(e.target.value)} placeholder="es. Controbilanciati elettrici" style={inputStyle} autoFocus
          onKeyDown={e=>e.key==='Enter'&&submit()} />
      </Field>
      <div style={{ display:'flex', gap:12, marginTop:22 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={submit} disabled={!nome.trim()}>{isNew?'Crea macrocategoria':'Salva'}</Btn>
      </div>
    </ModalShell>
  );
}

Object.assign(window, { StrListinoModal, AdminStr, strPrice });