/* global React, ReactDOM, useTweaks, TweaksPanel, TweakSection, TweakText, TweakNumber, TweakRadio, TweakToggle, TweakButton */

const { useState, useMemo } = React;

// ============================================================
// Trip data — the four itinerary options
// ============================================================
const OPTIONS = [
{
  hours: 4,
  name: 'Quick Paddle',
  blurb: 'Straight to the water. Best for tight schedules — kayak the Gorge and back to Portland by 5.',
  schedule: [
  { time: '1:00 PM', event: 'Depart Downtown Portland', detail: 'Meet at the pickup point. Van loaded with kayaks, gear, and snacks.' },
  { time: '2:00 PM', event: 'Kayak Tour Begins', detail: 'Guided paddle on the Columbia River. Singles and doubles available. All skill levels.', highlight: true },
  { time: '4:00 PM', event: 'End Kayak Tour', detail: 'De-rig, towel off, and reload the van.' },
  { time: '5:00 PM', event: 'Return to Portland', detail: 'Drop-off at the original pickup point.' }],

  includes: ['kayak']
},
{
  hours: 5,
  name: 'Falls + Paddle',
  blurb: "A taste of the Gorge before you get on the water. Stop at Multnomah Falls — Oregon's tallest waterfall — then paddle.",
  schedule: [
  { time: '12:00 PM', event: 'Depart Downtown Portland', detail: 'Meet at the pickup point. Scenic drive up the Columbia River Gorge.' },
  { time: '12:45 PM', event: 'Multnomah Falls', detail: 'Photos and a stretch at the iconic 620-ft waterfall. ~30 min stop.', highlight: true },
  { time: '2:00 PM', event: 'Kayak Tour Begins', detail: 'Guided paddle on the Columbia River. Singles and doubles available.', highlight: true },
  { time: '4:00 PM', event: 'End Kayak Tour', detail: 'De-rig, towel off, and reload the van.' },
  { time: '5:10 PM', event: 'Return to Portland', detail: 'Drop-off at the original pickup point.' }],

  includes: ['kayak', 'multnomah']
},
{
  hours: 6,
  name: 'Paddle + Dinner',
  blurb: 'The most popular team option. Falls, paddle, and a relaxed group dinner before heading back.',
  schedule: [
  { time: '12:00 PM', event: 'Depart Downtown Portland', detail: 'Meet at the pickup point. Scenic drive up the Columbia River Gorge.' },
  { time: '12:45 PM', event: 'Multnomah Falls', detail: 'Photos and a stretch at the iconic 620-ft waterfall. ~30 min stop.' },
  { time: '2:00 PM', event: 'Kayak Tour Begins', detail: 'Guided paddle on the Columbia River. Singles and doubles available.', highlight: true },
  { time: '4:00 PM', event: 'End Kayak Tour', detail: 'De-rig and head to dinner.' },
  { time: '4:15 PM', event: 'Group Dinner', detail: 'Local Cascade Locks restaurant. Pay your tab at the restaurant — not included in trip price.', highlight: true },
  { time: '6:00 PM', event: 'Return to Portland', detail: 'Drop-off at the original pickup point.' }],

  includes: ['kayak', 'multnomah', 'dinner']
},
{
  hours: 7,
  name: 'The Full Gorge',
  blurb: "The whole story of the Gorge in one afternoon — paddle, dinner, and a sunset waterfall tour with three more stops.",
  schedule: [
  { time: '12:00 PM', event: 'Depart Downtown Portland', detail: 'Meet at the pickup point. Scenic drive up the Columbia River Gorge.' },
  { time: '12:45 PM', event: 'Multnomah Falls', detail: 'Photos and a stretch at the iconic 620-ft waterfall.' },
  { time: '2:00 PM', event: 'Kayak Tour Begins', detail: 'Guided paddle on the Columbia River.', highlight: true },
  { time: '4:00 PM', event: 'End Kayak Tour', detail: 'De-rig and head to dinner.' },
  { time: '4:15 PM', event: 'Group Dinner', detail: 'Local Cascade Locks restaurant. Pay your tab at the restaurant — not included in trip price.' },
  { time: '5:30 PM', event: 'Horsetail Falls', detail: '176-ft braided fall right beside the Historic Columbia River Highway.' },
  { time: '6:00 PM', event: 'Latourell Falls', detail: '249-ft basalt-walled drop. Quick walk to the viewing platform.' },
  { time: '6:30 PM', event: 'Crown Point Vista House', detail: 'Sunset over the Gorge from 733 ft up. Best photo of the day.', highlight: true },
  { time: '7:00 PM', event: 'Return to Portland', detail: 'Drop-off at the original pickup point.' }],

  includes: ['kayak', 'multnomah', 'dinner', 'waterfalls']
}];


const KAYAK_RATE = 69; // per person
// Flat van fee by trip length (hours). Includes vehicle, fuel, and driver.
const VAN_FLAT = { 4: 800, 5: 950, 6: 1100, 7: 1250, 8: 1400 };
const HERO_IMG = 'assets/photo-kayak-tour.jpeg';

// ============================================================
// Helpers
// ============================================================
function fmt(n) {
  return '$' + Math.round(n).toLocaleString('en-US');
}

function calcQuote(opt, group, vanFlat) {
  const kayak = KAYAK_RATE * group;
  const van = (vanFlat && vanFlat[opt.hours]) ?? VAN_FLAT[opt.hours];
  const total = kayak + van;
  return { kayak, van, total, perPerson: total / group };
}

// ============================================================
// Components — every "page" is a US Letter sheet
// ============================================================

function SheetHead({ customer, customerTitle, date, proposalId, dark }) {
  return (
    <header className="sheet-head">
      <div className="logo">
        <img src="assets/logo-full.png" alt="Out of Office Experiences" />
      </div>
      <div className="meta">
        <strong>Custom Itinerary</strong>
        Prepared for {customer}{customerTitle ? <><br />{customerTitle}</> : null}<br />
        Trip date · {date}<br />
        Proposal #{proposalId}
      </div>
    </header>);

}

function SheetFoot({ pageNum, totalPages }) {
  return (
    <footer className="sheet-foot">
      <span className="tagline">Shared moments, stronger teams.</span>
      <span>outofofficeexperiences.com  ·  Cascade Locks, OR  ·  Page {pageNum} of {totalPages}</span>
    </footer>);

}

// ----- Cover page: hero + 4 option summary cards -----
function CoverSheet({ t, recIdx }) {
  const { customer, customerTitle, date, group, proposalId, contactEmail } = t;

  return (
    <section className="page" data-screen-label="01 Proposal Cover">
      <SheetHead customer={customer} customerTitle={customerTitle} date={date} proposalId={proposalId} />

      <div className="cover-hero">
        <img src={HERO_IMG} alt="Kayaking the Columbia River Gorge" />
        <div className="cover-text">
          <div className="cover-eyebrow">— Custom Trip Proposal</div>
          <h1>Get your team on the water.</h1>
        </div>
      </div>

      <div className="facts">
        <div className="fact">
          <div className="label">Group Size</div>
          <div className="value">{group} <span className="small">paddlers</span></div>
        </div>
        <div className="fact">
          <div className="label">Trip Date</div>
          <div className="value">{date}</div>
        </div>
        <div className="fact">
          <div className="label">Activity</div>
          <div className="value">Kayak <span className="small">+ falls</span></div>
        </div>
        <div className="fact">
          <div className="label">Pickup</div>
          <div className="value">Downtown <span className="small">Portland</span></div>
        </div>
      </div>

      <div className="section-head">
        <span className="num">01</span>
        <h2>Choose Your Itinerary</h2>
        <span className="rule"></span>
      </div>

      <p className="p" style={{ fontSize: '13px', lineHeight: 1.55, color: 'var(--fg-muted)', maxWidth: 'none', marginBottom: '16px' }}>Four time-and-activity options, all built around the same guided kayak tour on the Columbia. Pick the one that fits your day or suggest something even better and we'll make it happen for you!

      </p>

      <div className="options-grid">
        {OPTIONS.map((opt, i) => {
          const q = calcQuote(opt, group);
          const includesShort = [
          opt.includes.includes('kayak') && 'Kayak tour',
          opt.includes.includes('multnomah') && 'Multnomah Falls',
          opt.includes.includes('dinner') && 'Group dinner',
          opt.includes.includes('waterfalls') && '3 more falls + Vista House'].
          filter(Boolean).join(' · ');
          return (
            <div key={opt.hours} className={`option-card ${i === recIdx ? 'is-recommended' : ''}`}>
              {i === recIdx && <span className="rec-badge"></span>}
              <div className="opt-top">
                <div className="opt-hours">{opt.hours} hr<small>itinerary</small></div>
              </div>
              <div className="opt-name">{opt.name}</div>
              <p className="opt-includes">{includesShort}</p>
              <div className="opt-foot">
                <div>
                  <div className="opt-price">{fmt(q.total)}</div>
                  <div className="opt-perperson">{fmt(q.perPerson)} / person · all in</div>
                </div>
                <div style={{ textAlign: 'right' }}>
                  <div className="opt-perperson" style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.08em' }}>See p.{i + 2}</div>
                </div>
              </div>
            </div>);

        })}
      </div>

      <div className="note">
        <strong>How to confirm</strong>
        Reply with your chosen option and pay to confirm your dates.
      </div>

      <SheetFoot pageNum={1} totalPages={5} />
    </section>);

}

// ----- Detail sheet: timeline + pricing + includes for one option -----
function OptionSheet({ opt, idx, t, recommended }) {
  const { customer, customerTitle, date, group, proposalId } = t;
  const q = calcQuote(opt, group);

  const includesText = [
  'Professional guide for the duration of the trip',
  'Round-trip transportation in air-conditioned van',
  `Kayak rental — singles or doubles (${group} paddlers)`,
  'Paddle, PFD, dry bag, water bottle',
  'Pre-paddle safety briefing & basic instruction',
  opt.includes.includes('multnomah') && 'Multnomah Falls visit (parking + admission)',
  opt.includes.includes('dinner') && 'Group dinner reservation (food/drink paid at restaurant)',
  opt.includes.includes('waterfalls') && 'Horsetail, Latourell falls + Crown Point Vista House'].
  filter(Boolean);

  const bringText = [
  'Quick-dry layers (bring a sweater for the ride home)',
  'Closed-toe shoes that can get wet',
  'Sunglasses with strap, sunscreen, hat',
  'Towel & change of clothes for the van',
  opt.includes.includes('dinner') && 'Light layer for the post-paddle dinner'].
  filter(Boolean);

  return (
    <section className="page" data-screen-label={`0${idx + 2} Option ${opt.hours}hr`}>
      <SheetHead customer={customer} customerTitle={customerTitle} date={date} proposalId={proposalId} />

      <div className="section-head">
        <span className="num">OPTION {String.fromCharCode(65 + idx)}</span>
        <h2>{opt.hours}-Hour · {opt.name}</h2>
        <span className="rule"></span>
        {recommended && <span className="rec-badge" style={{ position: 'static', transform: 'none' }}></span>}
      </div>

      <p className="p" style={{ fontSize: '14px', lineHeight: 1.55, maxWidth: 'none', marginBottom: '20px', color: 'var(--fg)' }}>
        {opt.blurb}
      </p>

      <div className="section-head">
        <span className="num">▸</span>
        <h2 style={{ fontSize: 'var(--fs-16)' }}>Day Schedule</h2>
        <span className="rule"></span>
      </div>

      <div className="timeline">
        {opt.schedule.map((row, i) =>
        <div key={i} className={`tl-row ${row.highlight ? 'is-highlight' : ''}`}>
            <div className="tl-time">{row.time}</div>
            <div className="tl-marker">
              <span className="line"></span>
              <span className="dot"></span>
            </div>
            <div className="tl-content">
              <h4 className="tl-event">{row.event}</h4>
              <p className="tl-detail">{row.detail}</p>
            </div>
          </div>
        )}
      </div>

      <div className="two-col">
        <div>
          <div className="section-head">
            <span className="num">▸</span>
            <h2 style={{ fontSize: 'var(--fs-16)' }}>Includes</h2>
            <span className="rule"></span>
          </div>
          <ul className="includes-list">
            {includesText.map((it, i) => <li key={i}>{it}</li>)}
          </ul>
        </div>
        <div>
          <div className="section-head">
            <span className="num">▸</span>
            <h2 style={{ fontSize: 'var(--fs-16)' }}>What to Bring</h2>
            <span className="rule"></span>
          </div>
          <ul className="includes-list">
            {bringText.map((it, i) => <li key={i}>{it}</li>)}
          </ul>
        </div>
      </div>

      <div className="section-head">
        <span className="num">▸</span>
        <h2 style={{ fontSize: 'var(--fs-16)' }}>Pricing — {group} paddlers</h2>
        <span className="rule"></span>
      </div>

      <div className="pricing">
        <div className="pricing-row">
          <div className="desc">Guided kayak tour <small>${KAYAK_RATE} × {group} paddlers</small></div>
          <div className="amount">{fmt(q.kayak)}</div>
        </div>
        <div className="pricing-row">
          <div className="desc">Van transportation <small>flat rate · {opt.hours} hrs · driver, fuel, gear</small></div>
          <div className="amount">{fmt(q.van)}</div>
        </div>
        {opt.includes.includes('dinner') &&
        <div className="pricing-row">
            <div className="desc">Group dinner <small>paid directly at the restaurant — not included in OOE total</small></div>
            <div className="amount" style={{ color: 'var(--fg-muted)', fontWeight: 500 }}>—</div>
          </div>
        }
        <div className="pricing-row total">
          <div className="desc">Total</div>
          <div className="amount">{fmt(q.total)} <span style={{ fontSize: 12, color: 'var(--fg-muted)', fontWeight: 400, letterSpacing: 0 }}>· {fmt(q.perPerson)}/person</span></div>
        </div>
      </div>

      <SheetFoot pageNum={idx + 2} totalPages={5} />
    </section>);

}

// ============================================================
// App
// ============================================================
function App() {
  const [t, setTweak] = useTweaks(/*EDITMODE-BEGIN*/{
    "customer": "Mia Carney",
    "customerTitle": "VP of Operations, MBT Marketing",
    "contactName": "Jordan Reyes",
    "contactEmail": "hello@outofofficeexperiences.com",
    "date": "Thursday, July 30, 2026",
    "group": 14,
    "proposalId": "OOE-2026-0730",
    "recommended": "6hr",
    "templateMode": false
  } /*EDITMODE-END*/);

  const recIdx = useMemo(() => {
    const map = { '4hr': 0, '5hr': 1, '6hr': 2, '7hr': 3 };
    return map[t.recommended] ?? 2;
  }, [t.recommended]);

  // In template mode show generic placeholders so user can swap in their own
  const display = t.templateMode ?
  { ...t,
    customer: '[Customer Name]',
    customerTitle: '[Title, Company]',
    date: '[Trip Date]',
    proposalId: '[Proposal #]',
    contactName: '[Your Name]',
    contactEmail: '[your@email.com]'
  } :
  t;

  return (
    <>
      <div className="viewer">
        <div className="viewer-header">
          <span className="label">{t.templateMode ? 'Template Mode — generic placeholders' : 'Proposal'}</span>
          <span className="title">Custom Itinerary</span>
        </div>

        <CoverSheet t={display} recIdx={recIdx} />
        {OPTIONS.map((opt, i) =>
        <OptionSheet
          key={opt.hours}
          opt={opt}
          idx={i}
          t={display}
          recommended={i === recIdx} />

        )}
      </div>

      <TweaksPanel title="Tweaks" defaultOpen={false}>
        <TweakSection title="View">
          <TweakToggle
            label="Template mode"
            hint="Swap in generic placeholders so you can save this as a reusable template."
            value={t.templateMode}
            onChange={(v) => setTweak('templateMode', v)} />
          
          <TweakButton label="Print / Save as PDF" onClick={() => window.print()} />
        </TweakSection>

        <TweakSection title="Customer">
          <TweakText label="Customer" value={t.customer} onChange={(v) => setTweak('customer', v)} />
          <TweakText label="Title / Company" value={t.customerTitle} onChange={(v) => setTweak('customerTitle', v)} />
          <TweakText label="Trip date" value={t.date} onChange={(v) => setTweak('date', v)} />
          <TweakNumber label="Group size" value={t.group} min={1} max={50} onChange={(v) => setTweak('group', v)} />
          <TweakText label="Proposal #" value={t.proposalId} onChange={(v) => setTweak('proposalId', v)} />
        </TweakSection>

        <TweakSection title="Recommendation">
          <TweakRadio
            label="Highlight option"
            value={t.recommended}
            options={['4hr', '5hr', '6hr', '7hr']}
            onChange={(v) => setTweak('recommended', v)} />
          
        </TweakSection>

        <TweakSection title="Your Contact">
          <TweakText label="Your name" value={t.contactName} onChange={(v) => setTweak('contactName', v)} />
          <TweakText label="Your email" value={t.contactEmail} onChange={(v) => setTweak('contactEmail', v)} />
        </TweakSection>
      </TweaksPanel>
    </>);

}

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