// Vival PWA — Extensions: PIN login, pinned products, delivery screen, register
// This file assumes primitives + data.js + app.jsx globals exist.

// ===== PIN Login =====
window.PinLogin = function PinLogin({ onSuccess }) {
  const [pin, setPin] = useState('');
  const [error, setError] = useState(false);
  const [users, setUsers] = useState([]);
  const [selected, setSelected] = useState(null);
  const [loading, setLoading] = useState(true);
  const [storeName, setStoreName] = useState('');
  const FALLBACK = localStorage.getItem('vival_pin') || '1234';

  useEffect(() => {
    (async () => {
      try {
        const storeId = await window.resolveCurrentStore();
        const [usersRes, storeRes] = await Promise.all([
          window.sb.from('users').select('id, name, role').eq('active', true).eq('store_id', storeId).order('name'),
          window.sb.from('stores').select('name').eq('id', storeId).maybeSingle(),
        ]);
        setUsers(usersRes.data || []);
        setStoreName(storeRes.data?.name || 'Vival');
      } catch {}
      setLoading(false);
    })();
  }, []);

  const validate = (code) => {
    if (selected) {
      // Login as selected user — PIN must match this user's
      window.sb.from('users').select('*').eq('id', selected.id).single().then(({ data }) => {
        if (data && data.pin === code) {
          sessionStorage.setItem('vival_cashier', JSON.stringify({ id: data.id, name: data.name, role: data.role }));
          setTimeout(() => onSuccess(), 200);
        } else {
          setError(true);
          setTimeout(() => { setPin(''); setError(false); }, 500);
        }
      });
    } else if (code === FALLBACK) {
      sessionStorage.setItem('vival_cashier', JSON.stringify({ id: null, name: 'Gérant', role: 'admin' }));
      setTimeout(() => onSuccess(), 200);
    } else {
      setError(true);
      setTimeout(() => { setPin(''); setError(false); }, 500);
    }
  };

  const add = (d) => {
    if (pin.length >= 4) return;
    const next = pin + d;
    setPin(next);
    if (next.length === 4) validate(next);
  };
  const del = () => setPin(pin.slice(0, -1));

  const roleLabel = (r) => r === 'admin' ? 'Administrateur' : r === 'livreur' ? 'Livreur' : 'Caissier';
  const roleBg = (r) => r === 'admin' ? '#dc2626' : r === 'livreur' ? '#0891b2' : '#ea580c';

  // User picker screen
  if (!selected && users.length > 0) {
    return (
      <div className="pin-screen">
        <div className="pin-card" style={{maxWidth:420}}>
          <div className="pin-logo"><img src="assets/vival-logo.png" alt="Vival" /></div>
          <h1 className="pin-title">Qui êtes-vous ?</h1>
          <p className="pin-subtitle">Sélectionnez votre profil</p>
          <div style={{display:'grid', gap:8, marginTop:20}}>
            {users.map(u => (
              <button key={u.id} onClick={() => setSelected(u)}
                style={{display:'flex', alignItems:'center', gap:12, padding:'12px 14px', background:'var(--surface-1)', border:'1px solid var(--line-2)', borderRadius:12, cursor:'pointer', textAlign:'left'}}>
                <div style={{width:40, height:40, borderRadius:'50%', background: roleBg(u.role), color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontWeight:700, fontSize:16}}>{u.name[0]?.toUpperCase()}</div>
                <div style={{flex:1}}>
                  <div style={{fontWeight:700}}>{u.name}</div>
                  <div className="muted" style={{fontSize:12}}>{roleLabel(u.role)}</div>
                </div>
                <Icon name="chevron-right" style={{color:'var(--ink-3)'}} />
              </button>
            ))}
            <button onClick={() => setSelected({ _fallback: true, name: 'Gérant (PIN global)', role: 'admin' })}
              style={{display:'flex', alignItems:'center', gap:12, padding:'12px 14px', background:'transparent', border:'1px dashed var(--line-2)', borderRadius:12, cursor:'pointer', textAlign:'left', marginTop:4}}>
              <Icon name="lock" style={{color:'var(--ink-3)'}} />
              <div style={{flex:1}}>
                <div style={{fontWeight:600, fontSize:14}}>Autre (PIN gérant)</div>
                <div className="muted" style={{fontSize:11}}>Accès avec le code global</div>
              </div>
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="pin-screen">
      <div className="pin-card">
        <div className="pin-logo"><img src="assets/vival-logo.png" alt="Vival" /></div>
        {selected ? (
          <>
            <h1 className="pin-title">{selected.name}</h1>
            <p className="pin-subtitle">{roleLabel(selected.role)} · Code à 4 chiffres</p>
          </>
        ) : (
          <>
            <h1 className="pin-title">{storeName || 'Vival'}</h1>
            <p className="pin-subtitle">Code à 4 chiffres</p>
          </>
        )}
        <div className="pin-dots">
          {[0,1,2,3].map(i => (
            <div key={i} className={`pin-dot ${i < pin.length ? 'filled' : ''} ${error ? 'error' : ''}`}></div>
          ))}
        </div>
        <div className="pin-grid">
          {[1,2,3,4,5,6,7,8,9].map(n => (
            <button key={n} className="pin-key" onClick={() => add(String(n))}>{n}</button>
          ))}
          {selected
            ? <button className="pin-key action" onClick={() => { setSelected(null); setPin(''); }}>Retour</button>
            : <span className="pin-key" style={{visibility:'hidden'}} />}
          <button className="pin-key" onClick={() => add('0')}>0</button>
          <button className="pin-key action" onClick={del} aria-label="Effacer">
            <Icon name="close" />
          </button>
        </div>
      </div>
    </div>
  );
};

// ===== Pinned products row =====
window.PinnedRow = function PinnedRow({ onAdd }) {
  const pinned = VivalData.PRODUCTS.filter(p => p.pinned && p.stock > 0);
  if (pinned.length === 0) return null;
  return (
    <div className="pinned-section">
      <h3 className="pinned-title"><Icon name="star" style={{width:13,height:13,color:'var(--warning)'}}/> Produits épinglés — accès rapide</h3>
      <div className="pinned-row">
        {pinned.map(p => (
          <button key={p.id} className="pin-chip" onClick={() => onAdd(p.id)}>
            <div className="pin-chip-thumb"><Icon name={p.rayon} /></div>
            <div>
              <div className="pin-chip-name">{p.name}</div>
              <div className="pin-chip-price">{formatPrice(p.price).full}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
};

// ===== Delivery screen =====
window.DeliveryScreen = function DeliveryScreen() {
  const { orders, setOrders, setSelectedOrder, showToast } = useApp();
  const [signing, setSigning] = useState(null);
  const deliveries = orders.filter(o => o.status === 'prete' || o.status === 'en-cours');

  const markDelivered = async (o, signatureDataUrl) => {
    const updated = { ...o, status: 'livree', signature: signatureDataUrl, deliveredAt: new Date().toISOString() };
    setOrders(orders.map(x => x.id === o.id ? updated : x));
    try {
      const { error } = await window.sb.from('orders').update({
        status: 'livree',
        signature: signatureDataUrl || null,
        delivered_at: new Date().toISOString(),
      }).eq('id', o.id);
      if (error) throw error;
      showToast('Commande marquée livrée');
    } catch (e) {
      showToast('Erreur sync : ' + (e.message || e));
    }
  };

  const openItinerary = () => {
    const addresses = deliveries.map(o => {
      const c = VivalData.CUSTOMERS.find(x => x.id === o.customerId);
      return c?.address;
    }).filter(Boolean);
    if (!addresses.length) { showToast('Aucune adresse client'); return; }
    const url = addresses.length === 1
      ? `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(addresses[0])}`
      : `https://www.google.com/maps/dir/${addresses.map(encodeURIComponent).join('/')}`;
    window.open(url, '_blank', 'noopener');
  };

  return (
    <>
      <div className="page-header">
        <div className="page-header-grow">
          <h1 className="page-title">Tournée de livraison</h1>
          <p className="page-subtitle">{deliveries.length} commande{deliveries.length>1?'s':''} à livrer</p>
        </div>
        <Button variant="outline" icon="map-pin" onClick={openItinerary}>Itinéraire optimisé</Button>
      </div>

      <div style={{padding:'0 32px 32px'}}>
        {deliveries.length === 0 ? (
          <div className="empty-state">
            <Icon name="truck" />
            <div className="cart-empty-title">Aucune livraison en attente</div>
            <div style={{fontSize:13}}>Les commandes prêtes apparaîtront ici</div>
          </div>
        ) : deliveries.map((o, idx) => {
          const c = VivalData.CUSTOMERS.find(x => x.id === o.customerId);
          const total = o.lines.reduce((s, l) => {
            const p = VivalData.PRODUCTS.find(x => x.id === l.pid);
            return s + (p ? p.price * l.qty : 0);
          }, 0);
          return (
            <div key={o.id} className="delivery-card">
              <div className="delivery-order-num">{idx + 1}</div>
              <div className="delivery-info">
                <div className="delivery-name">{c?.name || 'Client libre'}</div>
                <div className="delivery-address"><Icon name="map-pin" style={{width:14,height:14}} /> {c?.address || '—'}</div>
                {c?.notes && <div className="delivery-notes">⚑ {c.notes}</div>}
                <div className="delivery-meta">{o.id} · {o.lines.length} articles · {formatPrice(total).full} · {o.payment}</div>
              </div>
              <div className="delivery-actions">
                <Button variant="primary" size="sm" icon="check" onClick={() => setSigning(o)}>Livrée</Button>
                <Button variant="outline" size="sm" icon="phone" disabled={!c?.phone} onClick={() => c?.phone && (window.location.href = `tel:${c.phone.replace(/\s/g, '')}`)}>Appeler</Button>
                <Button variant="ghost" size="sm" onClick={() => setSelectedOrder(o)}>Détail</Button>
              </div>
            </div>
          );
        })}
      </div>
      {signing && <SignatureModal order={signing} onClose={() => setSigning(null)} onSigned={(sig) => { markDelivered(signing, sig); setSigning(null); }} />}
    </>
  );
};

// ===== Signature pad =====
window.SignatureModal = function SignatureModal({ order, onClose, onSigned }) {
  const canvasRef = useRef(null);
  const drawing = useRef(false);
  const last = useRef({x:0, y:0});
  const [hasInk, setHasInk] = useState(false);

  useEffect(() => {
    const c = canvasRef.current;
    if (!c) return;
    const rect = c.getBoundingClientRect();
    c.width = rect.width * 2;
    c.height = rect.height * 2;
    const ctx = c.getContext('2d');
    ctx.scale(2, 2);
    ctx.strokeStyle = '#111';
    ctx.lineWidth = 2;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
  }, []);

  const pos = (e) => {
    const c = canvasRef.current;
    const rect = c.getBoundingClientRect();
    const t = e.touches ? e.touches[0] : e;
    return { x: t.clientX - rect.left, y: t.clientY - rect.top };
  };
  const start = (e) => { e.preventDefault(); drawing.current = true; last.current = pos(e); };
  const move = (e) => {
    if (!drawing.current) return;
    e.preventDefault();
    const p = pos(e);
    const ctx = canvasRef.current.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(last.current.x, last.current.y);
    ctx.lineTo(p.x, p.y);
    ctx.stroke();
    last.current = p;
    setHasInk(true);
  };
  const end = () => { drawing.current = false; };
  const clear = () => {
    const c = canvasRef.current;
    c.getContext('2d').clearRect(0, 0, c.width, c.height);
    setHasInk(false);
  };
  const validate = () => {
    const dataUrl = hasInk ? canvasRef.current.toDataURL('image/png') : null;
    onSigned(dataUrl);
  };

  return (
    <Modal open={true} onClose={onClose} title={`Preuve de livraison · ${order.id}`}
      footer={<>
        <Button variant="ghost" onClick={onClose}>Annuler</Button>
        <Button variant="outline" onClick={clear} disabled={!hasInk}>Effacer</Button>
        <Button variant="primary" icon="check" onClick={validate}>{hasInk ? 'Valider livraison' : 'Livrer sans signature'}</Button>
      </>}>
      <p className="muted" style={{marginTop:0}}>Faites signer le client ci-dessous (souris ou doigt).</p>
      <div style={{border:'1px dashed var(--line-2)', borderRadius:'var(--r-md)', background:'#fff', touchAction:'none'}}>
        <canvas ref={canvasRef}
          style={{width:'100%', height:200, display:'block', cursor:'crosshair'}}
          onMouseDown={start} onMouseMove={move} onMouseUp={end} onMouseLeave={end}
          onTouchStart={start} onTouchMove={move} onTouchEnd={end} />
      </div>
    </Modal>
  );
};

// ===== Register open/close =====
window.RegisterModal = function RegisterModal({ open, onClose, mode, orders }) {
  const [fund, setFund] = useState('');
  const [counted, setCounted] = useState('');
  const [session, setSession] = useState(null);
  const { showToast } = useApp();

  useEffect(() => {
    if (!open) return;
    (async () => {
      const { data } = await window.sb.from('register_sessions').select('*').eq('store_id', VivalData._storeId).is('closed_at', null).order('opened_at', {ascending:false}).limit(1).maybeSingle();
      setSession(data || null);
    })();
  }, [open]);

  if (!open) return null;

  const todaySales = orders.filter(o => o.status === 'payee' && new Date(o.createdAt).toDateString() === new Date().toDateString());
  const sumPayment = (method) => todaySales.filter(o => o.payment === method).reduce((s,o) => s + (o.totalTtc || 0), 0);
  const cash = sumPayment('espèces');
  const card = sumPayment('CB');
  const openingFund = Number(session?.opening_fund || 0);
  const expectedCash = openingFund + cash;
  const countedNum = Number((counted || '').toString().replace(',', '.')) || 0;
  const delta = counted ? countedNum - expectedCash : 0;

  const cashier = (() => { try { return JSON.parse(sessionStorage.getItem('vival_cashier') || 'null'); } catch { return null; } })();
  const doOpen = async () => {
    const f = Number((fund || '').toString().replace(',', '.')) || 0;
    const { error } = await window.sb.from('register_sessions').insert({
      opening_fund: f,
      cashier_id: cashier?.id || null,
      cashier_name: cashier?.name || null,
      store_id: VivalData._storeId,
    });
    if (error) { showToast('Erreur: ' + error.message); return; }
    showToast(`Caisse ouverte · fond ${formatPrice(f).full}`);
    onClose();
  };
  const doClose = async () => {
    if (!session) { showToast('Aucune caisse ouverte'); return; }
    const { error } = await window.sb.from('register_sessions').update({
      closed_at: new Date().toISOString(),
      counted_cash: countedNum,
      cash_sales: cash,
      card_sales: card,
      delta,
      tickets_count: todaySales.length,
    }).eq('id', session.id);
    if (error) { showToast('Erreur: ' + error.message); return; }
    showToast(`Caisse clôturée · écart ${formatPrice(delta).full}`);
    onClose();
  };

  return (
    <Modal open={true} onClose={onClose}
      title={mode === 'open' ? 'Ouverture de caisse' : 'Clôture de caisse (Z)'}
      footer={<><Button variant="ghost" onClick={onClose}>Annuler</Button>
        {mode === 'open'
          ? <Button variant="primary" icon="check" onClick={doOpen} disabled={!!session}>Ouvrir la caisse</Button>
          : <Button variant="primary" icon="check" onClick={doClose} disabled={!session || !counted}>Clôturer la journée</Button>}
      </>}>
      {mode === 'open' ? (
        session ? (
          <div className="card" style={{padding:16, background:'var(--warning-soft, #fff4e5)'}}>
            <strong>Caisse déjà ouverte</strong>
            <div className="muted" style={{fontSize:13, marginTop:4}}>Ouverte {new Date(session.opened_at).toLocaleString('fr-FR')} · Fond {formatPrice(session.opening_fund).full}</div>
          </div>
        ) : (
          <>
            <p className="muted" style={{marginTop:0}}>Saisis le fond de caisse de départ.</p>
            <Input size="lg" placeholder="Ex. 100,00" value={fund} onChange={e => setFund(e.target.value)} />
          </>
        )
      ) : (
        <div style={{display:'grid', gap:10}}>
          {!session && <div className="card" style={{padding:12, background:'var(--warning-soft, #fff4e5)', fontSize:13}}>⚠️ Aucune caisse ouverte — ouvrez-en une d'abord.</div>}
          <div className="card" style={{padding:16}}>
            <div style={{display:'flex', justifyContent:'space-between', padding:'4px 0'}}><span className="muted">Fond d'ouverture</span><strong>{formatPrice(openingFund).full}</strong></div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'4px 0'}}><span className="muted">Ventes espèces ({todaySales.filter(o => o.payment==='espèces').length})</span><strong>{formatPrice(cash).full}</strong></div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'4px 0'}}><span className="muted">Ventes CB ({todaySales.filter(o => o.payment==='CB').length})</span><strong>{formatPrice(card).full}</strong></div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderTop:'1px solid var(--line-2)', marginTop:6}}><span>Attendu en caisse</span><strong style={{fontSize:16}}>{formatPrice(expectedCash).full}</strong></div>
          </div>
          <div><div className="kpi-label" style={{marginBottom:4}}>Comptage des espèces réel</div>
            <Input size="lg" placeholder="Ex. 285,40" value={counted} onChange={e => setCounted(e.target.value)} /></div>
          {counted && (
            <div className="card" style={{padding:12, background: delta === 0 ? 'var(--success-soft)' : 'var(--warning-soft, #fff4e5)', display:'flex', justifyContent:'space-between'}}>
              <span>Écart</span>
              <strong style={{color: delta === 0 ? 'var(--success)' : 'var(--danger, #c02424)'}}>{delta > 0 ? '+' : ''}{formatPrice(delta).full}</strong>
            </div>
          )}
        </div>
      )}
    </Modal>
  );
};
