/* S5 — intake: photo + consent + pet details, ending at payment. */
const DSi = window.SparkleClassicDesignSystem_7a1470;

const emailOk = (v) => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v.trim());
const slugify = (v) => v.toLowerCase().trim().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');

/* Downscale an image (object URL) to a JPEG data URL, to stay well under the
   serverless body cap (~4.5MB) and keep Turso rows small. The artist only needs
   it for tracing, so ~1400px is plenty. */
function downscaleToDataUrl(srcUrl, maxDim, quality) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      const scale = Math.min(1, maxDim / Math.max(img.width, img.height));
      const w = Math.max(1, Math.round(img.width * scale));
      const h = Math.max(1, Math.round(img.height * scale));
      const c = document.createElement('canvas');
      c.width = w; c.height = h;
      c.getContext('2d').drawImage(img, 0, 0, w, h);
      resolve(c.toDataURL('image/jpeg', quality));
    };
    img.onerror = () => reject(new Error('We could not read that photo. Please try another.'));
    img.src = srcUrl;
  });
}

/* ---- pricing ---- */
const BASE_PRICE = 29;
const TOY_PRICE = 5;
const orderTotal = (d) => BASE_PRICE + (d && d.toyAddon ? TOY_PRICE : 0);

/* Optional $5 add-on: the customer's pet's favorite toy, pixel-ified into the game.
   INTERNAL TEAM NOTE (not customer-facing): when this add-on is purchased, the toy
   sprite REPLACES the red ball pickup in the house level. */
function ToyAddon({ data, setData, showError }) {
  const { Switch, Icon, Badge, Card } = DSi;
  const [err, setErr] = React.useState(null);
  const inputRef = React.useRef(null);
  const on = !!data.toyAddon;

  const handle = (file) => {
    setErr(null);
    if (!file) return;
    if (!file.type.startsWith('image/')) { setErr("That file won’t open as a photo. Try a JPG, PNG, or HEIC."); return; }
    if (file.size > 25 * 1024 * 1024) { setErr("That photo is a bit big (over 25MB). Try another and we’ll get it."); return; }
    setData({ ...data, toyPhotoUrl: URL.createObjectURL(file), toyPhotoName: file.name });
  };

  return (
    <Card surface={on ? 'cream' : 'card'} padding="md">
      <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
        <span style={{ flex: '0 0 auto', width: 42, height: 42, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--sunshine)', color: 'var(--sprite-outline)', boxShadow: 'var(--ofx-edges)', fontSize: 20 }}>
          <Icon name="heart" />
        </span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <strong style={{ fontSize: 16, color: 'var(--plum-ink)', whiteSpace: 'nowrap' }}>Add their favorite toy</strong>
            <Badge pixel>+$5</Badge>
          </div>
          <p className="spk-muted" style={{ margin: '3px 0 0', fontSize: 13.5 }}>
            We&rsquo;ll pixel-ify their favorite toy and hide it in the game to collect.
          </p>
        </div>
      </div>

      <div style={{ marginTop: 12 }}>
        <Switch
          checked={on}
          onChange={(e) => setData({ ...data, toyAddon: e.target.checked })}
          label={on ? 'Added to your order' : 'Add the toy for $5'}
        />
      </div>

      {on && (
        <div style={{ marginTop: 12 }}>
          {!data.toyPhotoUrl ? (
            <button
              onClick={() => inputRef.current && inputRef.current.click()}
              onDragOver={(e) => e.preventDefault()}
              onDrop={(e) => { e.preventDefault(); handle(e.dataTransfer.files[0]); }}
              style={{
                width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
                padding: '20px 16px', cursor: 'pointer', color: 'var(--plum-ink)',
                background: 'var(--pink-soft)', border: '3px dashed var(--plum-ink)',
              }}>
              <span style={{ fontSize: 26 }}><Icon name="camera" /></span>
              <strong style={{ fontSize: 15 }}>Add a photo of the toy</strong>
              <span className="spk-muted" style={{ fontSize: 13, textAlign: 'center', maxWidth: 260 }}>
                One clear photo of the toy on its own.
              </span>
            </button>
          ) : (
            <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
              <img src={data.toyPhotoUrl} alt={`Toy photo: ${data.toyPhotoName}`} style={{ width: 56, height: 56, objectFit: 'cover', boxShadow: 'var(--ofx-edges)', flex: '0 0 auto' }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                  <strong style={{ fontSize: 14, color: 'var(--plum-ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 140 }}>{data.toyPhotoName}</strong>
                  <Badge tone="success" dot>Added</Badge>
                </div>
                <button onClick={() => inputRef.current && inputRef.current.click()} style={{ background: 'none', border: 'none', color: 'var(--plum-accent)', textDecoration: 'underline', cursor: 'pointer', padding: 0, fontSize: 13, marginTop: 4 }}>
                  Replace toy photo
                </button>
              </div>
            </div>
          )}
          <input ref={inputRef} type="file" accept="image/*" onChange={(e) => handle(e.target.files[0])} style={{ display: 'none' }} />
          {err && (
            <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
              <Icon name="alert" size={15} aria-hidden="true" /> {err}
            </p>
          )}
          {showError && !data.toyPhotoUrl && (
            <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
              <Icon name="alert" size={15} aria-hidden="true" /> Add a photo of the toy, or switch the add-on off.
            </p>
          )}
        </div>
      )}
    </Card>
  );
}

function PhotoUpload({ data, setData }) {
  const { Icon, Badge, Checkbox } = DSi;
  const [err, setErr] = React.useState(null);
  const inputRef = React.useRef(null);

  const handle = (file) => {
    setErr(null);
    if (!file) return;
    if (!file.type.startsWith('image/')) {
      setErr("That file won’t open as a photo. Try a JPG, PNG, or HEIC.");
      return;
    }
    if (file.size > 25 * 1024 * 1024) {
      setErr("That photo is a bit big (over 25MB). Try another and we’ll get it.");
      return;
    }
    setData({ ...data, photoUrl: URL.createObjectURL(file), photoName: file.name });
  };

  return (
    <div>
      {!data.photoUrl ? (
        <button
          onClick={() => inputRef.current && inputRef.current.click()}
          onDragOver={(e) => e.preventDefault()}
          onDrop={(e) => { e.preventDefault(); handle(e.dataTransfer.files[0]); }}
          style={{
            width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
            padding: '26px 16px', cursor: 'pointer', color: 'var(--plum-ink)',
            background: 'var(--pink-soft)', border: '3px dashed var(--plum-ink)',
          }}>
          <span style={{ fontSize: 32 }}><Icon name="camera" /></span>
          <strong style={{ fontSize: 16 }}>Add your pet&rsquo;s photo</strong>
          <span className="spk-muted" style={{ fontSize: 13, textAlign: 'center', maxWidth: 260 }}>
            Clear, well-lit, facing the camera. One pet per game.
          </span>
        </button>
      ) : (
        <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
          <img src={data.photoUrl} alt={`Your photo: ${data.photoName}`} style={{
            width: 64, height: 64, objectFit: 'cover', boxShadow: 'var(--ofx-edges)', flex: '0 0 auto',
          }} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
              <strong style={{ fontSize: 14, color: 'var(--plum-ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 150 }}>{data.photoName}</strong>
              <Badge tone="success" dot>Added</Badge>
            </div>
            <button onClick={() => inputRef.current && inputRef.current.click()} style={{ background: 'none', border: 'none', color: 'var(--plum-accent)', textDecoration: 'underline', cursor: 'pointer', padding: 0, fontSize: 13, marginTop: 4 }}>
              Replace photo
            </button>
          </div>
        </div>
      )}
      <input ref={inputRef} type="file" accept="image/*" onChange={(e) => handle(e.target.files[0])} style={{ display: 'none' }} />

      {err && (
        <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
          <Icon name="alert" size={15} aria-hidden="true" /> {err}
        </p>
      )}

      {/* consent — appears with the photo */}
      <div style={{ marginTop: 14, paddingTop: 14, borderTop: '2px solid var(--border-soft)' }}>
        <Checkbox
          checked={!!data.consent}
          onChange={(e) => setData({ ...data, consent: e.target.checked })}
          label={<span>I understand my photo is used only to make my pet&rsquo;s sprite, and is deleted after my game is made. <a href="#privacy">Privacy policy</a></span>}
        />
      </div>
    </div>
  );
}

function IntakeScreen({ data, setData, onContinue, onBack }) {
  const { Button, Card, Input, Select, Textarea, Icon } = DSi;
  const [touched, setTouched] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [submitErr, setSubmitErr] = React.useState(null);
  const set = (patch) => setData({ ...data, ...patch });

  const petName = data.petName || '';
  const slug = slugify(petName) || 'your-pet';

  const petErr = touched && !petName.trim() ? 'Your hero needs a name — the game is named after them.' : undefined;
  const emailErr = touched && !emailOk(data.email || '') ? "That doesn’t look like an email." : undefined;
  const photoErr = touched && !data.photoUrl;
  const consentErr = touched && !data.consent;
  const toyErr = touched && !!data.toyAddon && !data.toyPhotoUrl;
  const total = orderTotal(data);

  const submit = async () => {
    setTouched(true);
    setSubmitErr(null);
    if (!petName.trim() || !emailOk(data.email || '') || !data.photoUrl || !data.consent) return;
    if (data.toyAddon && !data.toyPhotoUrl) return;
    setSubmitting(true);
    try {
      const photo = await downscaleToDataUrl(data.photoUrl, 1400, 0.82);
      let toyPhoto;
      if (data.toyAddon && data.toyPhotoUrl) toyPhoto = await downscaleToDataUrl(data.toyPhotoUrl, 1000, 0.82);
      const res = await fetch('/api/create-checkout', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          email: (data.email || '').trim(),
          customerName: data.customerName || '',
          petName: petName.trim(),
          slug,
          notes: data.notes || '',
          photo, photoMime: 'image/jpeg', photoName: data.photoName || 'pet.jpg',
          addon: !!data.toyAddon,
          toyPhoto,
        }),
      });
      const out = await res.json().catch(() => ({}));
      if (!res.ok || !out.url) throw new Error(out.error || 'We could not start checkout. Please try again.');
      window.location.href = out.url;
    } catch (e) {
      setSubmitting(false);
      setSubmitErr((e && e.message) || 'Something went wrong. Please try again.');
    }
  };

  if (submitting) {
    return (
      <div style={{ padding: '64px 24px', textAlign: 'center', minHeight: 420, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
        <div className="spk-spin" style={{
          width: 46, height: 46, boxShadow: 'var(--ofx-edges)', borderRadius: '50%',
          borderTop: '4px solid var(--plum-ink)', borderRight: '4px solid transparent',
          marginBottom: 20,
        }} aria-hidden="true" />
        <h2 className="spk-h2" style={{ fontSize: 22, margin: '0 0 6px' }}>Taking you to secure checkout&hellip;</h2>
        <p className="spk-muted" style={{ fontSize: 14, margin: 0 }}>One moment while we lock things in.</p>
      </div>
    );
  }

  return (
    <div style={{ padding: '2px 18px 30px' }}>
      <StepRail step={0} />
      <h1 className="spk-h2" style={{ fontSize: 25, textAlign: 'center', margin: '16px 0 4px' }}>Tell us about your pet</h1>
      <p className="spk-muted" style={{ textAlign: 'center', margin: '0 0 18px', fontSize: 14 }}>It takes about a minute.</p>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <Input
          label="Where should we send your game link?"
          type="email" inputMode="email" placeholder="you@email.com"
          leftIcon={<Icon name="mail" />}
          value={data.email || ''} onChange={(e) => set({ email: e.target.value })}
          onBlur={() => setTouched(true)} error={emailErr} required
        />
        <Input
          label="Your name"
          placeholder="e.g. Dana"
          value={data.customerName || ''} onChange={(e) => set({ customerName: e.target.value })}
        />

        {/* Pet name + live link */}
        <div>
          <Input
            label="Your pet's name" placeholder="e.g. Buttercup" required
            value={petName} onChange={(e) => set({ petName: e.target.value })}
            onBlur={() => setTouched(true)} error={petErr}
            hint={!petErr ? 'This becomes the hero’s name and the game’s private link.' : undefined}
          />
          <div style={{
            marginTop: 8, display: 'flex', alignItems: 'center', gap: 8, padding: '9px 12px',
            background: 'var(--cream)', boxShadow: 'var(--ofx-edges)',
          }}>
            <Icon name="link" size={16} aria-hidden="true" />
            <span style={{ fontFamily: 'var(--font-pixel)', fontSize: 10, color: 'var(--plum-ink)', wordBreak: 'break-all' }}>
              sparkleclassic.com/<span style={{ color: 'var(--plum-accent)' }}>{slug}</span>
            </span>
          </div>
        </div>

        {/* Photo + consent */}
        <Card surface="card" padding="md">
          <label className="spk-field__label" style={{ display: 'block', marginBottom: 8, fontWeight: 700, color: 'var(--plum-ink)' }}>
            Pet photo <span style={{ color: 'var(--danger)' }} aria-hidden="true">*</span>
          </label>
          <PhotoUpload data={data} setData={setData} />
          {photoErr && (
            <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
              <Icon name="alert" size={15} aria-hidden="true" /> Please add a clear photo so we can make your sprite.
            </p>
          )}
          {!photoErr && consentErr && (
            <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
              <Icon name="alert" size={15} aria-hidden="true" /> Please confirm the photo note so we can start.
            </p>
          )}
        </Card>

        {/* Optional $5 add-on — favorite toy */}
        <ToyAddon data={data} setData={setData} showError={toyErr} />

        {/* World choice paused (still deciding the world system); art styles coming soon. */}
        <Select label="Art style" options={['Classic 8-bit']}
          defaultValue="Classic 8-bit" disabled hint="More styles coming soon ✨"
          aria-label="Art style, more coming soon" />

        <Textarea
          label="Anything we should know about your pet?" rows={3} maxLength={240}
          placeholder="Markings, personality, favorite toy, nicknames…"
          hint="Optional — helps us capture them."
          value={data.notes || ''} onChange={(e) => set({ notes: e.target.value })}
        />
      </div>

      <div style={{ display: 'flex', gap: 10, marginTop: 22 }}>
        <Button variant="ghost" onClick={onBack} leftIcon={<Icon name="arrow-left" />}>Back</Button>
        <Button variant="primary" fullWidth onClick={submit} rightIcon={<Icon name="arrow-right" />}>
          {`Continue to payment · $${total}`}
        </Button>
      </div>
      {submitErr && (
        <p className="spk-field__error" role="alert" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, marginTop: 12, color: 'var(--danger)', fontSize: 13, fontWeight: 700 }}>
          <Icon name="alert" size={15} aria-hidden="true" /> {submitErr}
        </p>
      )}
      <p className="spk-muted" style={{ textAlign: 'center', fontSize: 12.5, marginTop: 12 }}>
        Next: secure payment. Your game is made by a real person and delivered in about 24 hours.
      </p>
    </div>
  );
}

Object.assign(window, { IntakeScreen, slugify, emailOk, orderTotal, BASE_PRICE, TOY_PRICE });
