// MiPaghi storyboard app — orchestrates scenes inside an iPhone frame on a
// retail-context backdrop, with a left side panel narrating each scene.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#1E78C8",
  "showBackdrop": true,
  "showSidePanel": true
}/*EDITMODE-END*/;

// Scene flow — 9 scenes total
const SCENE_FLOW = [
  { id: 'intro',     short: 'Intro',         label: 'Camera live · introduzione' },
  { id: 'pick',      short: 'Scelta',        label: 'Scelta del prodotto' },
  { id: 'capture',   short: 'Foto+Prezzo',   label: 'Scatto, riconoscimento, prezzo' },
  { id: 'cart',      short: 'Carrello',      label: 'Aggiungi o concludi' },
  { id: 'checkout',  short: 'Checkout',      label: 'Consegna, sconto, totale' },
  { id: 'payment',   short: 'Pagamento',     label: 'Standard o BNPL' },
  { id: 'share',     short: 'Cliente+Link',  label: 'Dati cliente · invia link' },
  { id: 'customer',  short: 'Esp. Cliente',  label: 'Esperienza lato cliente' },
  { id: 'backoffice',short: 'Backoffice',    label: 'Dashboard ordini' },
];

const SIDE_COPY = {
  intro: {
    eyebrow: '01 · Contesto',
    title: 'Il punto vendita diventa un terminale d\u2019ordine.',
    body: 'In boutique, il cliente è interessato ma non davanti a un checkout. MiPaghi trasforma lo smartphone del venditore in uno strumento di acquisizione: scatta, prezza, condividi.',
  },
  pick: {
    eyebrow: '02 · Selezione',
    title: 'L\u2019assistente avvia l\u2019ordine con un tap.',
    body: 'Tre prodotti rappresentativi del catalogo. Ogni card è una riga ordine pronta ad essere acquisita: foto e prezzo digitati direttamente.',
  },
  capture: {
    eyebrow: '03 · Acquisizione',
    title: 'Foto, riconoscimento, prezzo manuale.',
    body: 'Niente catalogo da consultare. L\u2019assistente scatta una foto reale del prodotto in mano al cliente, riconosce l\u2019articolo via AI e digita il prezzo concordato.',
  },
  cart: {
    eyebrow: '04 · Carrello',
    title: 'L\u2019ordine si compone in tempo reale.',
    body: 'L\u2019assistente può aggiungere altri articoli senza interrompere la trattativa. Il totale è sempre visibile e tracciabile.',
  },
  checkout: {
    eyebrow: '05 · Checkout',
    title: 'Condizioni chiare, totale aggiornato.',
    body: 'Ritiro o spedizione (con costo digitato dall\u2019assistente), sconto in % o in valore. L\u2019accordo informale diventa una transazione strutturata.',
  },
  payment: {
    eyebrow: '06 · Pagamento',
    title: 'Il momento BNPL.',
    body: 'L\u2019ordine esiste, è strutturato, è digitale. Solo ora il pagamento rateale si innesta come scelta naturale del cliente, accanto a carta e bonifico.',
  },
  share: {
    eyebrow: '07 · Dati cliente · Link',
    title: 'L\u2019assistente compila e invia il link.',
    body: 'Dati anagrafici, generazione del link MiPaghi, scelta del canale di invio (WhatsApp, email, SMS).',
  },
  customer: {
    eyebrow: '08 · Esperienza cliente',
    title: 'Il cliente conferma dal proprio dispositivo.',
    body: 'Riceve il link, apre il riepilogo, paga. La conferma rimbalza in tempo reale sul backoffice.',
  },
  backoffice: {
    eyebrow: '09 · Backoffice',
    title: 'L\u2019ordine entra nello storico.',
    body: 'Dashboard ordini, stati pagamento, performance per operatore. Niente CSV, niente fogli paralleli.',
  },
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [scene, setScene] = React.useState('intro');
  const [cart, setCart] = React.useState([]);
  const [pendingProduct, setPendingProduct] = React.useState(null);
  const [checkout, setCheckout] = React.useState({ delivery: null, shippingCost: 0, discount: 0, total: 0 });
  const [payment, setPayment] = React.useState(null);
  const [customer, setCustomer] = React.useState(null);
  const [channel, setChannel] = React.useState(null);

  const state = { scene, cart, pendingProduct, checkout, payment, customer, channel };

  const order = ['intro','pick','capture','cart','checkout','payment','share','customer','backoffice'];

  // Default state for direct scene jumps (so each scene is self-sufficient)
  const ensureDefaults = (target) => {
    const i = order.indexOf(target);
    let nextCart = cart, nextPending = pendingProduct, nextCheckout = checkout, nextPayment = payment, nextCustomer = customer, nextChannel = channel;

    // Capture needs a pending product
    if (target === 'capture' && !nextPending) {
      nextPending = 'bag';
      setPendingProduct('bag');
    }
    // Scenes from cart onward need a populated cart
    if (i >= order.indexOf('cart') && nextCart.length === 0) {
      nextCart = [
        { id: 'bag',  name: PRODUCTS.bag.name,  price: PRODUCTS.bag.price },
        { id: 'shoe', name: PRODUCTS.shoe.name, price: PRODUCTS.shoe.price },
      ];
      setCart(nextCart);
    }
    // Scenes from payment onward need a finalized checkout
    if (i >= order.indexOf('payment') && (!nextCheckout.delivery || nextCheckout.total === 0)) {
      const subtotal = nextCart.reduce((s, l) => s + l.price, 0);
      nextCheckout = { delivery: 'ship', shippingCost: 9.90, discount: 0, total: subtotal + 9.90 };
      setCheckout(nextCheckout);
    }
    // Scenes from share onward need a payment method
    if (i >= order.indexOf('share') && !nextPayment) {
      nextPayment = 'bnpl';
      setPayment('bnpl');
    }
    // Scenes from customer onward need customer + channel
    if (i >= order.indexOf('customer') && (!nextCustomer || !nextChannel)) {
      if (!nextCustomer) {
        nextCustomer = { first: 'Giulia', last: 'Bianchi', addr: 'Via Brera 12', city: 'Milano', cap: '20121', email: 'giulia.bianchi@email.it', phone: '+39 333 1234567' };
        setCustomer(nextCustomer);
      }
      if (!nextChannel) { nextChannel = 'wa'; setChannel('wa'); }
    }
  };

  const actions = {
    next: () => setScene('pick'),
    pickProduct: (id) => { setPendingProduct(id); setScene('capture'); },
    confirmPrice: (price, meta) => {
      const p = PRODUCTS[pendingProduct];
      setCart(c => [...c, { id: p.id, name: p.name, price, ...(meta || {}) }]);
      setPendingProduct(null);
      setScene('cart');
    },
    addAnother: () => setScene('pick'),
    toCart: () => setScene('cart'),
    toCheckout: () => setScene('checkout'),
    toPayment: (info) => { setCheckout(info); setScene('payment'); },
    toCustomerData: (method) => { setPayment(method); setScene('share'); },
    sendLink: (ch, cust) => { setChannel(ch); setCustomer(cust); setScene('customer'); },
    toBackoffice: () => setScene('backoffice'),
    back: () => {
      const i = order.indexOf(scene);
      if (i > 0) setScene(order[i - 1]);
    },
    restart: () => {
      setCart([]); setPendingProduct(null);
      setCheckout({ delivery: null, shippingCost: 0, discount: 0, total: 0 });
      setPayment(null); setCustomer(null); setChannel(null);
      setScene('intro');
    },
    jumpTo: (id) => { ensureDefaults(id); setScene(id); },
  };

  // Build the active scene component
  let SceneEl = null;
  switch (scene) {
    case 'intro':      SceneEl = <Scene0_Intro actions={actions}/>; break;
    case 'pick':       SceneEl = <Scene1_Pick state={state} actions={actions}/>; break;
    case 'capture':    SceneEl = <Scene2_Capture state={state} actions={actions}/>; break;
    case 'cart':       SceneEl = <Scene4_AddOrDone state={state} actions={actions}/>; break;
    case 'checkout':   SceneEl = <Scene6_Checkout state={state} actions={actions}/>; break;
    case 'payment':    SceneEl = <Scene9_Payment state={state} actions={actions}/>; break;
    case 'share':      SceneEl = <Scene7_Share state={state} actions={actions}/>; break;
    case 'customer':   SceneEl = <Scene8_Customer state={state} actions={actions}/>; break;
    case 'backoffice': SceneEl = <Scene9_Backoffice state={state} actions={actions}/>; break;
    default:           SceneEl = <Scene0_Intro actions={actions}/>;
  }

  const copy = SIDE_COPY[scene];
  const stepIndex = Math.max(0, SCENE_FLOW.findIndex(s => s.id === scene));
  const isCustomer = scene === 'customer';

  return (
    <div style={{
      width: '100vw', height: '100vh', position: 'relative',
      background: t.showBackdrop
        ? 'radial-gradient(1200px 600px at 20% 0%, #F2F7FC 0%, var(--cream) 60%)'
        : 'var(--cream)',
      display: 'grid',
      gridTemplateColumns: t.showSidePanel ? 'minmax(320px, 0.9fr) minmax(420px, 1fr)' : '1fr',
      overflow: 'hidden',
    }}>
      {t.showSidePanel && (() => {
        // Background swap based on scene index (1-based human numbering)
        // Scenes 6 (payment), 7 (share), 8 (customer) → customer POV
        // Scene 9 (backoffice) → manager at desk
        // Others → store interior
        const sceneNum = stepIndex + 1;
        const bgImage = sceneNum === 9 ? 'assets/manager-bg.jpg'
          : (sceneNum >= 6 && sceneNum <= 8) ? 'assets/customer-bg.jpg'
          : 'assets/store-bg.jpg';
        return (
        <aside style={{
          padding: '40px 48px 32px', display: 'flex', flexDirection: 'column',
          minWidth: 0, position: 'relative', overflow: 'hidden',
          color: '#fff',
          background: `
            linear-gradient(180deg, rgba(14,42,61,.78) 0%, rgba(14,42,61,.62) 35%, rgba(14,42,61,.78) 100%),
            url('${bgImage}') center / cover no-repeat
          `,
          transition: 'background-image .4s',
        }}>
          {/* Subtle vignette/overlay for legibility */}
          <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(135deg, rgba(14,42,61,.45), rgba(14,42,61,.0) 60%)', pointerEvents: 'none' }}/>
          <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(80% 50% at 30% 60%, rgba(0,0,0,.30), transparent 70%)', pointerEvents: 'none' }}/>

          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 'auto', position: 'relative', zIndex: 2 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <MiPaghiMark size={32}/>
              <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.1 }}>
                <span style={{ fontWeight: 800, fontSize: 16, letterSpacing: '-0.01em', color: '#fff' }}>MiPaghi</span>
                <span style={{ fontSize: 11, color: 'rgba(255,255,255,.65)', fontWeight: 600, letterSpacing: '.04em' }}>Vendita remota assistita</span>
              </div>
            </div>
            <div style={{
              padding: '6px 12px', borderRadius: 999,
              background: 'rgba(255,255,255,.14)', backdropFilter: 'blur(10px)',
              border: '1px solid rgba(255,255,255,.18)', fontSize: 11, fontWeight: 700, color: '#fff',
              fontVariantNumeric: 'tabular-nums',
            }}>
              {String(stepIndex + 1).padStart(2,'0')} / {String(SCENE_FLOW.length).padStart(2,'0')}
            </div>
          </div>

          <div key={scene} style={{ animation: 'fadeIn .35s ease both', maxWidth: 480, position: 'relative', zIndex: 2 }}>
            <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.16em', textTransform: 'uppercase', color: '#9FC5E8', marginBottom: 14 }}>
              {copy.eyebrow}
            </div>
            <h1 style={{
              margin: 0, fontSize: 'clamp(26px, 2.8vw, 38px)', fontWeight: 800,
              lineHeight: 1.1, letterSpacing: '-0.025em', color: '#fff',
              textWrap: 'balance', textShadow: '0 2px 24px rgba(0,0,0,.35)',
            }}>
              {copy.title}
            </h1>
            <p style={{
              margin: '18px 0 0', fontSize: 'clamp(13px, 1vw, 15px)', lineHeight: 1.55,
              color: 'rgba(255,255,255,.85)', fontWeight: 500, maxWidth: 440,
              textShadow: '0 1px 12px rgba(0,0,0,.30)',
            }}>
              {copy.body}
            </p>
          </div>

          <div style={{ marginTop: 36, position: 'relative', zIndex: 2 }}>
            <div style={{ display: 'flex', gap: 4, marginBottom: 14 }}>
              {SCENE_FLOW.map((s, i) => (
                <div key={s.id} style={{
                  flex: 1, height: 3, borderRadius: 2,
                  background: i <= stepIndex ? '#fff' : 'rgba(255,255,255,.18)',
                  transition: 'background .3s',
                }}/>
              ))}
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
              {SCENE_FLOW.map((s, i) => (
                <button key={s.id} onClick={() => actions.jumpTo(s.id)} style={{
                  cursor: 'pointer', fontFamily: 'inherit',
                  background: s.id === scene ? '#fff' : 'rgba(255,255,255,.10)',
                  color: s.id === scene ? 'var(--navy)' : 'rgba(255,255,255,.85)',
                  padding: '5px 9px', borderRadius: 999, fontSize: 10.5, fontWeight: 700,
                  border: '1px solid', borderColor: s.id === scene ? '#fff' : 'rgba(255,255,255,.20)',
                  backdropFilter: 'blur(6px)',
                  transition: 'all .15s', fontVariantNumeric: 'tabular-nums',
                }}
                title={s.label}
                >
                  <span style={{ opacity: .55, marginRight: 5 }}>{String(i+1).padStart(2,'0')}</span>
                  {s.short}
                </button>
              ))}
            </div>
          </div>
        </aside>
        );
      })()}

      <main style={{
        position: 'relative', display: 'grid', placeItems: 'center', minWidth: 0,
        padding: '40px 24px',
        background: '#0E2A3D',
        overflow: 'hidden',
      }}>
        {t.showBackdrop && <BoutiqueBackdrop sceneNum={stepIndex + 1}/>}

        <div style={{ position: 'relative', zIndex: 2, transform: 'scale(.92)' }}>
          <IOSDevice width={390} height={780}>
            {(() => {
              const fullBleed = scene === 'intro' || scene === 'capture';
              return (
                <div style={{
                  width: '100%', height: '100%',
                  background: '#fff',
                  display: 'flex', flexDirection: 'column',
                  position: 'relative', overflow: 'hidden',
                  fontFamily: 'inherit',
                  paddingTop: fullBleed ? 0 : 48,
                }}>
                  <div key={scene} style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
                       data-screen-label={`${String(stepIndex+1).padStart(2,'0')} ${SCENE_FLOW[stepIndex]?.short || scene}`}>
                    {SceneEl}
                  </div>
                </div>
              );
            })()}
          </IOSDevice>
        </div>

        <div style={{
          position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)',
          padding: '6px 12px', borderRadius: 999, background: 'rgba(255,255,255,.85)',
          backdropFilter: 'blur(8px)', border: '1px solid rgba(14,42,61,.08)',
          fontSize: 10, fontWeight: 700, color: 'var(--ink-2)',
          letterSpacing: '.1em', textTransform: 'uppercase',
          display: 'flex', alignItems: 'center', gap: 6, zIndex: 3,
        }}>
          <div style={{
            width: 6, height: 6, borderRadius: 3,
            background: isCustomer ? '#25D366' : 'var(--blue)',
          }}/>
          {isCustomer ? 'Smartphone cliente' : 'Smartphone assistente'}
        </div>
      </main>

      <TweaksPanel title="Demo · Tweaks">
        <TweakSection label="Aspetto">
          <TweakToggle label="Sfondo boutique" value={t.showBackdrop} onChange={v => setTweak('showBackdrop', v)}/>
          <TweakToggle label="Pannello narrativo" value={t.showSidePanel} onChange={v => setTweak('showSidePanel', v)}/>
        </TweakSection>
        <TweakSection label="Navigazione demo">
          <TweakSelect
            label="Vai a scena"
            value={scene}
            options={SCENE_FLOW.map((s, i) => ({ value: s.id, label: `${String(i+1).padStart(2,'0')} · ${s.short}` }))}
            onChange={v => actions.jumpTo(v)}
          />
          <TweakButton label="Ricomincia demo" onClick={actions.restart}/>
          <TweakButton label="Pre-popola → BNPL" secondary onClick={() => {
            setCart([
              { id: 'bag',   name: PRODUCTS.bag.name,   price: PRODUCTS.bag.price },
              { id: 'shoe',  name: PRODUCTS.shoe.name,  price: PRODUCTS.shoe.price },
            ]);
            setCheckout({ delivery: 'ship', shippingCost: 9.90, discount: 31.80, total: PRODUCTS.bag.price + PRODUCTS.shoe.price + 9.90 - 31.80 });
            setScene('payment');
          }}/>
          <TweakButton label="Pre-popola → Backoffice" secondary onClick={() => {
            setCart([
              { id: 'bag',   name: PRODUCTS.bag.name,   price: PRODUCTS.bag.price },
              { id: 'shoe',  name: PRODUCTS.shoe.name,  price: PRODUCTS.shoe.price },
            ]);
            setCheckout({ delivery: 'ship', shippingCost: 9.90, discount: 31.80, total: PRODUCTS.bag.price + PRODUCTS.shoe.price + 9.90 - 31.80 });
            setPayment('bnpl');
            setCustomer({ first: 'Giulia', last: 'Bianchi', addr: 'Via Brera 12', city: 'Milano', cap: '20121', email: 'giulia.bianchi@email.it', phone: '+39 333 1234567' });
            setChannel('wa');
            setScene('backoffice');
          }}/>
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

// Boutique backdrop using the real store image, blurred for the right pane.
// Swaps to the customer or manager photo on later scenes for narrative coherence.
function BoutiqueBackdrop({ sceneNum = 1 }) {
  const bg = sceneNum === 9 ? 'assets/manager-bg.jpg'
    : (sceneNum >= 6 && sceneNum <= 8) ? 'assets/customer-bg.jpg'
    : 'assets/store-bg.jpg';
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 1, pointerEvents: 'none', overflow: 'hidden' }}>
      <div style={{
        position: 'absolute', inset: -20,
        background: `url('${bg}') center / cover no-repeat`,
        filter: 'blur(14px) saturate(1.05)',
        transform: 'scale(1.1)',
        opacity: 0.85,
        transition: 'background-image .4s',
      }}/>
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(180deg, rgba(14,42,61,.55), rgba(14,42,61,.35) 50%, rgba(14,42,61,.65))',
      }}/>
      {/* Soft halo behind the device */}
      <div style={{
        position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%, -50%)',
        width: 520, height: 520, borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(255,255,255,.25), transparent 60%)',
      }}/>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
