/* Screens 5-9, i18n-aware, expanded medical, PDF download */

// ═════════════════════════════════════════════════════════
// SCREEN 5 — Medical (4 sections, sub-questions)
// ═════════════════════════════════════════════════════════
function ScreenMedical({ navigate, state, setState, t }) {
  const med = state.medical || {};
  const answers = med.answers || {};
  const details = med.details || {};
  const isAdv = state.activity === 'advanced';
  const totalSteps = isAdv ? 6 : 5;
  const setA = (id, v) => setState(s => ({ ...s, medical: { ...s.medical, answers: { ...(s.medical?.answers || {}), [id]: v } } }));
  const setD = (id, v) => setState(s => ({ ...s, medical: { ...s.medical, details: { ...(s.medical?.details || {}), [id]: v } } }));

  const allIds = ALL_MED_IDS();
  const answered = allIds.filter(id => answers[id] != null).length;
  const totalQ = allIds.length;
  const allAnswered = answered === totalQ;
  const hasYes = allIds.some(id => answers[id] === true);
  const next = isAdv ? 'credentials' : 'selfie';

  return (
    <Phone>
      <div className="screen">
        <Chrome onBack={() => navigate('physical')} step={3} totalSteps={totalSteps} label={`${t('medical')} · 3/5`} />
        <div className="screen-scroll" style={{ padding: '4px 20px 130px' }}>
          <div className="eyebrow">{t('medical')}</div>
          <h1 className="h1" style={{ marginTop: 4 }}>{t('medicalTitle')}</h1>
          <p className="sub">{t('medicalSub')}</p>

          <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: '#EEF5FB', border: '1px solid #BED8EE', borderRadius: 12, padding: 12, marginTop: 16 }}>
            <div style={{ width: 40, height: 40, borderRadius: '50%', background: BRAND.blue, color: '#fff', display: 'grid', placeItems: 'center', fontSize: 13, fontWeight: 700, flexShrink: 0, fontFamily: 'Archivo Black' }}>
              {answered}/{totalQ}
            </div>
            <div style={{ fontSize: 12, lineHeight: 1.45, color: '#0B3D69' }}>
              {t('yesNoNote')}
            </div>
          </div>

          {MEDICAL_SECTIONS.map(sec => (
            <div key={sec.id} style={{ marginTop: 22 }}>
              <div style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '10px 12px', background: BRAND.blue, color: '#fff',
                borderRadius: 10,
              }}>
                <div style={{ fontFamily: 'Archivo Black', fontSize: 18, color: BRAND.yellow }}>{sec.id}</div>
                <div className="display" style={{ fontSize: 13, letterSpacing: '0.02em' }}>{t(sec.titleKey).replace(/^[A-D] · /, '')}</div>
                <div style={{ marginLeft: 'auto', fontSize: 10, opacity: 0.7 }}>
                  {sec.qs.filter(q => answers[q.id] != null).length}/{sec.qs.length}
                </div>
              </div>

              <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 10 }}>
                {sec.qs.map((q, i) => {
                  const a = answers[q.id];
                  const needDesc = a === true;
                  return (
                    <div key={q.id} style={{
                      border: '1.5px solid ' + (a == null ? 'var(--line)' : (a ? '#F7C3C1' : '#BFE8CE')),
                      borderRadius: 12, padding: 10,
                      background: a == null ? '#fff' : (a ? '#FFF7F6' : '#F6FDF9'),
                      transition: 'all 0.2s',
                    }}>
                      <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
                        <div style={{ width: 22, height: 22, borderRadius: 6, background: BRAND.ink, color: '#fff', fontFamily: 'Archivo Black', fontSize: 9, display: 'grid', placeItems: 'center', flexShrink: 0 }}>{q.id}</div>
                        <div style={{ flex: 1, fontSize: 12.5, lineHeight: 1.4, color: 'var(--ink)', paddingTop: 2 }}>{t(q.key)}</div>
                      </div>
                      <div style={{ marginTop: 8 }}>
                        <YesNoI18n value={a} onChange={v => setA(q.id, v)} t={t}/>
                      </div>
                      {needDesc && (
                        <div style={{ marginTop: 8 }}>
                          <textarea
                            className="input"
                            style={{ height: 58, padding: 10, resize: 'none', fontSize: 12, fontFamily: 'inherit' }}
                            placeholder={t('pleaseDescribe')}
                            value={details[q.id] || ''}
                            onChange={e => setD(q.id, e.target.value)}
                          />
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          ))}

          {hasYes && (
            <div style={{ marginTop: 16, padding: 14, background: '#FFF4E5', border: '1px solid #FFD29A', borderRadius: 12, display: 'flex', gap: 10 }}>
              <div style={{ fontSize: 18 }}>🏥</div>
              <div style={{ fontSize: 12, lineHeight: 1.45, color: '#7A4A00' }}>{t('doctorNeeded')}</div>
            </div>
          )}

          <p style={{ fontSize: 10, color: 'var(--muted)', lineHeight: 1.55, marginTop: 16, fontStyle: 'italic' }}>
            {t('medicalLegalBlock')}
          </p>
        </div>

        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '14px 20px 28px', background: 'linear-gradient(180deg, rgba(255,255,255,0) 0%, #fff 40%)' }}>
          <button className="btn btn-primary" disabled={!allAnswered} onClick={() => navigate(next)}>
            {allAnswered ? t('continue') : t('answerMore')(totalQ - answered)}
            {allAnswered && <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7h10M7 2l5 5-5 5" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>}
          </button>
        </div>
      </div>
    </Phone>
  );
}

function YesNoI18n({ value, onChange, t }) {
  return (
    <div className="yn-row">
      <button className="yn-btn" data-state={value === true ? 'yes-on' : 'off'} onClick={() => onChange(true)}>
        {value === true && <CheckIcon size={12} />} {t('yes')}
      </button>
      <button className="yn-btn" data-state={value === false ? 'no-on' : 'off'} onClick={() => onChange(false)}>
        {value === false && <CheckIcon size={12} />} {t('no')}
      </button>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
// SCREEN 6 — Credentials
// ═════════════════════════════════════════════════════════
function ScreenCredentials({ navigate, state, setState, t }) {
  const c = state.creds || {};
  const set = (k, v) => setState(s => ({ ...s, creds: { ...s.creds, [k]: v } }));
  const hasIns = c.hasInsurance;

  return (
    <Phone>
      <div className="screen">
        <Chrome onBack={() => navigate('medical')} step={3.5} totalSteps={6} label={`${t('creds')} · 3½/5`} />
        <div className="screen-scroll" style={{ padding: '4px 20px 130px' }}>
          <div className="eyebrow">{t('creds')}</div>
          <h1 className="h1" style={{ marginTop: 4 }}>{t('credsTitle')}</h1>
          <p className="sub">{t('credsSub')}</p>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 20 }}>
            <Field label={t('agency')} required>
              <Select value={c.agency} onChange={v => set('agency', v)} placeholder={t('selectAgency')}
                options={['PADI','SSI','CMAS','NAUI','BSAC','SDI/TDI','RAID','Other']}/>
            </Field>
            <Field label={t('level')} required>
              <Input value={c.level} onChange={v => set('level', v)} placeholder={t('levelPlaceholder')} filled={!!c.level}/>
            </Field>
            <Field label={t('certNumber')}>
              <Input value={c.certNumber} onChange={v => set('certNumber', v)} placeholder="PADI-1234567" filled={!!c.certNumber}/>
            </Field>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
              <Field label={t('loggedDives')}>
                <Input type="number" value={c.logs} onChange={v => set('logs', v)} placeholder="120" filled={!!c.logs}/>
              </Field>
              <Field label={t('lastDive')}>
                <Input type="date" value={c.lastDive || '2026-02-18'} onChange={v => set('lastDive', v)}/>
              </Field>
            </div>

            <Field label={t('certCard')} required hint={t('certCardHint')}>
              <div style={{
                border: '2px dashed ' + (c.certPhoto ? BRAND.blue : 'var(--line)'),
                borderRadius: 14, padding: 18,
                background: c.certPhoto ? '#F2F8FD' : 'var(--bg-soft)',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10, cursor: 'pointer',
              }} onClick={() => set('certPhoto', !c.certPhoto)}>
                {c.certPhoto ? (
                  <>
                    <div style={{ width: 160, height: 100, borderRadius: 8, background: 'linear-gradient(135deg, #1A6BB5, #00AEEF)', position: 'relative', overflow: 'hidden', boxShadow: '0 8px 16px -8px rgba(26,107,181,0.5)' }}>
                      <div style={{ position: 'absolute', top: 10, left: 10, color: '#fff', fontSize: 8, letterSpacing: '0.1em' }}>PADI · PROFESSIONAL</div>
                      <div style={{ position: 'absolute', bottom: 32, left: 10, color: '#fff', fontFamily: 'Archivo Black', fontSize: 11 }}>ADVANCED OPEN WATER</div>
                      <div style={{ position: 'absolute', bottom: 18, left: 10, color: '#fff', fontSize: 9, opacity: 0.8 }}>{state.personal?.firstName || 'MAYA'} {state.personal?.lastName || 'RUIZ'}</div>
                      <div style={{ position: 'absolute', bottom: 8, left: 10, color: BRAND.yellow, fontSize: 8, fontFamily: 'monospace' }}>#PADI-1234567</div>
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--muted)' }}>{t('tapReupload')}</div>
                  </>
                ) : (
                  <>
                    <div style={{ fontSize: 36 }}>📷</div>
                    <div style={{ fontFamily: 'Archivo Black', fontSize: 14, color: BRAND.blue }}>{t('uploadTitle')}</div>
                    <div style={{ fontSize: 11, color: 'var(--muted)', textAlign: 'center' }}>{t('uploadSub')}<br/><span style={{ fontSize: 10 }}>{t('uploadFmt')}</span></div>
                    <div style={{ display: 'flex', gap: 8, marginTop: 4 }}>
                      <span className="chip">{t('camera')}</span>
                      <span className="chip cyan">{t('gallery')}</span>
                    </div>
                  </>
                )}
              </div>
            </Field>

            <div style={{ marginTop: 10, paddingTop: 16, borderTop: '1px dashed var(--line)' }}>
              <div className="eyebrow">{t('insurance')}</div>
              <div style={{ marginTop: 10 }}>
                <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 10 }}>{t('hasInsurance')}</div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button className="yn-btn" data-state={hasIns === true ? 'no-on' : 'off'} onClick={() => set('hasInsurance', true)}>
                    {hasIns === true && <CheckIcon size={12}/>} {t('yesHave')}
                  </button>
                  <button className="yn-btn" data-state={hasIns === false ? 'yes-on' : 'off'} onClick={() => set('hasInsurance', false)}>
                    {hasIns === false && <CheckIcon size={12}/>} {t('no')}
                  </button>
                </div>
              </div>
              {hasIns === true && (
                <div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <Field label={t('insProvider')}><Input value={c.insProvider} onChange={v => set('insProvider', v)} placeholder="DAN Europe" filled={!!c.insProvider}/></Field>
                  <Field label={t('insPolicy')}><Input value={c.insPolicy} onChange={v => set('insPolicy', v)} placeholder="DAN-2026-…" filled={!!c.insPolicy}/></Field>
                  <Field label={t('insExpiry')}><Input type="date" value={c.insExpiry || '2026-12-31'} onChange={v => set('insExpiry', v)}/></Field>
                </div>
              )}
              {hasIns === false && (
                <div style={{ marginTop: 14, padding: 14, background: BRAND.yellow + '2A', border: '1px solid ' + BRAND.yellow + 'AA', borderRadius: 12, display: 'flex', gap: 10 }}>
                  <div style={{ fontSize: 20 }}>🛟</div>
                  <div style={{ fontSize: 12, lineHeight: 1.5, color: '#5C4600' }}>
                    <b>{t('noWorries')}</b> {t('noInsBody')}
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>

        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '14px 20px 28px', background: 'linear-gradient(180deg, rgba(255,255,255,0) 0%, #fff 40%)' }}>
          <button className="btn btn-primary" onClick={() => navigate('selfie')}>{t('continue')}</button>
        </div>
      </div>
    </Phone>
  );
}

// ═════════════════════════════════════════════════════════
// SCREEN 7 — Selfie
// ═════════════════════════════════════════════════════════
function ScreenSelfie({ navigate, state, setState, t }) {
  const [stage, setStage] = React.useState(state.selfieDone ? 'done' : 'empty');
  const [camError, setCamError] = React.useState('');
  const isAdv = state.activity === 'advanced';
  const back = isAdv ? 'credentials' : 'medical';
  const videoRef = React.useRef(null);
  const streamRef = React.useRef(null);
  const fileInputRef = React.useRef(null);

  // Stop camera when leaving viewfinder
  const stopCamera = React.useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach(t => t.stop());
      streamRef.current = null;
    }
  }, []);

  React.useEffect(() => () => stopCamera(), [stopCamera]);

  // Start camera when entering viewfinder
  React.useEffect(() => {
    if (stage !== 'viewfinder') { stopCamera(); return; }
    let cancelled = false;
    setCamError('');
    (async () => {
      try {
        if (!navigator.mediaDevices?.getUserMedia) {
          throw new Error('no-api');
        }
        const stream = await navigator.mediaDevices.getUserMedia({
          video: { facingMode: 'user', width: { ideal: 720 }, height: { ideal: 960 } },
          audio: false,
        });
        if (cancelled) { stream.getTracks().forEach(t => t.stop()); return; }
        streamRef.current = stream;
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
          videoRef.current.play().catch(() => {});
        }
      } catch (err) {
        console.error('Camera error:', err);
        const msg = err?.name === 'NotAllowedError' ? 'permission'
                  : err?.name === 'NotFoundError' ? 'no-camera'
                  : err?.message === 'no-api' ? 'no-api'
                  : 'other';
        setCamError(msg);
      }
    })();
    return () => { cancelled = true; stopCamera(); };
  }, [stage, stopCamera]);

  // Capture frame from live video
  const captureFromCamera = () => {
    const video = videoRef.current;
    if (!video || !video.videoWidth) return;
    const canvas = document.createElement('canvas');
    // Portrait 3:4 crop
    const vw = video.videoWidth, vh = video.videoHeight;
    const targetRatio = 3 / 4;
    let sw = vw, sh = vh, sx = 0, sy = 0;
    if (vw / vh > targetRatio) {
      sw = vh * targetRatio; sx = (vw - sw) / 2;
    } else {
      sh = vw / targetRatio; sy = (vh - sh) / 2;
    }
    canvas.width = 600; canvas.height = 800;
    const ctx = canvas.getContext('2d');
    // Mirror to match what user sees
    ctx.translate(canvas.width, 0);
    ctx.scale(-1, 1);
    ctx.drawImage(video, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);
    const dataUrl = canvas.toDataURL('image/jpeg', 0.85);
    stopCamera();
    setState(s => ({ ...s, selfieDone: true, selfieDataUrl: dataUrl }));
    setStage('done');
  };

  // Handle file from gallery/native camera
  const handleFile = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      const img = new Image();
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const targetRatio = 3 / 4;
        let sw = img.width, sh = img.height, sx = 0, sy = 0;
        if (img.width / img.height > targetRatio) {
          sw = img.height * targetRatio; sx = (img.width - sw) / 2;
        } else {
          sh = img.width / targetRatio; sy = (img.height - sh) / 2;
        }
        canvas.width = 600; canvas.height = 800;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);
        const dataUrl = canvas.toDataURL('image/jpeg', 0.85);
        setState(s => ({ ...s, selfieDone: true, selfieDataUrl: dataUrl }));
        setStage('done');
      };
      img.src = reader.result;
    };
    reader.readAsDataURL(file);
    e.target.value = '';
  };

  const openGallery = () => fileInputRef.current?.click();

  return (
    <Phone>
      <div className="screen">
        <Chrome onBack={() => navigate(back)} step={4} totalSteps={5} label={`${t('photo')} · 4/5`} />
        <div className="screen-scroll" style={{ padding: '4px 20px 130px' }}>
          <div className="eyebrow">{t('photo')}</div>
          <h1 className="h1" style={{ marginTop: 4 }}>{t('photoTitle')}</h1>
          <p className="sub">{t('photoSub')}</p>

          {stage === 'empty' && (
            <>
              <div style={{ marginTop: 22, aspectRatio: '3/4', background: 'linear-gradient(180deg, #E7F3FB 0%, #CBE4F4 100%)', borderRadius: 18, border: '2px dashed #9EC7E4', position: 'relative', overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <img src="assets/atlas-clean.png" alt="" style={{ width: 170, animation: 'floatMascot 4s ease-in-out infinite', filter: 'drop-shadow(0 8px 20px rgba(0,0,0,0.2))' }}/>
                {[0,1,2,3].map(i => (
                  <div key={i} style={{
                    position: 'absolute',
                    ...(i < 2 ? { top: 16 } : { bottom: 16 }),
                    ...(i % 2 === 0 ? { left: 16 } : { right: 16 }),
                    width: 28, height: 28,
                    borderColor: BRAND.blue, borderStyle: 'solid', borderWidth: 0,
                    borderTopWidth: i < 2 ? 3 : 0,
                    borderBottomWidth: i >= 2 ? 3 : 0,
                    borderLeftWidth: i % 2 === 0 ? 3 : 0,
                    borderRightWidth: i % 2 === 1 ? 3 : 0,
                    borderRadius: 6,
                  }}/>
                ))}
                <div style={{ position: 'absolute', top: 14, left: 0, right: 0, textAlign: 'center', fontSize: 10, color: BRAND.blue, letterSpacing: '0.1em', fontWeight: 700 }}>{t('photoBooth')}</div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
                <button className="btn btn-primary" onClick={() => setStage('viewfinder')}><span style={{ fontSize: 16 }}>📷</span> {t('takeSelfie')}</button>
                <button className="btn btn-ghost" onClick={openGallery}><span style={{ fontSize: 16 }}>🖼️</span> {t('chooseGallery')}</button>
                <input ref={fileInputRef} type="file" accept="image/*" onChange={handleFile} style={{ display: 'none' }}/>
              </div>
              <p style={{ fontSize: 11, color: 'var(--muted)', textAlign: 'center', marginTop: 14, lineHeight: 1.5 }}>{t('photoTip')}</p>
            </>
          )}

          {stage === 'viewfinder' && (
            <>
              <div style={{ marginTop: 22, aspectRatio: '3/4', background: '#0A0A0A', borderRadius: 18, position: 'relative', overflow: 'hidden' }}>
                {!camError && (
                  <video
                    ref={videoRef}
                    autoPlay
                    playsInline
                    muted
                    style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', transform: 'scaleX(-1)' }}
                  />
                )}
                {camError && (
                  <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', color: '#fff', padding: 24, textAlign: 'center', gap: 10 }}>
                    <div style={{ fontSize: 32 }}>📷</div>
                    <div style={{ fontSize: 13, fontWeight: 700 }}>
                      {camError === 'permission' && (t('camPermission') || 'Permiso de cámara denegado')}
                      {camError === 'no-camera' && (t('camNotFound') || 'No se encontró cámara')}
                      {camError === 'no-api' && (t('camNotSupported') || 'Cámara no soportada en este navegador')}
                      {camError === 'other' && (t('camError') || 'No se pudo iniciar la cámara')}
                    </div>
                    <div style={{ fontSize: 11, opacity: 0.75, lineHeight: 1.5, maxWidth: 240 }}>
                      {camError === 'permission'
                        ? (t('camPermissionHelp') || 'Activa el acceso a la cámara en ajustes del navegador, o usa la galería.')
                        : (t('camErrorHelp') || 'Prueba subir una foto desde la galería.')}
                    </div>
                  </div>
                )}
                {!camError && (
                  <div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-50%)', width: '55%', aspectRatio: '3/4', border: '2px dashed rgba(255,255,255,0.55)', borderRadius: '50%', pointerEvents: 'none' }}/>
                )}
                {!camError && (
                  <div style={{ position: 'absolute', top: 12, left: 0, right: 0, textAlign: 'center', color: '#fff', fontSize: 11 }}>
                    <span style={{ background: 'rgba(0,0,0,0.4)', padding: '4px 10px', borderRadius: 999 }}>{t('centerFace')}</span>
                  </div>
                )}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
                {!camError ? (
                  <button className="btn btn-yellow" onClick={captureFromCamera}>
                    <div style={{ width: 24, height: 24, borderRadius: '50%', border: '3px solid ' + BRAND.ink }}/> {t('capture')}
                  </button>
                ) : (
                  <button className="btn btn-primary" onClick={openGallery}><span style={{ fontSize: 16 }}>🖼️</span> {t('chooseGallery')}</button>
                )}
                <button className="btn btn-ghost" onClick={() => { stopCamera(); setStage('empty'); }}>{t('cancel')}</button>
                <input ref={fileInputRef} type="file" accept="image/*" onChange={handleFile} style={{ display: 'none' }}/>
              </div>
            </>
          )}

          {stage === 'done' && (
            <>
              <div style={{ marginTop: 22, aspectRatio: '3/4', borderRadius: 18, position: 'relative', overflow: 'hidden', background: '#0A0A0A', boxShadow: '0 20px 40px -10px rgba(8, 44, 79, 0.35)' }}>
                {state.selfieDataUrl ? (
                  <img src={state.selfieDataUrl} alt="Selfie" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}/>
                ) : (
                  <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, #9DC6E1 0%, #1A6BB5 100%)' }}/>
                )}
                <div style={{ position: 'absolute', top: 12, left: 12, background: 'rgba(0,0,0,0.5)', color: '#fff', fontSize: 10, padding: '4px 8px', borderRadius: 999, fontFamily: 'monospace' }}>
                  ✓ {t('captured')} · {state.personal?.firstName || 'Diver'}
                </div>
                <div style={{ position: 'absolute', bottom: 12, left: 12, right: 12, background: 'rgba(255,255,255,0.95)', borderRadius: 10, padding: 10, display: 'flex', alignItems: 'center', gap: 8 }}>
                  <div style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--ok)', display: 'grid', placeItems: 'center', color: '#fff' }}><CheckIcon size={14}/></div>
                  <div style={{ flex: 1, fontSize: 11, fontWeight: 600 }}>{t('faceOk')}</div>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
                <button className="btn btn-primary" onClick={() => navigate('legal')}>{t('looksGood')} <CheckIcon size={14} color="#fff"/></button>
                <button className="btn btn-ghost" onClick={() => setStage('empty')}>{t('retake')}</button>
              </div>
            </>
          )}
        </div>
      </div>
    </Phone>
  );
}

// ═════════════════════════════════════════════════════════
// SCREEN 8 — Legal & Signature
// ═════════════════════════════════════════════════════════
function ScreenLegal({ navigate, state, setState, t, lang }) {
  const [open, setOpen] = React.useState('medical');
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState('');
  const legal = state.legal || {};
  const set = (k, v) => setState(s => ({ ...s, legal: { ...s.legal, [k]: v } }));

  const [hasSig, setHasSig] = React.useState(!!legal.signed);
  const canvasRef = React.useRef(null);
  const drawingRef = React.useRef(false);
  const lastRef = React.useRef(null);

  React.useEffect(() => {
    const c = canvasRef.current;
    if (!c) return;
    const dpr = window.devicePixelRatio || 1;
    const rect = c.getBoundingClientRect();
    c.width = rect.width * dpr;
    c.height = rect.height * dpr;
    const ctx = c.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.strokeStyle = BRAND.blue;
    ctx.lineWidth = 2.5;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
  }, []);

  const getPos = (e) => {
    const c = canvasRef.current;
    const rect = c.getBoundingClientRect();
    const p = e.touches ? e.touches[0] : e;
    return { x: p.clientX - rect.left, y: p.clientY - rect.top };
  };

  const saveSigImage = () => {
    const url = canvasRef.current.toDataURL('image/png');
    setState(s => ({ ...s, legal: { ...s.legal, signed: true, sigDataUrl: url, sigTimestamp: new Date().toISOString() } }));
  };

  const start = (e) => {
    e.preventDefault();
    drawingRef.current = true;
    lastRef.current = getPos(e);
    setHasSig(true);
  };
  const move = (e) => {
    if (!drawingRef.current) return;
    e.preventDefault();
    const p = getPos(e);
    const ctx = canvasRef.current.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(lastRef.current.x, lastRef.current.y);
    ctx.lineTo(p.x, p.y);
    ctx.stroke();
    lastRef.current = p;
  };
  const end = () => {
    if (drawingRef.current) {
      drawingRef.current = false;
      saveSigImage();
    }
  };

  const clearSig = () => {
    const c = canvasRef.current;
    c.getContext('2d').clearRect(0, 0, c.width, c.height);
    setHasSig(false);
    setState(s => ({ ...s, legal: { ...s.legal, signed: false, sigDataUrl: null } }));
  };

  const canSubmit = legal.acceptMed && legal.acceptPriv && legal.acceptImg && hasSig;

  const setAccept = (k) => {
    const now = new Date().toISOString();
    setState(s => {
      const prev = !!s.legal?.[k];
      return { ...s, legal: { ...s.legal, [k]: !prev, [k + 'At']: !prev ? now : null } };
    });
  };

  const sections = [
    { id: 'medical', tag: t('secMedical'), title: t('secMedicalTitle'), body: (<>
      <p>{t('medicalLegal1')}</p><p>{t('medicalLegal2')}</p><p>{t('medicalLegal3')}</p>
    </>), check: 'acceptMed' },
    { id: 'priv', tag: t('secPriv'), title: t('secPrivTitle'), body: (<>
      <p>{t('privLegal1')}</p><p>{t('privLegal2')}</p><p>{t('privLegal3')}</p>
      <p style={{ fontSize: 10, color: 'var(--muted)' }}>{t('privController')}</p>
    </>), check: 'acceptPriv' },
    { id: 'img', tag: t('secImg'), title: t('secImgTitle'), body: (<>
      <p>{t('imgLegal1')}</p><p>{t('imgLegal2')}</p><p>{t('imgLegal3')}</p>
    </>), check: 'acceptImg' },
  ];

  return (
    <Phone>
      <div className="screen">
        <Chrome onBack={() => navigate('selfie')} step={5} totalSteps={5} label={`${t('almost')} · 5/5`} />
        <div className="screen-scroll" style={{ padding: '4px 20px 170px' }}>
          <div className="eyebrow">{t('almost')}</div>
          <h1 className="h1" style={{ marginTop: 4 }}>{t('legalTitle')}</h1>
          <p className="sub">{t('legalSub')}</p>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
            {sections.map(s => {
              const checked = !!legal[s.check];
              const isOpen = open === s.id;
              return (
                <div key={s.id} className={"acc-item" + (checked ? ' checked' : '')}>
                  <div className="acc-head" onClick={() => setOpen(isOpen ? null : s.id)}>
                    <div onClick={(e) => { e.stopPropagation(); setAccept(s.check); }} style={{ display: 'inline-flex' }}>
                      <Checkbox checked={checked} onChange={() => {}}/>
                    </div>
                    <div className="title">
                      <small>{s.tag}</small>
                      {s.title}
                    </div>
                    <svg width="14" height="14" viewBox="0 0 14 14" style={{ transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s', flexShrink: 0 }}>
                      <path d="M2 5l5 5 5-5" stroke="var(--muted)" strokeWidth="1.8" fill="none" strokeLinecap="round"/>
                    </svg>
                  </div>
                  <div className={"acc-body" + (isOpen ? ' open' : '')}>{s.body}</div>
                </div>
              );
            })}
          </div>

          <div style={{ marginTop: 22 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
              <div className="field-label">{t('sigLabel')} <span className="req">*</span></div>
              <button onClick={clearSig} style={{ border: 'none', background: 'none', fontSize: 11, color: BRAND.blue, fontWeight: 600, cursor: 'pointer' }}>{t('clear')}</button>
            </div>
            <div className="sig-pad">
              <canvas ref={canvasRef}
                onMouseDown={start} onMouseMove={move} onMouseUp={end} onMouseLeave={end}
                onTouchStart={start} onTouchMove={move} onTouchEnd={end}/>
              {!hasSig && <div className="sig-hint">{t('sigHint')}</div>}
            </div>
            <div style={{ fontSize: 10, color: 'var(--muted)', marginTop: 6 }}>
              {t('signedBy')} {state.personal?.firstName || '—'} {state.personal?.lastName || ''} · {new Date().toLocaleDateString()}
            </div>
          </div>
        </div>

        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '14px 20px 28px', background: 'linear-gradient(180deg, rgba(255,255,255,0) 0%, #fff 40%)' }}>
          {submitError && <div style={{ fontSize: 11, color: '#c0392b', textAlign: 'center', marginBottom: 8 }}>⚠️ {submitError}</div>}
          <button className="btn btn-primary" disabled={!canSubmit || submitting} onClick={async () => {
            const ref = 'ATL-' + Math.floor(100000 + Math.random() * 899999);
            const submittedAt = new Date().toISOString();
            const finalState = { ...state, submittedAt, bookingRef: ref };
            setState(finalState);
            setSubmitting(true);
            setSubmitError('');
            try {
              if (window.ATLANTIS_BACKEND_URL) {
                const pdfBase64 = await window.atlantisGeneratePdfBase64(finalState, lang);
                await fetch(window.ATLANTIS_BACKEND_URL, {
                  method: 'POST',
                  mode: 'no-cors',
                  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
                  body: JSON.stringify({
                    bookingRef: ref,
                    lang, activity: finalState.activity,
                    personal: finalState.personal, physical: finalState.physical,
                    creds: finalState.creds, medical: finalState.medical, legal: finalState.legal,
                    pdfBase64,
                  }),
                });
              }
              navigate('done');
            } catch (err) {
              console.error(err);
              setSubmitError((lang === 'es' ? 'Error al enviar. ' : lang === 'de' ? 'Fehler beim Senden. ' : 'Submission failed. ') + err.message);
              navigate('done');
            } finally {
              setSubmitting(false);
            }
          }}>
            {submitting ? (lang === 'es' ? 'Enviando...' : lang === 'de' ? 'Senden...' : 'Sending...') : (canSubmit ? t('complete') : t('completeDisabled'))}
            {canSubmit && !submitting && <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7l4 4 6-8" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>}
          </button>
        </div>
      </div>
    </Phone>
  );
}

// ═════════════════════════════════════════════════════════
// PDF BUILDER — shared by submit (backend) and download
// ═════════════════════════════════════════════════════════
function buildAtlantisPdf(state, lang, bookingRef) {
  const { jsPDF } = window.jspdf;
  const doc = new jsPDF({ unit: 'pt', format: 'a4' });
  const W = doc.internal.pageSize.getWidth();
  let y = 40;

  doc.setFillColor(26, 107, 181);
  doc.rect(0, 0, W, 70, 'F');
  doc.setTextColor(255, 255, 255);
  doc.setFont('helvetica', 'bold'); doc.setFontSize(18);
  doc.text('ATLANTIS DIVING LANZAROTE', 40, 35);
  doc.setFont('helvetica', 'normal'); doc.setFontSize(10);
  doc.text('Customer onboarding form · atlantislanzarote.com', 40, 52);
  y = 90;

  const p = state.personal || {};
  const ph = state.physical || {};
  const c = state.creds || {};
  const med = state.medical || {};
  const legal = state.legal || {};

  doc.setTextColor(0, 0, 0);
  doc.setFont('helvetica', 'bold'); doc.setFontSize(11);
  doc.text(`${p.firstName || ''} ${p.lastName || ''}`, 40, y);
  doc.setFont('helvetica', 'normal'); doc.setFontSize(9);
  doc.setTextColor(100);
  doc.text(`Ref: ${bookingRef}  ·  ${new Date().toLocaleString(lang)}  ·  Language: ${lang.toUpperCase()}`, 40, y + 14);
  y += 36;

  const section = (title) => {
    if (y > 760) { doc.addPage(); y = 40; }
    doc.setDrawColor(26, 107, 181); doc.setLineWidth(1.5);
    doc.line(40, y, W - 40, y);
    y += 4;
    doc.setFont('helvetica', 'bold'); doc.setFontSize(11); doc.setTextColor(26, 107, 181);
    doc.text(title, 40, y + 12);
    y += 22;
    doc.setTextColor(0);
  };
  const kv = (k, v) => {
    if (y > 790) { doc.addPage(); y = 40; }
    doc.setFont('helvetica', 'bold'); doc.setFontSize(9); doc.setTextColor(100);
    doc.text(k + ':', 40, y);
    doc.setFont('helvetica', 'normal'); doc.setTextColor(0);
    const lines = doc.splitTextToSize(String(v || '—'), W - 200);
    doc.text(lines, 180, y);
    y += Math.max(14, lines.length * 11);
  };

  section('1 · PERSONAL DETAILS');
  kv('Name', `${p.firstName || ''} ${p.lastName || ''}`);
  kv('Email', p.email);
  kv('Date of birth', p.dob);
  kv('Phone', `${p.phoneCc || ''} ${p.phone || ''}`);
  kv('Nationality', p.nationality);
  kv('Emergency contact', `${p.emName || '—'} · ${p.emPhone || '—'}`);

  section('2 · PHYSICAL DETAILS');
  kv('Height', `${ph.height || '—'} cm`);
  kv('Weight', `${ph.weight || '—'} kg`);
  kv('Wetsuit boot (EU)', ph.shoe);
  kv('Suggested suit', suggestSuit(ph.height || 170, ph.weight || 70));
  kv('Activity path', state.activity === 'advanced' ? 'Certified diver' : 'Beginner / Try dive');

  section('3 · MEDICAL DECLARATION (PADI / DAN)');
  MEDICAL_SECTIONS.forEach(sec => {
    if (y > 770) { doc.addPage(); y = 40; }
    doc.setFont('helvetica', 'bold'); doc.setFontSize(10); doc.setTextColor(26, 107, 181);
    doc.text(I18N[lang][sec.titleKey], 40, y);
    y += 14;
    doc.setTextColor(0);
    sec.qs.forEach(q => {
      if (y > 790) { doc.addPage(); y = 40; }
      const ans = med.answers?.[q.id];
      const ansStr = ans === true ? 'YES' : ans === false ? 'NO' : '—';
      doc.setFont('helvetica', 'normal'); doc.setFontSize(8.5); doc.setTextColor(60);
      const qtext = doc.splitTextToSize(`${q.id}. ${I18N[lang][q.key]}`, W - 120);
      doc.text(qtext, 48, y);
      doc.setFont('helvetica', 'bold');
      doc.setTextColor(ans === true ? 200 : ans === false ? 23 : 150, ans === true ? 50 : ans === false ? 166 : 150, ans === true ? 50 : ans === false ? 87 : 150);
      doc.text(ansStr, W - 60, y);
      y += Math.max(12, qtext.length * 10);
      if (ans === true && med.details?.[q.id]) {
        doc.setFont('helvetica', 'italic'); doc.setTextColor(100); doc.setFontSize(8);
        const dt = doc.splitTextToSize('→ ' + med.details[q.id], W - 120);
        doc.text(dt, 60, y);
        y += dt.length * 10 + 2;
      }
    });
    y += 4;
  });

  if (state.activity === 'advanced') {
    section('4 · DIVER CREDENTIALS');
    kv('Agency', c.agency);
    kv('Level', c.level);
    kv('Cert number', c.certNumber);
    kv('Logged dives', c.logs);
    kv('Last dive', c.lastDive);
    kv('Dive insurance', c.hasInsurance === true ? 'Yes' : c.hasInsurance === false ? 'No' : '—');
    if (c.hasInsurance === true) {
      kv('Insurance provider', c.insProvider);
      kv('Policy number', c.insPolicy);
      kv('Policy expiry', c.insExpiry);
    }
  }

  doc.addPage(); y = 40;
  doc.setFillColor(26, 107, 181);
  doc.rect(0, 0, W, 50, 'F');
  doc.setTextColor(255); doc.setFont('helvetica', 'bold'); doc.setFontSize(13);
  doc.text('ATTACHMENTS', 40, 30);
  y = 80;

  if (state.selfieDataUrl) {
    doc.setTextColor(0); doc.setFont('helvetica', 'bold'); doc.setFontSize(11);
    doc.text('Selfie', 40, y); y += 10;
    try { doc.addImage(state.selfieDataUrl, 'JPEG', 40, y, 150, 200); } catch (e) {}
    y += 220;
  }

  doc.setFont('helvetica', 'bold'); doc.setFontSize(11);
  doc.text('Legal consents & signature', 40, y); y += 16;
  doc.setFont('helvetica', 'normal'); doc.setFontSize(9);
  const consentRow = (label, ts) => {
    doc.text(`☑ ${label}`, 48, y);
    doc.setTextColor(100); doc.setFontSize(8);
    doc.text(ts ? `accepted ${new Date(ts).toLocaleString(lang)}` : '', 300, y);
    doc.setTextColor(0); doc.setFontSize(9);
    y += 14;
  };
  consentRow('Medical declaration', legal.acceptMedAt);
  consentRow('Privacy policy (GDPR)', legal.acceptPrivAt);
  consentRow('Image consent', legal.acceptImgAt);
  y += 10;

  if (legal.sigDataUrl) {
    doc.setFont('helvetica', 'bold'); doc.setFontSize(10);
    doc.text('Signature:', 40, y); y += 6;
    try { doc.addImage(legal.sigDataUrl, 'PNG', 40, y, 220, 80); } catch (e) {}
    y += 90;
    doc.setFont('helvetica', 'normal'); doc.setFontSize(8); doc.setTextColor(100);
    doc.text(`${p.firstName || ''} ${p.lastName || ''} · ${legal.sigTimestamp ? new Date(legal.sigTimestamp).toLocaleString(lang) : ''}`, 40, y);
  }

  doc.setTextColor(100); doc.setFont('helvetica', 'italic'); doc.setFontSize(8);
  doc.text('Atlantis Lanzarote S.L. · Puerto del Carmen, Lanzarote · hola@atlantislanzarote.com', 40, 800);
  doc.text('Processed under EU GDPR 2016/679 · This document contains confidential medical data.', 40, 814);

  return doc;
}

window.atlantisGeneratePdfBase64 = function(state, lang) {
  const ref = state.bookingRef || ('ATL-' + Math.floor(100000 + Math.random() * 899999));
  const doc = buildAtlantisPdf(state, lang, ref);
  const dataUri = doc.output('datauristring');
  return dataUri.split(',')[1];
};

// ═════════════════════════════════════════════════════════
// SCREEN 9 — Confirmation (with PDF download)
// ═════════════════════════════════════════════════════════
function ScreenDone({ navigate, state, setState, t, lang }) {
  const [busy, setBusy] = React.useState(false);
  const bookingRef = state.bookingRef || ('ATL-' + Math.floor(100000 + Math.random() * 899999));

  const downloadPdf = () => {
    if (busy) return;
    setBusy(true);
    try {
      const doc = buildAtlantisPdf(state, lang, bookingRef);
      const p = state.personal || {};
      const dateStr = new Date().toISOString().slice(0, 10);
      const safeFn = (s) => String(s || '').replace(/[^A-Za-z0-9]/g, '');
      const filename = `${safeFn(p.firstName) || 'Diver'}_${safeFn(p.lastName) || ''}_Atlantis_${dateStr}.pdf`;
      doc.save(filename);
    } catch (e) {
      console.error(e);
      alert('PDF generation failed: ' + e.message);
    }
    setTimeout(() => setBusy(false), 800);
  };

  return (
    <Phone statusDark={true} homeLight={true}>
      <div className="screen" style={{ background: 'linear-gradient(180deg, #1A6BB5 0%, #0F4D86 60%, #082C4F 100%)', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
          {[...Array(18)].map((_, i) => (
            <div key={i} style={{
              position: 'absolute', width: 3 + (i % 6) * 2, height: 3 + (i % 6) * 2,
              borderRadius: '50%', background: 'rgba(255,255,255,0.45)',
              left: `${(i * 31) % 100}%`, bottom: -20,
              animation: `bubble ${5 + (i % 5)}s ease-in ${i * 0.3}s infinite`,
            }}/>
          ))}
        </div>

        <div className="screen-scroll" style={{ position: 'relative', zIndex: 2, padding: '70px 24px 40px', flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', color: '#fff' }}>
          <div style={{ position: 'relative', marginTop: 10, animation: 'popIn 0.6s cubic-bezier(.2,1.4,.4,1)' }}>
            <div style={{ width: 110, height: 110, borderRadius: '50%', background: BRAND.yellow, display: 'grid', placeItems: 'center', boxShadow: '0 20px 40px rgba(0,0,0,0.35), inset 0 4px 8px rgba(255,255,255,0.5)' }}>
              <svg width="56" height="56" viewBox="0 0 60 60">
                <path d="M12 30 l 12 12 l 24 -24" stroke={BRAND.ink} strokeWidth="7" strokeLinecap="round" strokeLinejoin="round" fill="none" strokeDasharray="80" strokeDashoffset="80" style={{ animation: 'drawCheck 0.7s cubic-bezier(.2,.8,.2,1) 0.35s forwards' }}/>
              </svg>
            </div>
            <img src="assets/atlas-clean.png" alt="" style={{ position: 'absolute', right: -48, bottom: -10, width: 74, transform: 'rotate(8deg)', filter: 'drop-shadow(0 8px 14px rgba(0,0,0,0.3))', animation: 'floatMascot 3.5s ease-in-out infinite 0.8s' }}/>
          </div>

          <div className="display" style={{ fontSize: 30, lineHeight: 1.05, marginTop: 28 }}>{t('allSet')}</div>
          <p style={{ fontSize: 14, opacity: 0.85, marginTop: 10, maxWidth: 280, lineHeight: 1.5 }}>{t('allSetSub')}</p>

          <div style={{ marginTop: 20, background: 'rgba(255,255,255,0.1)', backdropFilter: 'blur(8px)', border: '1px solid rgba(255,255,255,0.18)', borderRadius: 18, padding: 16, width: '100%', textAlign: 'left' }}>
            <div style={{ fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: BRAND.yellow, fontWeight: 700 }}>{t('yourBooking')}</div>
            <div className="display" style={{ fontSize: 18, marginTop: 6 }}>
              {state.personal?.firstName || 'Maya'} {state.personal?.lastName || 'Ruiz'}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginTop: 14 }}>
              <div><div style={{ fontSize: 9, opacity: 0.6, letterSpacing: '0.1em', textTransform: 'uppercase' }}>{t('activity')}</div><div style={{ fontSize: 12, fontWeight: 600, marginTop: 2 }}>{state.activity === 'advanced' ? t('certifiedDiver') : t('tryDiveOW')}</div></div>
              <div><div style={{ fontSize: 9, opacity: 0.6, letterSpacing: '0.1em', textTransform: 'uppercase' }}>{t('reference')}</div><div style={{ fontSize: 12, fontWeight: 600, marginTop: 2, fontFamily: 'monospace' }}>{bookingRef}</div></div>
              <div><div style={{ fontSize: 9, opacity: 0.6, letterSpacing: '0.1em', textTransform: 'uppercase' }}>{t('wetsuitEst')}</div><div style={{ fontSize: 12, fontWeight: 600, marginTop: 2 }}>{suggestSuit(state.physical?.height || 170, state.physical?.weight || 70)}</div></div>
              <div><div style={{ fontSize: 9, opacity: 0.6, letterSpacing: '0.1em', textTransform: 'uppercase' }}>{t('boot')}</div><div style={{ fontSize: 12, fontWeight: 600, marginTop: 2 }}>EU {state.physical?.shoe || '42'}</div></div>
            </div>
          </div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, width: '100%', marginTop: 18 }}>
            <button className="btn btn-yellow" disabled={busy} onClick={downloadPdf}>
              {busy ? t('generatingPdf') : <>📄 {t('downloadPdf')}</>}
            </button>
            <button className="btn" style={{ background: 'rgba(255,255,255,0.12)', color: '#fff', border: '1px solid rgba(255,255,255,0.3)' }}>
              📅 {t('addToCal')}
            </button>
            <button className="btn" style={{ background: 'transparent', color: 'rgba(255,255,255,0.7)', border: '1px solid rgba(255,255,255,0.2)' }} onClick={() => { setState({}); navigate('language'); }}>
              {t('startNew')}
            </button>
          </div>

          <div style={{ marginTop: 16, paddingTop: 12, fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.5)' }}>atlantislanzarote.com</div>
        </div>
      </div>
    </Phone>
  );
}

Object.assign(window, {
  ScreenMedical, ScreenCredentials, ScreenSelfie, ScreenLegal, ScreenDone,
});
