// shared.jsx — common data, hooks, and small primitives used by all 3 site variations.

const PHONE_DISPLAY = '587-409-6268';
const PHONE_HREF = 'tel:+15874096268';
const EMAIL = 'afarah@farahwindowcleaning.com';
const LOCATION = 'Edmonton, AB';

const SERVICES = [
  {
    key: 'recurring',
    title: 'Recurring Storefront Service',
    short: 'Weekly · bi-weekly · monthly',
    blurb:
      'A standing route that keeps your storefront sharp without you ever having to call. Same crew, same day each cycle, before your doors open.',
    bullets: ['Locked-in pricing, no surprise upcharges', 'Before-hours or after-close slots', 'COI on file for your landlord'],
    slotId: 'service-recurring',
    placeholder: 'Photo: crew squeegeeing a retail storefront before opening',
    src: 'service-recurring-storefront.png',
  },
  {
    key: 'onetime',
    title: 'One-Time & Grand Opening Cleans',
    short: 'Pop-ups, openings, post-construction',
    blurb:
      'Opening a new location, post-renovation, or hosting an event? We do single-visit deep cleans on tight timelines — usually within 48 hours of your call.',
    bullets: ['48-hour turnaround on most jobs', 'Construction overspray & sticker removal', 'Inside + outside, frames, tracks, sills'],
    slotId: 'service-onetime',
    placeholder: 'Photo: crew member doing a one-time grand-opening clean',
    src: 'service-recurring-storefront.png',
  },
  {
    key: 'signage',
    title: 'Signage, Awnings & Frames',
    short: 'Channel letters, vinyl, fabric awnings',
    blurb:
      'Faded signage and grimy awnings age a storefront faster than the windows do. We bring them back without damaging vinyl, channel letters, or fabric.',
    bullets: ['Soft-wash safe on vinyl & fabric', 'Channel-letter & light-box cleaning', 'Bundle with your window route'],
    slotId: 'service-signage',
    placeholder: 'Photo: brightening up a fabric awning over a Whyte Ave shop',
    src: 'service-recurring-storefront.png',
  },
  {
    key: 'interior',
    title: 'Interior Glass & Partitions',
    short: 'Office dividers, glass doors, vestibules',
    blurb:
      'Glass dividers, conference-room walls, vestibule doors — all the interior glass your team and customers actually touch every day.',
    bullets: ['Streak-free interior & exterior', 'After-hours office service', 'Fingerprint + smudge removal'],
    slotId: 'service-interior',
    placeholder: 'Photo: crew member detailing interior glass partitions in an office',
    src: 'service-recurring-storefront.png',
  },
];

const DIFFERENTIATORS = [
  { icon: 'window',   title: 'Storefront-only',         note: 'We don’t do houses or high-rises. Storefront glass is what we do all day, every day.' },
  { icon: 'calendar', title: 'Before-hours service',    note: 'We arrive at 5am, 6am, or after close — your customers never see a squeegee.' },
  { icon: 'shield',   title: 'Fully insured + WCB',     note: '$2M liability and WCB coverage. COIs emailed to your landlord on request.' },
  { icon: 'pin',      title: 'Edmonton-based',         note: 'We live and work here. No franchise, no head office — you talk to the owner.' },
  { icon: 'check',    title: 'Recurring routes',        note: 'Same crew, same day each cycle. Predictable for your team and ours.' },
  { icon: 'sparkle',  title: 'No-streak guarantee',     note: 'See a streak after we leave? We come back same-day, no charge.' },
  { icon: 'price',    title: 'Locked-in pricing',       note: 'Flat per-visit rate on contracts. No surprise upcharges, no per-pane shell game.' },
  { icon: 'mail',     title: 'Multiple-location billing', note: 'Run a chain? One invoice, one POC, all your locations on one schedule.' },
];

const FAQS = [
  {
    q: 'How often should I have my storefront windows cleaned?',
    a: 'For most Edmonton storefronts, every 2–4 weeks is the sweet spot — enough to keep glass and signage looking sharp without overdoing it. High-traffic spots (cafes, restaurants, dispensaries) usually want weekly. We’ll walk the property once and recommend a cadence you can actually budget against.',
  },
  {
    q: 'Do you work before-hours so we don’t disturb customers?',
    a: 'Yes — the majority of our route runs between 5am and 9am, before any customer walks past your storefront. We can also book after-close slots for late-evening venues. Whichever doesn’t cost you a single foot of foot traffic.',
  },
  {
    q: 'Are you insured and WCB-covered? Can we get a COI on file?',
    a: 'Yes — $2 million liability coverage, WCB on every crew member, and a Certificate of Insurance we’ll send straight to your landlord or property manager so it stays on file before our first visit.',
  },
  {
    q: 'Do you service multiple locations under one contract?',
    a: 'Absolutely. We service multi-location retailers, restaurant groups, and dental/medical chains across Greater Edmonton on a single contract — one POC, one invoice, every location on the same recurring schedule.',
  },
  {
    q: 'How do you price recurring contracts?',
    a: 'Flat per-visit rate, locked in for the term. We walk your property once, count the panes, factor in any awnings or signage, and quote a single number you’ll see on every invoice. No surprise upcharges, no per-pane gymnastics.',
  },
  {
    q: 'What’s your guarantee if a window streaks?',
    a: 'Text us a photo within 48 hours. We’ll be back same-day or next-business-day at no charge — you only pay when the glass is perfect.',
  },
];

const SERVICE_AREAS = [
  'Downtown', 'Old Strathcona', '124 Street', 'Whyte Avenue', 'Jasper Avenue',
  'Sherwood Park', 'St. Albert', 'South Common', 'West Edmonton', 'Leduc',
];

// ── Theme presets ────────────────────────────────────────────────────────
// Each preset overrides the primary accent on every variation. Variation
// chrome (background, secondary palette, typography) stays distinct.
const THEMES = {
  sky: {
    label: 'Sky',
    primary: '#0EA5E9',
    primaryDeep: '#0369A1',
    primarySoft: '#E0F2FE',
    accent: '#F59E0B',
  },
  ocean: {
    label: 'Ocean',
    primary: '#0F4C81',
    primaryDeep: '#082F4C',
    primarySoft: '#E2ECF6',
    accent: '#D4A24C',
  },
  spring: {
    label: 'Spring',
    primary: '#16A34A',
    primaryDeep: '#14532D',
    primarySoft: '#DCFCE7',
    accent: '#F97316',
  },
  sunrise: {
    label: 'Sunrise',
    primary: '#F97316',
    primaryDeep: '#9A3412',
    primarySoft: '#FFEDD5',
    accent: '#0EA5E9',
  },
};

// ── Small shared SVG icons ───────────────────────────────────────────────
const Icon = ({ name, size = 20, stroke = 'currentColor', strokeWidth = 1.8, fill = 'none' }) => {
  const p = { width: size, height: size, viewBox: '0 0 24 24', fill, stroke, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'phone': return (<svg {...p}><path d="M5 4h3l2 5-2.5 1.5a11 11 0 0 0 6 6L15 14l5 2v3a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>);
    case 'arrow': return (<svg {...p}><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></svg>);
    case 'check': return (<svg {...p}><path d="m5 13 4 4 10-10"/></svg>);
    case 'sparkle': return (<svg {...p}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M5.6 18.4l2.8-2.8M15.6 8.4l2.8-2.8"/></svg>);
    case 'shield': return (<svg {...p}><path d="M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6l-8-3z"/><path d="m9 12 2 2 4-4"/></svg>);
    case 'home': return (<svg {...p}><path d="m3 11 9-7 9 7"/><path d="M5 10v10h14V10"/><path d="M10 20v-6h4v6"/></svg>);
    case 'pin': return (<svg {...p}><path d="M12 21s7-6.5 7-12a7 7 0 0 0-14 0c0 5.5 7 12 7 12z"/><circle cx="12" cy="9" r="2.5"/></svg>);
    case 'leaf': return (<svg {...p}><path d="M4 20c0-9 7-16 16-16 0 9-7 16-16 16z"/><path d="M4 20c4-4 8-6 12-8"/></svg>);
    case 'price': return (<svg {...p}><path d="M20 12 12 4H4v8l8 8 8-8z"/><circle cx="9" cy="9" r="1.4"/></svg>);
    case 'calendar': return (<svg {...p}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>);
    case 'window': return (<svg {...p}><rect x="3" y="3" width="18" height="18" rx="1"/><path d="M12 3v18M3 12h18"/></svg>);
    case 'squeegee': return (<svg {...p}><path d="m4 20 7-7M11 13l5-5 4 4-5 5z"/><path d="M3 21h6"/></svg>);
    case 'star': return (<svg {...p} fill="currentColor" stroke="none"><path d="m12 2 2.9 6.3 6.8.7-5.1 4.6 1.5 6.7L12 16.9l-6.1 3.4 1.5-6.7L2.3 9l6.8-.7z"/></svg>);
    case 'menu': return (<svg {...p}><path d="M4 7h16M4 12h16M4 17h16"/></svg>);
    case 'plus': return (<svg {...p}><path d="M12 5v14M5 12h14"/></svg>);
    case 'minus': return (<svg {...p}><path d="M5 12h14"/></svg>);
    case 'mail': return (<svg {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 7 9-7"/></svg>);
    default: return null;
  }
};

// ── Quote form (used by all 3 variations, styled by container) ──────────
// External CRM-hosted form embedded via iframe. The form_embed.js script
// from the same vendor wires up resize/visibility messaging.
function QuoteForm({ accent = '#0EA5E9', dark = false, compact = false }) {
  React.useEffect(() => {
    const SRC = 'https://links.amanahcrm.com/js/form_embed.js';
    if (document.querySelector(`script[src="${SRC}"]`)) return;
    const s = document.createElement('script');
    s.src = SRC;
    s.async = true;
    document.body.appendChild(s);
  }, []);
  return (
    <div style={{ width: '100%' }}>
      <iframe
        src="https://links.amanahcrm.com/widget/form/OkYelDFLGPwTuM6CHf2J"
        style={{ display: 'block', width: '100%', height: 985, border: 'none', borderRadius: 3 }}
        id="inline-OkYelDFLGPwTuM6CHf2J"
        data-layout='{"id":"INLINE"}'
        data-trigger-type="alwaysShow"
        data-trigger-value=""
        data-activation-type="alwaysActivated"
        data-activation-value=""
        data-deactivation-type="neverDeactivate"
        data-deactivation-value=""
        data-form-name="Form 0"
        data-height="985"
        data-layout-iframe-id="inline-OkYelDFLGPwTuM6CHf2J"
        data-form-id="OkYelDFLGPwTuM6CHf2J"
        title="Form 0"
      />
    </div>
  );
}

function _QuoteForm_unused({ accent = '#0EA5E9', dark = false, compact = false }) {
  const [state, setState] = React.useState({
    name: '', phone: '', email: '', business: '', frequency: 'recurring', message: '',
  });
  const [errors, setErrors] = React.useState({});
  const [submitted, setSubmitted] = React.useState(false);

  const set = (k) => (e) => setState((s) => ({ ...s, [k]: e.target.value }));

  const validate = () => {
    const e = {};
    if (!state.name.trim()) e.name = 'Please tell us your name.';
    const phoneDigits = state.phone.replace(/\D/g, '');
    if (!phoneDigits || phoneDigits.length < 10) e.phone = 'A 10-digit phone, please.';
    if (state.email && !/^\S+@\S+\.\S+$/.test(state.email)) e.email = 'Double-check the email format.';
    return e;
  };

  const onSubmit = (ev) => {
    ev.preventDefault();
    const e = validate();
    setErrors(e);
    if (Object.keys(e).length === 0) setSubmitted(true);
  };
  const labelColor = dark ? 'rgba(255,255,255,0.78)' : '#475569';
  const inputBg = dark ? 'rgba(255,255,255,0.06)' : '#fff';
  const inputBorder = dark ? 'rgba(255,255,255,0.18)' : '#CBD5E1';
  const inputText = dark ? '#fff' : '#0F172A';

    if (submitted) {    return (
      <div style={{
        background: dark ? 'rgba(255,255,255,0.05)' : '#fff',
        border: `1.5px solid ${accent}`, borderRadius: 16, padding: compact ? 24 : 36, textAlign: 'center',
      }}>
        <div style={{
          width: 56, height: 56, borderRadius: '50%', background: accent,
          color: '#fff', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16,
        }}>
          <Icon name="check" size={28} strokeWidth={2.5} />
        </div>
        <div style={{ fontSize: compact ? 22 : 26, fontWeight: 700, color: dark ? '#fff' : '#0F172A', marginBottom: 8 }}>
          Got it — talk soon.
        </div>
        <div style={{ color: labelColor, fontSize: 15, lineHeight: 1.55, maxWidth: 380, margin: '0 auto' }}>
          We’ll text or email you a quote within the day. For anything urgent, just call <b style={{ color: dark ? '#fff' : '#0F172A' }}>{PHONE_DISPLAY}</b>.
        </div>
        <button type="button" onClick={() => { setSubmitted(false); setState({ name:'', phone:'', email:'', business:'', frequency:'recurring', message:'' }); }}
          style={{
            marginTop: 20, background: 'transparent', border: `1.5px solid ${inputBorder}`,
            color: dark ? '#fff' : '#475569', padding: '10px 18px', borderRadius: 999, cursor: 'pointer',
            fontWeight: 600, fontSize: 14,
          }}>
          Send another request
        </button>
      </div>
    );
  }

  const inputStyle = {
    width: '100%', boxSizing: 'border-box', padding: '13px 14px', borderRadius: 10,
    border: `1.5px solid ${inputBorder}`, background: inputBg, color: inputText,
    fontSize: 15, fontFamily: 'inherit', outline: 'none', transition: 'border-color .15s, box-shadow .15s',
  };
  const errStyle = { color: '#DC2626', fontSize: 12.5, marginTop: 5, fontWeight: 500 };
  const labelStyle = { display: 'block', fontSize: 12.5, fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', color: labelColor, marginBottom: 6 };

  return (
    <form onSubmit={onSubmit} style={{ display: 'grid', gap: 14 }} noValidate>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <div>
          <label style={labelStyle}>Name</label>
          <input style={{ ...inputStyle, borderColor: errors.name ? '#DC2626' : inputBorder }}
            value={state.name} onChange={set('name')} placeholder="Your name" />
          {errors.name && <div style={errStyle}>{errors.name}</div>}
        </div>
        <div>
          <label style={labelStyle}>Phone</label>
          <input style={{ ...inputStyle, borderColor: errors.phone ? '#DC2626' : inputBorder }}
            value={state.phone} onChange={set('phone')} placeholder="587-409-6268" />
          {errors.phone && <div style={errStyle}>{errors.phone}</div>}
        </div>
      </div>
      <div>
        <label style={labelStyle}>Business name + address</label>
        <input style={{ ...inputStyle }}
          value={state.business} onChange={set('business')}
          placeholder="e.g. Daily Grind Coffee — 10523 Whyte Ave" />
      </div>
      <div>
        <label style={labelStyle}>Email (optional)</label>
        <input style={{ ...inputStyle, borderColor: errors.email ? '#DC2626' : inputBorder }}
          value={state.email} onChange={set('email')} placeholder="you@yourbusiness.com" />
        {errors.email && <div style={errStyle}>{errors.email}</div>}
      </div>
      <div>
        <label style={labelStyle}>Service type</label>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          {[
            { id: 'recurring', label: 'Recurring' },
            { id: 'onetime', label: 'One-time' },
          ].map((v) => {
            const active = state.frequency === v.id;
            return (
              <button key={v.id} type="button" onClick={() => setState((s) => ({ ...s, frequency: v.id }))}
                style={{
                  padding: '12px 14px', borderRadius: 10, cursor: 'pointer',
                  border: `1.5px solid ${active ? accent : inputBorder}`,
                  background: active ? (dark ? `${accent}26` : `${accent}14`) : inputBg,
                  color: active ? (dark ? '#fff' : accent) : (dark ? 'rgba(255,255,255,0.78)' : '#475569'),
                  fontWeight: 600, fontSize: 14, fontFamily: 'inherit',
                }}>
                {v.label}
              </button>
            );
          })}
        </div>
      </div>
      <div>
        <label style={labelStyle}>Anything we should know? (optional)</label>
        <textarea rows={3} style={{ ...inputStyle, resize: 'vertical', minHeight: 80 }}
          value={state.message} onChange={set('message')}
          placeholder="Storefront type, # of panes, awnings or signage, preferred cadence…" />
      </div>
      <button type="submit" style={{
        marginTop: 4, padding: '15px 22px', borderRadius: 12, border: 'none', cursor: 'pointer',
        background: accent, color: '#fff', fontWeight: 700, fontSize: 15.5, letterSpacing: '0.01em',
        fontFamily: 'inherit', boxShadow: `0 8px 24px -8px ${accent}88`, display: 'flex',
        alignItems: 'center', justifyContent: 'center', gap: 10,
      }}>
        Get my storefront quote
        <Icon name="arrow" size={18} strokeWidth={2.2} />
      </button>
      <div style={{ fontSize: 12.5, color: labelColor, textAlign: 'center', marginTop: 2 }}>
        Or call us directly — <b style={{ color: dark ? '#fff' : '#0F172A' }}>{PHONE_DISPLAY}</b>
      </div>
    </form>
  );
}

// ── FAQ accordion (shared) ───────────────────────────────────────────────
function FAQAccordion({ items, accent = '#0EA5E9', dark = false, divider }) {
  const [open, setOpen] = React.useState(0);
  const textColor = dark ? '#fff' : '#0F172A';
  const subColor = dark ? 'rgba(255,255,255,0.72)' : '#475569';
  const line = divider || (dark ? 'rgba(255,255,255,0.12)' : '#E2E8F0');
  return (
    <div style={{ borderTop: `1px solid ${line}` }}>
      {items.map((item, i) => {
        const isOpen = open === i;
        return (
          <div key={i} style={{ borderBottom: `1px solid ${line}` }}>
            <button type="button" onClick={() => setOpen(isOpen ? -1 : i)}
              style={{
                width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                gap: 20, padding: '22px 4px', background: 'transparent', border: 'none', cursor: 'pointer',
                textAlign: 'left', color: textColor, fontFamily: 'inherit',
              }}>
              <span style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.01em' }}>{item.q}</span>
              <span style={{
                width: 32, height: 32, borderRadius: '50%', flex: '0 0 32px',
                background: isOpen ? accent : (dark ? 'rgba(255,255,255,0.08)' : '#F1F5F9'),
                color: isOpen ? '#fff' : (dark ? '#fff' : '#0F172A'),
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                transition: 'background .15s',
              }}>
                <Icon name={isOpen ? 'minus' : 'plus'} size={16} strokeWidth={2.4} />
              </span>
            </button>
            <div style={{
              maxHeight: isOpen ? 240 : 0, overflow: 'hidden', transition: 'max-height .3s ease',
            }}>
              <div style={{ padding: '0 56px 22px 4px', color: subColor, fontSize: 15.5, lineHeight: 1.65 }}>
                {item.a}
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ── Service tabs (Recurring ↔ One-time) ──────────────────────────────────
// A controlled tab strip variants can wrap with their own chrome.
function ServiceTabs({ accent = '#0EA5E9', value, onChange, dark = false }) {
  return (
    <div style={{
      display: 'inline-flex', padding: 5, borderRadius: 999,
      background: dark ? 'rgba(255,255,255,0.08)' : '#F1F5F9',
      border: `1px solid ${dark ? 'rgba(255,255,255,0.1)' : '#E2E8F0'}`,
    }}>
      {[
        { id: 'recurring', label: 'Recurring service' },
        { id: 'onetime', label: 'One-time clean' },
      ].map((t) => {
        const active = value === t.id;
        return (
          <button key={t.id} type="button" onClick={() => onChange(t.id)}
            style={{
              padding: '10px 22px', borderRadius: 999, border: 'none', cursor: 'pointer',
              background: active ? accent : 'transparent',
              color: active ? '#fff' : (dark ? 'rgba(255,255,255,0.8)' : '#475569'),
              fontWeight: 600, fontSize: 14.5, fontFamily: 'inherit',
              transition: 'background .18s, color .18s',
            }}>
            {t.label}
          </button>
        );
      })}
    </div>
  );
}

// ── Brand assets ─────────────────────────────────────────────────────────
// The real Farah Window Cleaning wordmark & favicon, supplied by the
// owner. `light` flips them white via CSS filter so they sit cleanly on
// dark surfaces (footers, dark heroes).
function BrandWordmark({ height = 28, light = false, style }) {
  return (
    <img
      src="logo-wordmark.svg"
      alt="Farah Window Cleaning"
      style={{
        height,
        width: 'auto',
        display: 'block',
        filter: light ? 'invert(1) brightness(1.05)' : 'none',
        ...style,
      }}
    />
  );
}

function BrandMark({ size = 44, style }) {
  return (
    <img
      src="favicon.svg"
      alt=""
      aria-hidden="true"
      style={{ width: size, height: size, display: 'block', ...style }}
    />
  );
}

Object.assign(window, {
  PHONE_DISPLAY, PHONE_HREF, EMAIL, LOCATION,
  SERVICES, DIFFERENTIATORS, FAQS, SERVICE_AREAS, THEMES,
  Icon, QuoteForm, FAQAccordion, ServiceTabs,
  BrandWordmark, BrandMark,
});
