/* ============================================================
   OPPORTUNITÀ — modal dettaglio + modal creazione
   Gestisce: note, fase, commerciale, prenotazioni collegate,
   macchine nuove desiderate (ricerca+crea), timeline.
   ============================================================ */

/* ---- Ricerca/crea macchina desiderata (nuova) ---- */
function DesiredMachineField({ currentUser, onAdd }) {
  const [q, setQ] = useState('');
  const [results, setResults] = useState([]);
  const [open, setOpen] = useState(false);
  const [searching, setSearching] = useState(false);
  const timer = useRef(null);

  const onChange = (v) => {
    setQ(v);
    if (!v.trim() || v.trim().length < 2) { setResults([]); setOpen(false); return; }
    setOpen(true); setSearching(true);
    if (timer.current) clearTimeout(timer.current);
    timer.current = setTimeout(async () => {
      try { setResults(await window.DataAPI.searchDesiredMachines(v) || []); }
      catch(e){ console.error(e); setResults([]); }
      finally { setSearching(false); }
    }, 280);
  };

  const pick = (m) => { onAdd(m); setQ(''); setResults([]); setOpen(false); };
  const createNew = async () => {
    const n = q.trim(); if (n.length < 2) return;
    try {
      const m = await window.DataAPI.createDesiredMachine(n, currentUser?.id);
      if (m) pick(m);
    } catch(e){ console.error(e); }
  };

  const exactExists = results.some(r => r.nome.toLowerCase() === q.trim().toLowerCase());

  return (
    <div style={{ position:'relative' }}>
      <div style={{ position:'relative' }}>
        <Icon name="search" size={16} style={{ position:'absolute', left:12, top:'50%', transform:'translateY(-50%)', color:'var(--ink-4)' }} />
        <input value={q} onChange={e=>onChange(e.target.value)} placeholder="Cerca o aggiungi macchina nuova…"
          style={{ ...inputStyle, paddingLeft:38 }} onFocus={()=>q.trim().length>=2&&setOpen(true)} />
      </div>
      {open && q.trim().length >= 2 && (
        <div style={{ position:'absolute', top:'100%', left:0, right:0, marginTop:4, zIndex:30, background:'var(--surface)',
          border:'1px solid var(--line)', borderRadius:'var(--r-md)', boxShadow:'var(--sh-2)', maxHeight:260, overflowY:'auto' }}>
          {searching && <div style={{ padding:'10px 13px', fontSize:12.5, color:'var(--ink-3)' }}>Ricerca…</div>}
          {results.map(m => (
            <button key={m.id} onClick={()=>pick(m)} style={{ display:'flex', width:'100%', textAlign:'left', alignItems:'center', gap:9,
              padding:'10px 13px', borderBottom:'1px solid var(--line-2)', fontSize:13.5 }}>
              <Icon name="boxes" size={15} style={{ color:'var(--ink-3)' }} /> {m.nome}
            </button>
          ))}
          {!searching && !exactExists && (
            <button onClick={createNew} style={{ display:'flex', width:'100%', textAlign:'left', alignItems:'center', gap:9,
              padding:'10px 13px', fontSize:13.5, fontWeight:700, color:'var(--red)' }}>
              <Icon name="plus" size={15} /> Aggiungi "{q.trim()}"
            </button>
          )}
          {!searching && results.length===0 && exactExists && (
            <div style={{ padding:'10px 13px', fontSize:12.5, color:'var(--ink-4)' }}>Già presente</div>
          )}
        </div>
      )}
    </div>
  );
}

/* ---- PAGINA dettaglio opportunità ---- */
function OpportunityDetail({ opportunity, role, currentUser, users, stages, bookings, archive, clienti, products, clienteCat, onBack, onChangeStage, onReload, onOpenBooking, toast }) {
  const vp = useViewport();
  const isManager = role==='admin' || role==='backoffice';
  const [note, setNote] = useState(opportunity.note || '');
  const [savingNote, setSavingNote] = useState(false);
  const [prob, setProb] = useState(opportunity.prob!=null ? String(opportunity.prob) : '');
  const [linkedBookings, setLinkedBookings] = useState([]);
  const [desired, setDesired] = useState([]);
  const [history, setHistory] = useState([]);
  const [visits, setVisits] = useState([]);
  const [loading, setLoading] = useState(true);
  const [commId, setCommId] = useState(opportunity.commerciale_id || '');
  const [confirmList, setConfirmList] = useState(null); // per la conferma multi-macchina
  const [removeTarget, setRemoveTarget] = useState(null); // macchina da rimuovere
  const [addingVisit, setAddingVisit] = useState(false);
  const [desiredPending, setDesiredPending] = useState(null); // macchina in attesa dei dati contratto

  const stage = (stages||[]).find(s => s.id === opportunity.stage_id);
  const stageName = (id) => (stages||[]).find(s=>s.id===id)?.nome || '—';
  const commName = (id) => (users||[]).find(u=>u.id===id)?.nome || '—';
  const cliente = opportunity.cliente || (clienti||[]).find(c=>c.id===opportunity.cliente_id)?.ragione_sociale || 'Opportunità';

  const load = async () => {
    setLoading(true);
    try {
      const [obLinks, dmLinks, hist] = await Promise.all([
        window.DataAPI.list('opportunity_bookings', { eq:['opportunity_id', opportunity.id] }),
        window.DataAPI.list('opportunity_desired_machines', { eq:['opportunity_id', opportunity.id] }),
        window.DataAPI.list('opportunity_stage_history', { eq:['opportunity_id', opportunity.id] }),
      ]);
      // visite collegate a questa opportunità
      try {
        const allVisits = await window.DataAPI.listVisits();
        setVisits((allVisits||[]).filter(v => v.opportunity_id === opportunity.id).sort((a,b)=>new Date(b.data_visita)-new Date(a.data_visita)));
      } catch(e){ setVisits([]); }
      const bIds = (obLinks||[]).map(l=>l.booking_id);
      // prenotazioni: prima da bookings attivi, poi da archivio
      const active = (bookings||[]).filter(b => bIds.includes(b.id));
      const archivedLinked = (archive||[]).filter(b => bIds.includes(b.id) && !active.some(a=>a.id===b.id));
      setLinkedBookings([...active, ...archivedLinked.map(b=>({ ...b, _archived:true }))]);

      const dmIds = (dmLinks||[]).map(l=>l.desired_machine_id);
      if (dmIds.length) {
        const all = await window.DataAPI.list('desired_machines');
        setDesired((all||[]).filter(m => dmIds.includes(m.id)));
      } else setDesired([]);
      setHistory((hist||[]).slice().sort((a,b)=>new Date(a.changed_at)-new Date(b.changed_at)));
    } catch(e){ console.error('load opp detail', e); }
    finally { setLoading(false); }
  };
  useEffect(()=>{ load(); }, [opportunity.id, bookings, archive]);

  const saveNote = async () => {
    setSavingNote(true);
    try { await window.DataAPI.update('opportunities', opportunity.id, { note }); toast('Note salvate'); onReload&&onReload(); }
    catch(e){ console.error(e); toast('Errore salvataggio note'); }
    finally { setSavingNote(false); }
  };
  const saveProb = async () => {
    const v = prob===''?null:Math.max(0,Math.min(100,parseInt(prob)||0));
    try { await window.DataAPI.update('opportunities', opportunity.id, { prob: v }); toast('Probabilità aggiornata'); onReload&&onReload(); }
    catch(e){ console.error(e); toast('Errore'); }
  };
  const changeComm = async (newId) => {
    setCommId(newId);
    try { await window.DataAPI.update('opportunities', opportunity.id, { commerciale_id: newId || null }); toast('Commerciale aggiornato'); onReload&&onReload(); }
    catch(e){ console.error(e); toast('Errore'); }
  };
  // Aggiunta macchina da casa madre: prima si chiedono tipo contratto ed
  // eventuali date/prezzo, poi si collega all'opportunità.
  const addDesired = (m) => {
    if (desired.some(d=>d.id===m.id)) return;
    setDesiredPending(m);
  };
  const confirmDesired = async (m, dati) => {
    try {
      await window.DataAPI.insert('opportunity_desired_machines', {
        opportunity_id: opportunity.id, desired_machine_id: m.id,
        tipo: dati.tipo || null,
        prezzo: dati.prezzo !== '' ? Number(dati.prezzo) : null,
        data_inizio: dati.inizio || null,
        data_fine: dati.fine || null,
      });
      setDesired(prev => [...prev, m]); setDesiredPending(null); onReload && onReload();
    } catch(e){ console.error(e); toast('Errore aggiunta macchina'); }
  };
  const removeDesired = async (m) => {
    try {
      const sb = window.DataAPI.client();
      await sb.from('opportunity_desired_machines').delete().eq('opportunity_id', opportunity.id).eq('desired_machine_id', m.id);
      setDesired(prev => prev.filter(x=>x.id!==m.id)); onReload && onReload();
    } catch(e){ console.error(e); toast('Errore'); }
  };

  // rimuovi macchina (libera + sgancia). Se è l'ultima attiva → chiedi cosa fare.
  const activeLinked = linkedBookings.filter(b=>!b._archived);
  const doRemoveBooking = async (b) => {
    try {
      await window.DataAPI.rpc('remove_booking_from_opportunity', {
        p_opportunity_id: opportunity.id, p_booking_id: b.id, p_user_id: currentUser?.id||null,
      });
      toast('Macchina rimossa e liberata');
      setRemoveTarget(null);
      onReload && onReload();
      load();
    } catch(e){ console.error(e); toast('Errore rimozione: '+(e?.message||'')); }
  };
  const onRemoveClick = (b) => {
    if (activeLinked.length === 1) {
      // ultima macchina: chiedi se chiudere come persa o tenere aperta
      setRemoveTarget({ booking:b, isLast:true });
    } else {
      setRemoveTarget({ booking:b, isLast:false });
    }
  };

  // conferma: 1 macchina → diretta a ordine; N → lista (gestita da modal esterno)
  const stageByCode = (code) => (stages||[]).find(s=>s.codice===code);
  const goToStage = (code) => { const s = stageByCode(code); if (s) onChangeStage(opportunity.id, s.id); };

  const closed = opportunity.esito && opportunity.esito !== 'aperta';

  return (
    <div className="scroll" style={{ flex:1, minWidth:0, overflowY:'auto', overflowX:'hidden' }}>
      {/* top bar */}
      <div style={{ padding: vp.isMobile?'10px 12px':'14px 30px', borderBottom:'1px solid var(--line)', background:'var(--surface)',
        display:'flex', alignItems:'center', gap: vp.isMobile?8:14, position:'sticky', top:0, zIndex:20, flexWrap: vp.isMobile?'wrap':'nowrap' }}>
        <button onClick={onBack} style={{ display:'flex', alignItems:'center', gap:7, fontSize:13, fontWeight:700, color:'var(--ink-2)', padding:'7px 12px', borderRadius:'var(--r-md)', border:'1.5px solid var(--line)', flexShrink:0 }}>
          <Icon name="chevLeft" size={16} /> {vp.isMobile ? '' : 'Avanzamento'}
        </button>
        <div style={{ flex:1, minWidth:0, order: vp.isMobile?3:0, width: vp.isMobile?'100%':'auto' }}>
          <h1 style={{ margin:0, fontFamily:'var(--font-display)', fontSize: vp.isMobile?16:19, fontWeight:800, letterSpacing:'-.01em', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{cliente}</h1>
          <div style={{ fontSize:12, color:'var(--ink-3)' }}>Opportunità · {stage?stage.nome:'—'}</div>
        </div>
        {stage && (
          <span style={{ display:'inline-flex', alignItems:'center', gap:6, padding:'5px 10px', borderRadius:99,
            background: closed ? (opportunity.esito==='vinta'?'#e8f6f0':'var(--line-2)') : 'var(--red-tint)',
            color: closed ? (opportunity.esito==='vinta'?'var(--st-disponibile)':'var(--ink-3)') : 'var(--red)',
            fontWeight:700, fontSize:11.5, flexShrink:0 }}>
            {closed ? (opportunity.esito==='vinta'?'Vinta':'Persa') : `${stage.percent}%`}
          </span>
        )}
      </div>

      <div style={{ padding: vp.isMobile?'16px 12px 30px':'24px 30px 50px', maxWidth:1180, margin:'0 auto' }}>
        <div style={{ display:'grid', gridTemplateColumns: vp.isMobile?'1fr':'1.4fr 1fr', gap: vp.isMobile?16:24, alignItems:'start' }}>

          {/* LEFT */}
          <div style={{ display:'flex', flexDirection:'column', gap:20 }}>

            {/* Macchine collegate */}
            <Card>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:12 }}>
                <h3 style={cardTitle}>Macchine ({activeLinked.length})</h3>
                {!closed && activeLinked.length>0 && (
                  <Btn size="sm" icon="check" onClick={()=> activeLinked.length===1 ? goToStage('ordine') : setConfirmList(activeLinked) }>Conferma</Btn>
                )}
              </div>
              {linkedBookings.length===0 ? (
                <div style={{ fontSize:13, color:'var(--ink-4)', padding:'6px 0' }}>Nessuna macchina collegata. L'opportunità può esistere anche senza macchine.</div>
              ) : (
                <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                  {linkedBookings.map(b => {
                    const prod = (products||[]).find(p=>p.id===b.prodId);
                    const modello = b.prodLabel || (prod ? [prod.marca, prod.modello].filter(Boolean).join(' ') : '') || 'Mezzo';
                    const matricola = prod?.matricola || b.matricola || null;
                    return (
                    <div key={b.id} style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 12px', background:'var(--surface-2)', borderRadius:'var(--r-md)', border:'1px solid var(--line)', opacity: b._archived?0.65:1 }}>
                      <Icon name="forklift" size={16} style={{ color:'var(--ink-3)', flexShrink:0 }} />
                      <button onClick={()=>!b._archived && onOpenBooking(b)} style={{ flex:1, minWidth:0, textAlign:'left', cursor: b._archived?'default':'pointer' }}>
                        <div style={{ fontSize:13, fontWeight:700, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{modello}</div>
                        <div style={{ fontSize:11.5, color:'var(--ink-3)' }}>
                          {matricola ? `Matr. ${matricola}` : ''}{matricola?' · ':''}{b.tipo==='STR'?'Noleggio breve':b.tipo==='LTR'?'Noleggio lungo':b.tipo}
                          {b.numeroPreventivo?` · prev. ${b.numeroPreventivo}`:''}{b._archived?' · archiviata':''}
                        </div>
                      </button>
                      {!b._archived && (
                        <button onClick={()=>onOpenBooking(b)} title="Apri prenotazione"
                          style={{ display:'inline-flex', alignItems:'center', gap:5, padding:'6px 11px', borderRadius:'var(--r-md)', border:'1.5px solid var(--line)', fontSize:12, fontWeight:700, color:'var(--ink-2)', flexShrink:0 }}>
                          Apri <Icon name="arrowRight" size={13} />
                        </button>
                      )}
                      {!closed && !b._archived && (
                        <button onClick={()=>onRemoveClick(b)} title="Rimuovi e libera" style={{ color:'var(--red)', padding:6, flexShrink:0 }}><Icon name="x" size={15} /></button>
                      )}
                    </div>
                    );
                  })}
                </div>
              )}
            </Card>

            {/* Macchine desiderate */}
            <Card>
              <h3 style={{ ...cardTitle, marginBottom:12 }}>Macchine nuove desiderate ({desired.length})</h3>
              {desired.length>0 && (
                <div style={{ display:'flex', flexWrap:'wrap', gap:8, marginBottom:12 }}>
                  {desired.map(m => (
                    <span key={m.id} style={{ display:'inline-flex', alignItems:'center', gap:7, padding:'6px 10px', background:'var(--red-tint)', borderRadius:99, fontSize:12.5, fontWeight:700, color:'var(--ink-2)' }}>
                      <Icon name="boxes" size={13} /> {m.nome}
                      {!closed && <button onClick={()=>removeDesired(m)} style={{ color:'var(--red)', display:'flex' }}><Icon name="x" size={13} /></button>}
                    </span>
                  ))}
                </div>
              )}
              {!closed && <DesiredMachineField currentUser={currentUser} onAdd={addDesired} />}
              {!closed && <div style={{ fontSize:11, color:'var(--ink-4)', marginTop:6 }}>Se il modello non è in elenco puoi aggiungerlo: sarà proposto agli altri commerciali.</div>}
            </Card>

            {/* Note */}
            <Card>
              <h3 style={{ ...cardTitle, marginBottom:10 }}>Note</h3>
              <textarea value={note} onChange={e=>setNote(e.target.value)} placeholder="Annotazioni sulla trattativa…" disabled={closed}
                style={{ ...inputStyle, minHeight:90, resize:'vertical', fontFamily:'inherit', opacity:closed?0.7:1 }} />
              {!closed && (
                <div style={{ display:'flex', justifyContent:'flex-end', marginTop:8 }}>
                  <Btn size="sm" icon="check" onClick={saveNote} disabled={savingNote || note===(opportunity.note||'')}>Salva note</Btn>
                </div>
              )}
            </Card>
          </div>

          {/* RIGHT */}
          <div style={{ display:'flex', flexDirection:'column', gap:20 }}>

            {/* Fase */}
            <Card>
              <h3 style={{ ...cardTitle, marginBottom:12 }}>Fase</h3>
              <div style={{ position:'relative', marginBottom:10 }}>
                <select value={opportunity.stage_id||''} onChange={e=>onChangeStage(opportunity.id, e.target.value)} disabled={closed}
                  style={{ ...inputStyle, appearance:'none', paddingRight:34, fontWeight:700, opacity:closed?0.7:1 }}>
                  {(stages||[]).filter(s=>s.active).map(s=><option key={s.id} value={s.id}>{s.nome} · {s.percent}%</option>)}
                </select>
                <Icon name="chevDown" size={16} style={{ position:'absolute', right:12, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
              </div>
              {/* barra avanzamento */}
              <div style={{ height:6, borderRadius:99, background:'var(--line-2)', overflow:'hidden' }}>
                <div style={{ width:(stage?.percent||0)+'%', height:'100%', background:'var(--red)', borderRadius:99, transition:'width .3s' }} />
              </div>
              <div style={{ fontSize:11.5, color:'var(--ink-4)', fontWeight:600, marginTop:6 }}>{stage?.percent||0}% avanzamento</div>
              {closed && <div style={{ marginTop:10, fontSize:12.5, fontWeight:700, color: opportunity.esito==='vinta'?'var(--st-disponibile)':'var(--ink-3)' }}>Opportunità {opportunity.esito}{opportunity.chiusa_il?` · ${new Date(opportunity.chiusa_il).toLocaleDateString('it-IT')}`:''}</div>}
            </Card>

            {/* Dati commerciali */}
            <Card>
              <h3 style={{ ...cardTitle, marginBottom:12 }}>Dati commerciali</h3>
              <div style={{ marginBottom:14 }}>
                <SectionLabel>Commerciale di riferimento</SectionLabel>
                {isManager && !closed ? (
                  <div style={{ position:'relative' }}>
                    <select value={commId} onChange={e=>changeComm(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:34 }}>
                      <option value="">— Nessuno —</option>
                      {(users||[]).map(u=><option key={u.id} value={u.id}>{u.nome}{u.role&&u.role!=='commerciale'?' ('+u.role+')':''}</option>)}
                    </select>
                    <Icon name="chevDown" size={16} style={{ position:'absolute', right:12, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
                  </div>
                ) : (
                  <div style={{ fontSize:14, fontWeight:700 }}>{commName(opportunity.commerciale_id)}</div>
                )}
              </div>
              <div>
                <SectionLabel>Probabilità di chiusura</SectionLabel>
                {!closed ? (
                  <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                    <input type="number" min="0" max="100" value={prob} onChange={e=>setProb(e.target.value)} placeholder="—"
                      style={{ ...inputStyle, width:90 }} />
                    <span style={{ fontSize:14, color:'var(--ink-3)' }}>%</span>
                    <Btn size="sm" onClick={saveProb} disabled={prob===(opportunity.prob!=null?String(opportunity.prob):'')}>Salva</Btn>
                  </div>
                ) : (
                  <div style={{ fontSize:14, fontWeight:700 }}>{opportunity.prob!=null?`${opportunity.prob}%`:'—'}</div>
                )}
              </div>
            </Card>

            {/* Visite */}
            <Card>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:12 }}>
                <h3 style={cardTitle}>Visite ({visits.length})</h3>
                {!closed && <Btn size="sm" variant="ghost" icon="plus" onClick={()=>setAddingVisit(true)}>Programma</Btn>}
              </div>
              {visits.length===0 ? (
                <div style={{ fontSize:13, color:'var(--ink-4)' }}>Nessuna visita collegata. Programmale dal Calendario.</div>
              ) : (
                <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                  {visits.map(v => {
                    const d = new Date(v.data_visita);
                    const future = d >= new Date() && v.stato==='programmata';
                    return (
                      <div key={v.id} style={{ display:'flex', alignItems:'center', gap:10, padding:'9px 11px', background:'var(--surface-2)', borderRadius:'var(--r-md)', border:'1px solid var(--line)' }}>
                        <Icon name="calendar" size={15} style={{ color: future?'var(--red)':'var(--ink-3)', flexShrink:0 }} />
                        <div style={{ flex:1, minWidth:0 }}>
                          <div style={{ fontSize:12.5, fontWeight:700 }}>{v.titolo || 'Visita'}</div>
                          <div style={{ fontSize:11, color:'var(--ink-3)' }}>{d.toLocaleDateString('it-IT',{day:'2-digit',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'})}</div>
                        </div>
                        <span style={{ fontSize:10, fontWeight:800, padding:'2px 7px', borderRadius:99,
                          background: v.stato==='completata'?'#e8f6f0':future?'var(--red-tint)':'var(--line-2)',
                          color: v.stato==='completata'?'var(--st-disponibile)':future?'var(--red)':'var(--ink-3)' }}>
                          {v.stato==='completata'?'Fatta':future?'In arrivo':v.stato==='annullata'?'Annullata':'Passata'}
                        </span>
                      </div>
                    );
                  })}
                </div>
              )}
            </Card>

            {/* Timeline */}
            <Card>
              <h3 style={{ ...cardTitle, marginBottom:12 }}>Cronologia fasi</h3>
              {loading ? <div style={{ fontSize:13, color:'var(--ink-3)' }}>Caricamento…</div>
                : history.length===0 ? <div style={{ fontSize:13, color:'var(--ink-4)' }}>Nessun cambio fase registrato.</div>
                : (
                  <div style={{ position:'relative', paddingLeft:20 }}>
                    <div style={{ position:'absolute', left:5, top:6, bottom:6, width:2, background:'var(--line)' }} />
                    {history.map((h) => (
                      <div key={h.id} style={{ position:'relative', paddingBottom:14 }}>
                        <span style={{ position:'absolute', left:-19, top:2, width:12, height:12, borderRadius:99, background:'var(--red)', border:'2px solid var(--surface)' }} />
                        <div style={{ fontSize:13, fontWeight:700 }}>{h.from_stage_id ? `${stageName(h.from_stage_id)} → ` : 'Creata in '}{stageName(h.to_stage_id)}</div>
                        <div style={{ fontSize:11.5, color:'var(--ink-4)' }}>
                          {new Date(h.changed_at).toLocaleDateString('it-IT', { day:'2-digit', month:'short', year:'numeric', hour:'2-digit', minute:'2-digit' })}
                          {h.changed_by ? ` · ${commName(h.changed_by)}` : ''}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
            </Card>
          </div>
        </div>
      </div>

      {/* Conferma multi-macchina */}
      {confirmList && (
        <ConfirmMachinesModal machines={confirmList} onClose={()=>setConfirmList(null)}
          onConfirm={(keepIds)=>{ setConfirmList(null); goToStage('ordine'); }} />
      )}

      {/* Rimozione macchina */}
      {removeTarget && !removeTarget.isLast && (
        <ConfirmDialog
          title="Rimuovere la macchina?"
          message={<>La macchina <b>{removeTarget.booking.prodLabel}</b> verrà liberata (torna disponibile) e scollegata dall'opportunità.</>}
          confirmLabel="Rimuovi e libera"
          onConfirm={()=>doRemoveBooking(removeTarget.booking)}
          onClose={()=>setRemoveTarget(null)}
        />
      )}
      {removeTarget && removeTarget.isLast && (
        <ModalShell onClose={()=>setRemoveTarget(null)} width={440} title="Ultima macchina della trattativa"
          subtitle="Questa è l'unica macchina dell'opportunità">
          <div style={{ fontSize:13.5, color:'var(--ink-2)', lineHeight:1.5, marginBottom:18 }}>
            Rimuovendo <b>{removeTarget.booking.prodLabel}</b> la macchina verrà liberata. Vuoi chiudere l'opportunità come <b>persa</b> oppure tenerla aperta senza macchine (potrai ricollegarne altre)?
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:9 }}>
            <Btn full icon="x" onClick={()=>{ doRemoveBooking(removeTarget.booking); goToStage('perso'); }}>Libera e chiudi come persa</Btn>
            <Btn full variant="ghost" onClick={()=>doRemoveBooking(removeTarget.booking)}>Libera e tieni aperta</Btn>
            <Btn full variant="ghost" onClick={()=>setRemoveTarget(null)}>Annulla</Btn>
          </div>
        </ModalShell>
      )}

      {/* Dati contratto per una macchina da casa madre appena aggiunta */}
      {desiredPending && (
        <DesiredDataModal machine={desiredPending}
          onClose={()=>setDesiredPending(null)}
          onSave={(dati)=>confirmDesired(desiredPending, dati)} />
      )}

      {/* Nuova visita precompilata con cliente + opportunità */}
      {addingVisit && (
        <VisitModal
          visit={null}
          prefillDate={new Date()}
          role={role} currentUser={currentUser} users={users} clienti={clienti}
          opportunities={[opportunity]} stages={stages} bookings={bookings}
          prefillCliente={{ nome: cliente, id: opportunity.cliente_id }}
          prefillOppId={opportunity.id}
          onClose={()=>setAddingVisit(false)}
          onSave={async (v)=>{
            try {
              const saved = await window.DataAPI.saveVisit(v);
              if (saved) window.LogAPI?.logEvent('visit.scheduled', {
                entity_type:'visit', entity_id: saved.id, title:'Visita programmata',
                description:`${saved.cliente} · ${new Date(saved.data_visita).toLocaleDateString('it-IT')}`,
                metadata:{ cliente: saved.cliente, commerciale_id: saved.commerciale_id, data_visita: saved.data_visita },
              });
              toast('Visita programmata'); setAddingVisit(false); load();
            } catch(e){ console.error(e); toast('Errore: '+(e?.message||'')); }
          }}
          onDelete={()=>{}} />
      )}
    </div>
  );
}

/* Modal conferma multi-macchina: lista con cestino per escluderne alcune */
function ConfirmMachinesModal({ machines, onClose, onConfirm }) {
  const [excluded, setExcluded] = useState([]);
  const toggle = (id) => setExcluded(prev => prev.includes(id) ? prev.filter(x=>x!==id) : [...prev, id]);
  const keep = machines.filter(m=>!excluded.includes(m.id));
  return (
    <ModalShell onClose={onClose} width={460} title="Conferma ordine" subtitle="Seleziona le macchine da confermare per questo cliente">
      <div style={{ display:'flex', flexDirection:'column', gap:8, marginBottom:16 }}>
        {machines.map(m => {
          const off = excluded.includes(m.id);
          return (
            <div key={m.id} style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 12px', borderRadius:'var(--r-md)',
              border:'1px solid var(--line)', background: off?'var(--line-2)':'var(--surface-2)', opacity: off?0.55:1 }}>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:13, fontWeight:700, textDecoration: off?'line-through':'none' }}>{m.prodLabel}</div>
                <div style={{ fontSize:11.5, color:'var(--ink-3)' }}>{m.tipo}</div>
              </div>
              <button onClick={()=>toggle(m.id)} title={off?'Reintegra':'Escludi'} style={{ color: off?'var(--ink-3)':'var(--red)', padding:6 }}>
                <Icon name={off?'refresh':'x'} size={15} />
              </button>
            </div>
          );
        })}
      </div>
      <div style={{ fontSize:12, color:'var(--ink-3)', marginBottom:16 }}>
        {keep.length} macchina/e verranno confermate · l'opportunità passa in "ordine". Le escluse restano collegate ma non confermate.
      </div>
      <div style={{ display:'flex', gap:12 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={()=>onConfirm(keep.map(m=>m.id))} disabled={keep.length===0}>Conferma {keep.length>0?`(${keep.length})`:''}</Btn>
      </div>
    </ModalShell>
  );
}

/* piccoli helper stile card */
const cardTitle = { margin:0, fontFamily:'var(--font-display)', fontSize:16, fontWeight:800 };
function Card({ children }) {
  return <div style={{ background:'var(--surface)', border:'1px solid var(--line)', borderRadius:'var(--r-lg)', padding:'18px 20px', boxShadow:'var(--sh-1)' }}>{children}</div>;
}

/* ---- Modal creazione opportunità ---- */
function OpportunityNewModal({ role, currentUser, users, stages, clienti, setClienti, zone, clienteCat,
                              products, attributi, onClose, onCreated, toast }) {
  const vp = useViewport();
  const isManager = role==='admin' || role==='backoffice';
  // --- cliente ---
  const [clienteName, setClienteName] = useState('');
  const [clienteId, setClienteId] = useState(null);
  const [nuovoCliente, setNuovoCliente] = useState(false);   // crea cliente non in elenco
  const [nzona, setNzona] = useState('');
  const [ncat, setNcat] = useState('');
  const [results, setResults] = useState([]);
  const [showResults, setShowResults] = useState(false);
  const timer = useRef(null);
  // --- opportunità ---
  const [stageId, setStageId] = useState('');
  const [commId, setCommId] = useState(currentUser?.id || '');
  const [note, setNote] = useState('');
  const [saving, setSaving] = useState(false);
  // --- macchine (righe da aggiungere) ---
  // { key, source:'catalogo'|'casamadre', prodId?, label, desiredId?, desiredNome?,
  //   catId?, sub?, tipo, prezzo, inizio, fine }
  const [righe, setRighe] = useState([]);
  const [pickerOpen, setPickerOpen] = useState(null); // 'catalogo' | 'casamadre' | null

  useEffect(() => {
    const first = (stages||[]).filter(s=>s.active).sort((a,b)=>(a.sort_order||0)-(b.sort_order||0))[0];
    if (first && !stageId) setStageId(first.id);
  }, [stages]);

  const onClienteChange = (v) => {
    setClienteName(v); setClienteId(null);
    if (!v.trim() || v.trim().length<2) { setResults([]); setShowResults(false); return; }
    setShowResults(true);
    if (timer.current) clearTimeout(timer.current);
    timer.current = setTimeout(async () => {
      try { setResults(await window.DataAPI.searchClienti(v) || []); } catch(e){ setResults([]); }
    }, 280);
  };
  const pickCliente = (c) => { setClienteName(c.ragione_sociale); setClienteId(c.id); setNuovoCliente(false); setResults([]); setShowResults(false); };

  const addRiga = (r) => { setRighe(prev => [...prev, { key: 'r'+Date.now()+Math.random(), tipo:'Vendita', prezzo:'', inizio:'', fine:'', ...r }]); setPickerOpen(null); };
  const updRiga = (key, patch) => setRighe(prev => prev.map(r => r.key===key ? { ...r, ...patch } : r));
  const delRiga = (key) => setRighe(prev => prev.filter(r => r.key!==key));

  const isNol = (t) => t==='STR' || t==='LTR' || t==='Tampone';
  // Le date servono per i noleggi, TRANNE un LTR da casa madre: a inizio
  // trattativa non si sa quando il cliente ordina né quando la casa madre
  // consegna, quindi lì restano facoltative.
  const dateFacoltative = (r) => r.source === 'casamadre' && r.tipo === 'LTR';
  const valid = clienteName.trim().length >= 2 && stageId &&
    righe.every(r => !isNol(r.tipo) || dateFacoltative(r) || (r.inizio && r.fine));

  const submit = async () => {
    if (!valid) return;
    setSaving(true);
    try {
      // 1) cliente nuovo se richiesto
      let cid = clienteId;
      if (!cid && nuovoCliente) {
        const nc = await window.DataAPI.insert('clienti', {
          ragione_sociale: clienteName.trim(),
          zona_id: nzona || null,
          client_category_id: ncat || null,
        });
        if (nc?.id) { cid = nc.id; setClienti && setClienti(prev => [...(prev||[]), nc]); }
      }

      // 2) opportunità
      const opp = await window.DataAPI.insert('opportunities', {
        cliente_id: cid || null,
        cliente: clienteName.trim(),
        stage_id: stageId,
        commerciale_id: commId || currentUser?.id || null,
        note: note.trim() || null,
      });
      if (!opp?.id) throw new Error('creazione opportunità fallita');
      try { await window.DataAPI.insert('opportunity_stage_history', { opportunity_id: opp.id, to_stage_id: stageId, changed_by: currentUser?.id||null }); } catch(e){}

      // 3) macchine
      const commNome = (users||[]).find(u=>u.id===(commId||currentUser?.id))?.nome || currentUser?.nome || '';
      for (const r of righe) {
        if (r.source === 'catalogo' && r.prodId) {
          // crea una vera prenotazione collegata all'opportunità
          const bid = 'PR-' + Math.floor(1000+Math.random()*9000);
          const row = {
            id: bid, product_id: r.prodId, cliente: clienteName.trim(), cliente_id: cid || null,
            commerciale_id: commId || currentUser?.id || null, commerciale_nome: commNome,
            tipo: r.tipo,
            data_inizio: r.inizio || new Date().toISOString().slice(0,10),
            data_fine: r.fine || new Date(Date.now()+30*86400000).toISOString().slice(0,10),
            status: 'attiva',
            prezzo_pattuito: r.prezzo!=='' ? Number(r.prezzo) : null,
          };
          await window.DataAPI.insert('bookings', row);
          await window.DataAPI.insert('opportunity_bookings', { opportunity_id: opp.id, booking_id: bid });
          try { await window.DataAPI.update('products', r.prodId, { status: 'PRENOTATO' }); } catch(e){ console.error('stato prodotto', e); }
        } else if (r.source === 'casamadre') {
          // macchina nuova dalla casa madre: crea/riusa il modello e collega con i dati
          let dmId = r.desiredId;
          if (!dmId) {
            const dm = await window.DataAPI.createDesiredMachine(r.desiredNome, currentUser?.id);
            dmId = dm?.id;
          }
          if (dmId) {
            // aggiorna categoria/sottocategoria del modello se indicate
            if (r.catId || r.sub) {
              try { await window.DataAPI.update('desired_machines', dmId, { category_id: r.catId || null, sottocategoria: r.sub || null }); } catch(e){}
            }
            await window.DataAPI.insert('opportunity_desired_machines', {
              opportunity_id: opp.id, desired_machine_id: dmId,
              tipo: r.tipo, prezzo: r.prezzo!=='' ? Number(r.prezzo) : null,
              data_inizio: isNol(r.tipo) && r.inizio ? r.inizio : null,
              data_fine:   isNol(r.tipo) && r.fine   ? r.fine   : null,
            });
          }
        }
      }

      window.LogAPI?.logEvent('opportunity.created', {
        entity_type:'opportunity', entity_id: opp.id, title:'Opportunità creata',
        description:`${clienteName.trim()}${righe.length?` · ${righe.length} macchina/e`:''}`,
        metadata:{ cliente: clienteName.trim(), commerciale_id: commId||currentUser?.id, n_macchine: righe.length },
      });
      toast('Opportunità creata');
      onCreated && onCreated();
    } catch(e){ console.error('create opp', e); toast('Errore creazione: '+(e?.message||'')); setSaving(false); }
  };

  const noMatch = clienteName.trim().length>=2 && !clienteId && results.length===0;

  return (
    <ModalShell onClose={onClose} width={640} title="Nuova opportunità" subtitle="Crea una trattativa con cliente e macchine">
      <div className="scroll" style={{ display:'flex', flexDirection:'column', gap:16, maxHeight:'68vh', overflowY:'auto', paddingRight:2 }}>
        {/* ---- CLIENTE ---- */}
        <div style={{ position:'relative' }}>
          <Field label="Cliente" required>
            <input value={clienteName} onChange={e=>onClienteChange(e.target.value)} placeholder="Cerca o scrivi il nome…" style={inputStyle} autoFocus />
          </Field>
          {showResults && results.length>0 && (
            <div style={{ position:'absolute', top:'100%', left:0, right:0, zIndex:30, background:'var(--surface)', border:'1px solid var(--line)',
              borderRadius:'var(--r-md)', boxShadow:'var(--sh-2)', maxHeight:200, overflowY:'auto', marginTop:2 }}>
              {results.map(c => (
                <button key={c.id} onClick={()=>pickCliente(c)} style={{ display:'block', width:'100%', textAlign:'left', padding:'9px 13px', fontSize:13.5, borderBottom:'1px solid var(--line-2)' }}>
                  {c.ragione_sociale}
                </button>
              ))}
            </div>
          )}
          {clienteId && <div style={{ fontSize:11.5, color:'var(--st-disponibile)', fontWeight:700, marginTop:5 }}>✓ Cliente esistente selezionato</div>}
          {/* cliente non trovato → offri di crearlo */}
          {noMatch && !nuovoCliente && (
            <button onClick={()=>setNuovoCliente(true)}
              style={{ display:'inline-flex', alignItems:'center', gap:6, marginTop:7, padding:'7px 12px', borderRadius:'var(--r-md)',
                border:'1.5px dashed var(--red)', background:'var(--red-tint)', color:'var(--red)', fontSize:12.5, fontWeight:700 }}>
              <Icon name="plus" size={14} /> Crea "{clienteName.trim()}" come nuovo cliente
            </button>
          )}
          {nuovoCliente && (
            <div style={{ marginTop:10, padding:'12px 13px', background:'var(--surface-2)', border:'1px solid var(--line)', borderRadius:'var(--r-md)' }}>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:10 }}>
                <span style={{ fontSize:12, fontWeight:800, color:'var(--red)' }}>Nuovo cliente in anagrafica</span>
                <button onClick={()=>setNuovoCliente(false)} style={{ color:'var(--ink-4)', padding:3 }}><Icon name="x" size={14} /></button>
              </div>
              <div style={{ display:'grid', gridTemplateColumns: vp.isMobile?'1fr':'1fr 1fr', gap:10 }}>
                <Field label="Zona">
                  <div style={{ position:'relative' }}>
                    <select value={nzona} onChange={e=>setNzona(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:30 }}>
                      <option value="">—</option>
                      {(zone||[]).map(z=><option key={z.id} value={z.id}>{z.nome}</option>)}
                    </select>
                    <Icon name="chevDown" size={15} style={{ position:'absolute', right:10, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
                  </div>
                </Field>
                <Field label="Categoria">
                  <div style={{ position:'relative' }}>
                    <select value={ncat} onChange={e=>setNcat(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:30 }}>
                      <option value="">—</option>
                      {(clienteCat||[]).map(c=><option key={c.id} value={c.id}>{c.nome}</option>)}
                    </select>
                    <Icon name="chevDown" size={15} style={{ position:'absolute', right:10, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
                  </div>
                </Field>
              </div>
            </div>
          )}
        </div>

        {/* ---- FASE / COMMERCIALE ---- */}
        <div style={{ display:'grid', gridTemplateColumns: vp.isMobile?'1fr':'1fr 1fr', gap:12 }}>
          <Field label="Fase iniziale" required>
            <div style={{ position:'relative' }}>
              <select value={stageId} onChange={e=>setStageId(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:34 }}>
                {(stages||[]).filter(s=>s.active).sort((a,b)=>(a.sort_order||0)-(b.sort_order||0)).map(s=><option key={s.id} value={s.id}>{s.nome} · {s.percent}%</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>
          {isManager && (
            <Field label="Commerciale">
              <div style={{ position:'relative' }}>
                <select value={commId} onChange={e=>setCommId(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:34 }}>
                  <option value="">— Assegna a me —</option>
                  {(users||[]).map(u=><option key={u.id} value={u.id}>{u.nome}{u.role&&u.role!=='commerciale'?' ('+u.role+')':''}</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>

        {/* ---- MACCHINE ---- */}
        <div style={{ borderTop:'1px solid var(--line)', paddingTop:14 }}>
          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:10, flexWrap:'wrap', gap:8 }}>
            <SectionLabel>Macchine ({righe.length})</SectionLabel>
            <div style={{ display:'flex', gap:8 }}>
              <Btn size="sm" variant="ghost" icon="forklift" onClick={()=>setPickerOpen(pickerOpen==='catalogo'?null:'catalogo')}>Da catalogo</Btn>
              <Btn size="sm" variant="ghost" icon="boxes" onClick={()=>setPickerOpen(pickerOpen==='casamadre'?null:'casamadre')}>Da casa madre</Btn>
            </div>
          </div>

          {pickerOpen==='catalogo' && (
            <CatalogPicker products={products} onPick={(p)=>addRiga({ source:'catalogo', prodId:p.id, label: prodLabel(p) })} onClose={()=>setPickerOpen(null)} />
          )}
          {pickerOpen==='casamadre' && (
            <div style={{ marginBottom:12 }}>
              <DesiredMachineField currentUser={currentUser}
                onAdd={(m)=>addRiga({ source:'casamadre', desiredId:m.id, desiredNome:m.nome, label:m.nome, catId:m.category_id||'', sub:m.sottocategoria||'' })} />
            </div>
          )}

          {righe.length===0 ? (
            <div style={{ fontSize:12.5, color:'var(--ink-4)', padding:'10px 0' }}>Nessuna macchina. Puoi aggiungerle ora o più tardi dall'opportunità.</div>
          ) : (
            <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
              {righe.map(r => (
                <RigaMacchina key={r.key} r={r} vp={vp} attributi={attributi}
                  onUpd={(p)=>updRiga(r.key,p)} onDel={()=>delRiga(r.key)} />
              ))}
            </div>
          )}
        </div>

        <Field label="Note (opzionale)">
          <textarea value={note} onChange={e=>setNote(e.target.value)} placeholder="Prime annotazioni…" style={{ ...inputStyle, minHeight:60, resize:'vertical', fontFamily:'inherit' }} />
        </Field>
      </div>
      <div style={{ display:'flex', gap:12, marginTop:18 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={submit} disabled={!valid || saving}>{saving?'Creazione…':'Crea opportunità'}</Btn>
      </div>
    </ModalShell>
  );
}

/* Riga macchina dentro la creazione opportunità */
function RigaMacchina({ r, vp, attributi, onUpd, onDel }) {
  const isNol = r.tipo==='STR' || r.tipo==='LTR' || r.tipo==='Tampone';
  const isCasaMadre = r.source==='casamadre';
  // LTR da casa madre: date facoltative (tempi di ordine e consegna ancora ignoti)
  const dateOpz = isCasaMadre && r.tipo==='LTR';
  // sottocategorie: attributo "rilievo" della categoria scelta
  const subAttr = isCasaMadre && r.catId
    ? (attributi||[]).find(a => a.rilievo && Array.isArray(a.tipi) && a.tipi.includes(r.catId))
    : null;

  return (
    <div style={{ padding:'12px 13px', background:'var(--surface-2)', border:'1px solid var(--line)', borderRadius:'var(--r-md)' }}>
      <div style={{ display:'flex', alignItems:'center', gap:9, marginBottom:10 }}>
        <Icon name={isCasaMadre?'boxes':'forklift'} size={16} style={{ color: isCasaMadre?'var(--ink-3)':'var(--red)', flexShrink:0 }} />
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontSize:13, fontWeight:700, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{r.label}</div>
          <div style={{ fontSize:10.5, color:'var(--ink-4)', fontWeight:700, textTransform:'uppercase', letterSpacing:'.03em' }}>
            {isCasaMadre?'Nuova · casa madre':'Dal catalogo'}
          </div>
        </div>
        <button onClick={onDel} title="Rimuovi" style={{ color:'var(--red)', padding:5, flexShrink:0 }}><Icon name="x" size={15} /></button>
      </div>

      <div style={{ display:'grid', gridTemplateColumns: vp.isMobile?'1fr 1fr':'repeat(4,1fr)', gap:9 }}>
        {/* tipo contratto */}
        <Field label="Contratto" required>
          <div style={{ position:'relative' }}>
            <select value={r.tipo} onChange={e=>onUpd({ tipo:e.target.value })} style={{ ...inputStyle, appearance:'none', paddingRight:28, fontSize:12.5 }}>
              {['Vendita','STR','LTR','Prova','Tampone'].map(t=><option key={t} value={t}>{t==='STR'?'Nol. breve':t==='LTR'?'Nol. lungo':t}</option>)}
            </select>
            <Icon name="chevDown" size={14} style={{ position:'absolute', right:9, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
          </div>
        </Field>

        {/* categoria + sottocategoria solo per casa madre */}
        {isCasaMadre && (
          <Field label="Categoria">
            <div style={{ position:'relative' }}>
              <select value={r.catId||''} onChange={e=>onUpd({ catId:e.target.value, sub:'' })} style={{ ...inputStyle, appearance:'none', paddingRight:28, fontSize:12.5 }}>
                <option value="">—</option>
                {(typeof CATEGORIE!=='undefined'?CATEGORIE:[]).map(c=><option key={c.id} value={c.id}>{c.nome}</option>)}
              </select>
              <Icon name="chevDown" size={14} style={{ position:'absolute', right:9, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
            </div>
          </Field>
        )}
        {isCasaMadre && subAttr && (
          <Field label={subAttr.nome}>
            <div style={{ position:'relative' }}>
              <select value={r.sub||''} onChange={e=>onUpd({ sub:e.target.value })} style={{ ...inputStyle, appearance:'none', paddingRight:28, fontSize:12.5 }}>
                <option value="">—</option>
                {(subAttr.termini||[]).map(t=><option key={t} value={t}>{t}</option>)}
              </select>
              <Icon name="chevDown" size={14} style={{ position:'absolute', right:9, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', pointerEvents:'none' }} />
            </div>
          </Field>
        )}

        {/* prezzo */}
        <Field label={isNol?'Prezzo (€/mese)':'Prezzo (€)'}>
          <input type="number" value={r.prezzo} onChange={e=>onUpd({ prezzo:e.target.value })} placeholder="0" style={{ ...inputStyle, fontSize:12.5 }} />
        </Field>

        {/* date per noleggio */}
        {isNol && (
          <>
            <Field label={dateOpz?'Dal (facolt.)':'Dal'} required={!dateOpz}>
              <input type="date" value={r.inizio} onChange={e=>onUpd({ inizio:e.target.value })} style={{ ...inputStyle, fontSize:12.5 }} />
            </Field>
            <Field label={dateOpz?'Al (facolt.)':'Al'} required={!dateOpz}>
              <input type="date" value={r.fine} onChange={e=>onUpd({ fine:e.target.value })} style={{ ...inputStyle, fontSize:12.5 }} />
            </Field>
          </>
        )}
      </div>
      {isNol && (!r.inizio || !r.fine) && (
        dateOpz
          ? <div style={{ fontSize:11, color:'var(--ink-4)', marginTop:7 }}>Date facoltative: per un noleggio lungo da casa madre puoi compilarle più avanti, quando si conoscono i tempi di ordine e consegna.</div>
          : <div style={{ fontSize:11, color:'var(--red)', fontWeight:600, marginTop:7 }}>Per i noleggi servono data di inizio e fine</div>
      )}
    </div>
  );
}

/* Selettore macchina dal catalogo (solo mezzi disponibili) */
function CatalogPicker({ products, onPick, onClose }) {
  const [q, setQ] = useState('');
  const disponibili = (products||[]).filter(p => ['DISPONIBILE','IN_ARRIVO','DA_VERIFICARE'].includes(p.stato));
  const filtered = q.trim()
    ? disponibili.filter(p => (prodLabel(p)+' '+(p.matricola||'')).toLowerCase().includes(q.trim().toLowerCase())).slice(0,40)
    : disponibili.slice(0,40);
  return (
    <div style={{ marginBottom:12, border:'1px solid var(--line)', borderRadius:'var(--r-md)', overflow:'hidden' }}>
      <div style={{ position:'relative', borderBottom:'1px solid var(--line-2)' }}>
        <Icon name="search" size={16} 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 nel catalogo (modello o matricola)…" autoFocus
          style={{ width:'100%', padding:'10px 12px 10px 38px', fontSize:13, border:'none', outline:'none', background:'var(--surface)' }} />
      </div>
      <div className="scroll" style={{ maxHeight:190, overflowY:'auto', background:'var(--surface)' }}>
        {filtered.length===0 ? (
          <div style={{ padding:'14px', fontSize:12.5, color:'var(--ink-4)' }}>Nessun mezzo disponibile trovato</div>
        ) : filtered.map(p => (
          <button key={p.id} onClick={()=>onPick(p)}
            style={{ display:'flex', alignItems:'center', gap:9, width:'100%', textAlign:'left', padding:'9px 13px', borderBottom:'1px solid var(--line-2)', fontSize:13 }}>
            <Icon name="forklift" size={15} style={{ color:'var(--ink-3)', flexShrink:0 }} />
            <span style={{ flex:1, minWidth:0, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{prodLabel(p)}</span>
            {p.matricola && <span style={{ fontSize:11, color:'var(--ink-4)', flexShrink:0 }}>{p.matricola}</span>}
          </button>
        ))}
      </div>
    </div>
  );
}

/* piccolo helper label sezione */
function SectionLabel({ children }) {
  return <div style={{ fontSize:11.5, fontWeight:800, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.04em', marginBottom:8 }}>{children}</div>;
}

/* Modal: liberazione dell'ultima macchina di un'opportunità (dalla scheda prenotazione) */
function FreeLastMachineModal({ booking, opportunity, onClose, onChoose }) {
  return (
    <ModalShell onClose={onClose} width={440} title="Ultima macchina della trattativa"
      subtitle="Questa è l'unica macchina collegata all'opportunità">
      <div style={{ fontSize:13.5, color:'var(--ink-2)', lineHeight:1.5, marginBottom:18 }}>
        Liberando <b>{booking.prodLabel}</b> l'opportunità <b>{opportunity.cliente||''}</b> resterà senza macchine.
        Vuoi chiudere l'opportunità come <b>persa</b> oppure tenerla aperta (tornerà in "Lead" e potrai ricollegare altre macchine)?
      </div>
      <div style={{ display:'flex', flexDirection:'column', gap:9 }}>
        <Btn full icon="x" onClick={()=>onChoose('perso')}>Libera e chiudi come persa</Btn>
        <Btn full variant="ghost" onClick={()=>onChoose('aperta')}>Libera e tieni aperta</Btn>
        <Btn full variant="ghost" onClick={onClose}>Annulla</Btn>
      </div>
    </ModalShell>
  );
}

/* Dati contratto per una macchina desiderata (casa madre) */
function DesiredDataModal({ machine, onClose, onSave }) {
  const [tipo, setTipo] = useState('Vendita');
  const [prezzo, setPrezzo] = useState('');
  const [inizio, setInizio] = useState('');
  const [fine, setFine] = useState('');
  const isNol = tipo==='STR' || tipo==='LTR' || tipo==='Tampone';
  // LTR da casa madre: date facoltative
  const dateOpz = tipo==='LTR';
  const valid = !isNol || dateOpz || (inizio && fine);

  return (
    <ModalShell onClose={onClose} width={460} title="Dati della macchina" subtitle={machine.nome}>
      <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
        <Field label="Tipo di contratto" required>
          <div style={{ position:'relative' }}>
            <select value={tipo} onChange={e=>setTipo(e.target.value)} style={{ ...inputStyle, appearance:'none', paddingRight:34 }}>
              {['Vendita','STR','LTR','Prova','Tampone'].map(t=><option key={t} value={t}>{t==='STR'?'Noleggio breve (STR)':t==='LTR'?'Noleggio lungo (LTR)':t}</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>
        <Field label={isNol?'Prezzo (€/mese)':'Prezzo (€)'}>
          <input type="number" value={prezzo} onChange={e=>setPrezzo(e.target.value)} placeholder="0" style={inputStyle} />
        </Field>
        {isNol && (
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 }}>
            <Field label={dateOpz?'Dal (facolt.)':'Dal'} required={!dateOpz}>
              <input type="date" value={inizio} onChange={e=>setInizio(e.target.value)} style={inputStyle} />
            </Field>
            <Field label={dateOpz?'Al (facolt.)':'Al'} required={!dateOpz}>
              <input type="date" value={fine} onChange={e=>setFine(e.target.value)} style={inputStyle} />
            </Field>
          </div>
        )}
        {isNol && dateOpz && (!inizio || !fine) && (
          <div style={{ fontSize:11.5, color:'var(--ink-4)', lineHeight:1.5 }}>
            Per un noleggio lungo da casa madre le date sono facoltative: potrai compilarle più avanti, quando si conoscono i tempi di ordine e di consegna.
          </div>
        )}
      </div>
      <div style={{ display:'flex', gap:12, marginTop:20 }}>
        <Btn variant="ghost" full onClick={onClose}>Annulla</Btn>
        <Btn full icon="check" onClick={()=>onSave({ tipo, prezzo, inizio, fine })} disabled={!valid}>Aggiungi</Btn>
      </div>
    </ModalShell>
  );
}

Object.assign(window, { OpportunityDetail, OpportunityNewModal, DesiredDataModal, DesiredMachineField, ConfirmMachinesModal, FreeLastMachineModal, RigaMacchina, CatalogPicker });