/* Forms — window.ContactForm + window.AdhesionForm
   - Submits to /api/send-mail (Vercel serverless function using IONOS SMTP)
   - Sends 2 emails per submission: admin notification + sender confirmation
   - "Télécharger en PDF" opens a print-styled new tab and triggers print()
   
   ────────────────────────────────────────────────────────────────────────
   CONFIG
   
   The mailer endpoint is /api/send-mail (relative path → same-origin).
   Override MAILER_ENDPOINT below if hosting the API on a different domain.
   See api/send-mail.js + CLAUDE.md for environment variables to set in Vercel.
   
   If the endpoint is unreachable (offline / not yet deployed), forms fall
   back to opening the user's email client via mailto:.
   ──────────────────────────────────────────────────────────────────────── */
(function () {
  const { useState, useMemo, useRef } = React;
  const Icon = window.Icon;

  const MAILER_ENDPOINT = "/api/send-mail";
  const TO_EMAIL = "contact@em-alliance.org";

  async function sendMail({ kind, lang, fields, sender }) {
    try {
      const res = await fetch(MAILER_ENDPOINT, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ kind, lang, fields, sender, _hp: "" }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok || data.ok === false) return { ok: false, error: data.error || data.detail || ("HTTP " + res.status) };
      return { ok: true };
    } catch (err) {
      return { ok: false, error: err.message || String(err) };
    }
  }

  // mailto fallback when API is unreachable
  function buildMailto({ to, subject, body }) {
    const q = "subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body);
    return "mailto:" + to + "?" + q;
  }

  function openPdfWindow({ title, blocks, lang }) {
    const FR = lang === "fr";
    const win = window.open("", "_blank");
    if (!win) return;
    const blockHtml = blocks.map((b) => {
      if (b.type === "section") return `<h2>${escape(b.title)}</h2>`;
      if (b.type === "row") return `<div class="row"><div class="lbl">${escape(b.label)}</div><div class="val">${escape(b.value || "—")}</div></div>`;
      if (b.type === "longtext") return `<div class="block"><div class="lbl">${escape(b.label)}</div><p class="long">${escape(b.value || "—")}</p></div>`;
      return "";
    }).join("\n");
    const css = `
      @page { size: A4; margin: 22mm 20mm; }
      html, body { font-family: 'Hanken Grotesk', system-ui, sans-serif; color: #1a2236; background: #faf7f1; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
      body { padding: 48px 56px; margin: 0; }
      .head { display: flex; justify-content: space-between; align-items: flex-end; border-bottom: 2px solid #1f3864; padding-bottom: 18px; margin-bottom: 28px; }
      .brand { font-family: 'Cormorant Garamond', 'Playfair Display', Georgia, serif; font-size: 22px; font-weight: 600; letter-spacing: .01em; color: #1f3864; }
      .brand .accent { color: #b8902f; font-style: italic; }
      .meta { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: #8a93a7; text-align: right; }
      h1 { font-family: 'Cormorant Garamond', 'Playfair Display', Georgia, serif; font-size: 32px; font-weight: 600; margin: 0 0 6px; color: #1a2236; letter-spacing: -.005em; }
      .lede { font-size: 13px; color: #5b6479; margin: 0 0 32px; max-width: 520px; }
      h2 { font-family: 'Cormorant Garamond', 'Playfair Display', Georgia, serif; font-size: 18px; font-weight: 600; color: #1f3864; margin: 26px 0 10px; padding-bottom: 6px; border-bottom: 1px solid #e5dccb; }
      .row { display: grid; grid-template-columns: 180px 1fr; gap: 14px; padding: 7px 0; border-bottom: 1px dashed #e8e1d2; }
      .row:last-child { border-bottom: 0; }
      .lbl { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: #8a93a7; padding-top: 2px; }
      .val { font-size: 13px; color: #1a2236; }
      .block { margin: 10px 0 4px; }
      .block .lbl { margin-bottom: 6px; }
      .long { font-size: 12.5px; line-height: 1.55; color: #2b3247; margin: 0; white-space: pre-wrap; }
      .foot { margin-top: 40px; padding-top: 16px; border-top: 1px solid #e5dccb; display: flex; justify-content: space-between; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: #8a93a7; }
      .stamp { display: inline-block; padding: 4px 9px; border: 1px dashed #b8902f; border-radius: 99px; color: #8a6a1c; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; }
    `;
    const today = new Date().toLocaleDateString(FR ? "fr-FR" : "en-GB", { day: "2-digit", month: "long", year: "numeric" });
    win.document.write(`<!doctype html><html lang="${lang}"><head><meta charset="utf-8"><title>${escape(title)}</title><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Playfair+Display:wght@600&family=Hanken+Grotesk:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet"><style>${css}</style></head><body>
      <div class="head">
        <div class="brand">European Mesopotamia <span class="accent">Alliance</span></div>
        <div class="meta">${escape(today)}<br>${FR ? "Document" : "Document"} · EMA</div>
      </div>
      <span class="stamp">${FR ? "Brouillon — à transmettre" : "Draft — to be submitted"}</span>
      <h1 style="margin-top:14px">${escape(title)}</h1>
      <p class="lede">${FR ? "Récapitulatif du dossier ci-dessous. Vous pouvez l'enregistrer en PDF depuis la boîte de dialogue d'impression (destination : « Enregistrer au format PDF »)." : "Summary below. You can save as PDF from the print dialog (destination: \"Save as PDF\")."}</p>
      ${blockHtml}
      <div class="foot"><span>European Mesopotamia Alliance</span><span>${escape(TO_EMAIL)}</span></div>
      <script>window.onload = function(){ setTimeout(function(){ window.print(); }, 350); };<\/script>
    </body></html>`);
    win.document.close();
  }
  function escape(s) { return String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c])); }

  // ---------- shared UI primitives ----------
  function FormField({ label, required, full, error, hint, children }) {
    return (
      <label style={{ display: "flex", flexDirection: "column", gap: 7, gridColumn: full ? "1/-1" : "auto" }}>
        <span style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8 }}>
          <span style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: error ? "#c0392b" : "var(--slate-400)" }}>
            {label}{required && <span style={{ color: "var(--gold-500)", marginLeft: 4 }}>*</span>}
          </span>
          {hint && <span style={{ fontSize: 11, color: "var(--slate-400)" }}>{hint}</span>}
        </span>
        {children}
        {error && <span style={{ fontSize: 11.5, color: "#c0392b" }}>{error}</span>}
      </label>
    );
  }

  const inputStyle = {
    padding: "13px 14px",
    border: "1px solid var(--hairline)",
    borderRadius: 6,
    background: "var(--surface)",
    fontSize: 14.5,
    fontFamily: "var(--sans)",
    color: "var(--ink)",
    outline: "none",
    transition: "border-color .15s, box-shadow .15s",
  };
  const inputErr = { borderColor: "#c0392b", boxShadow: "0 0 0 3px rgba(192,57,43,.08)" };

  function TextInput({ value, onChange, type = "text", placeholder, error, autoComplete }) {
    return <input type={type} value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} autoComplete={autoComplete}
      onFocus={(e) => { e.target.style.borderColor = "var(--gold-500)"; e.target.style.boxShadow = "0 0 0 3px rgba(184,144,47,.12)"; }}
      onBlur={(e) => { e.target.style.borderColor = error ? "#c0392b" : "var(--hairline)"; e.target.style.boxShadow = error ? "0 0 0 3px rgba(192,57,43,.08)" : "none"; }}
      style={{ ...inputStyle, ...(error ? inputErr : {}) }} />;
  }

  function TextArea({ value, onChange, rows = 5, placeholder, error }) {
    return <textarea value={value} onChange={(e) => onChange(e.target.value)} rows={rows} placeholder={placeholder}
      onFocus={(e) => { e.target.style.borderColor = "var(--gold-500)"; e.target.style.boxShadow = "0 0 0 3px rgba(184,144,47,.12)"; }}
      onBlur={(e) => { e.target.style.borderColor = error ? "#c0392b" : "var(--hairline)"; e.target.style.boxShadow = error ? "0 0 0 3px rgba(192,57,43,.08)" : "none"; }}
      style={{ ...inputStyle, resize: "vertical", lineHeight: 1.5, ...(error ? inputErr : {}) }} />;
  }

  function Select({ value, onChange, options, error }) {
    return <select value={value} onChange={(e) => onChange(e.target.value)}
      style={{ ...inputStyle, appearance: "none", backgroundImage: "linear-gradient(45deg, transparent 50%, var(--slate-400) 50%),linear-gradient(135deg, var(--slate-400) 50%, transparent 50%)", backgroundPosition: "calc(100% - 18px) center, calc(100% - 13px) center", backgroundSize: "5px 5px, 5px 5px", backgroundRepeat: "no-repeat", paddingRight: 36, ...(error ? inputErr : {}) }}>
      {options.map((o) => <option key={o.value || o} value={o.value || o}>{o.label || o}</option>)}
    </select>;
  }

  // ---------- CONTACT FORM ----------
  window.ContactForm = function ContactForm({ C, lang }) {
    const FR = lang === "fr";
    const T = useMemo(() => FR ? {
      eyebrow: "Formulaire", title: "Écrivez-nous",
      details: "Coordonnées", office: "Bureau de l'Alliance", hours: "Heures d'ouverture",
      hoursVal: "Lundi – Vendredi · 9h – 18h (Paris)", address: "Adresse", compliance: "Conformité",
      complianceVal: "KYC à l'entrée · ISO 37001 en cours · Sapin II / AFA",
      name: "Nom complet", org: "Organisation", email: "E-mail", phone: "Téléphone",
      topic: "Sujet", message: "Votre message", placeholder: "Décrivez en quelques lignes votre projet, vos questions, et le délai souhaité.",
      gdpr: "J'accepte que mes données soient traitées pour répondre à ma demande (RGPD).",
      send: "Envoyer le message", sending: "Envoi…",
      successTitle: "Message envoyé",
      successBody: "Une confirmation vient d'être envoyée à votre adresse. Notre équipe revient vers vous sous 48 heures ouvrées.",
      errorTitle: "Échec de l'envoi",
      errorRetry: "Réessayez dans un instant, ou écrivez directement à",
      required: "Champ requis", invalidEmail: "E-mail invalide",
      reasons: ["Adhésion", "Partenariat", "Mission / événement", "Presse", "Autre"],
      subjectPrefix: "Contact EMA",
    } : {
      eyebrow: "Form", title: "Send us a message",
      details: "Contact details", office: "Alliance office", hours: "Office hours",
      hoursVal: "Monday – Friday · 9am – 6pm (Paris)", address: "Address", compliance: "Compliance",
      complianceVal: "KYC on entry · ISO 37001 in progress · Sapin II / AFA",
      name: "Full name", org: "Organization", email: "Email", phone: "Phone",
      topic: "Topic", message: "Your message", placeholder: "Describe your project, questions and timeline in a few lines.",
      gdpr: "I agree that my data will be processed to handle my request (GDPR).",
      send: "Send the message", sending: "Sending…",
      successTitle: "Message sent",
      successBody: "A confirmation has just been sent to your address. Our team will get back to you within 2 business days.",
      errorTitle: "Could not send",
      errorRetry: "Please try again in a moment, or write directly to",
      required: "Required", invalidEmail: "Invalid email",
      reasons: ["Membership", "Partnership", "Mission / event", "Press", "Other"],
      subjectPrefix: "EMA Contact",
    }, [FR]);

    const [f, setF] = useState({ name: "", org: "", email: "", phone: "", topic: T.reasons[0], message: "" });
    const set = (k) => (v) => setF((p) => ({ ...p, [k]: v }));
    const [errs, setErrs] = useState({});
    const [status, setStatus] = useState("idle"); // idle | sending | sent | error
    const [errMsg, setErrMsg] = useState("");
    const [gdpr, setGdpr] = useState(false);

    function validate() {
      const e = {};
      if (!f.name.trim()) e.name = T.required;
      if (!f.email.trim()) e.email = T.required;
      else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(f.email)) e.email = T.invalidEmail;
      if (!f.message.trim()) e.message = T.required;
      if (!gdpr) e.gdpr = T.required;
      setErrs(e);
      return Object.keys(e).length === 0;
    }

    async function submit(e) {
      e.preventDefault();
      if (!validate()) return;
      const subject = T.subjectPrefix + " · " + f.topic + " — " + f.name;
      const fields = {
        name: f.name, org: f.org, email: f.email, phone: f.phone,
        topic: f.topic, message: f.message,
      };

      setStatus("sending");
      const res = await sendMail({
        kind: "contact", lang, fields,
        sender: { name: f.name, email: f.email },
      });
      if (res.ok) {
        setStatus("sent");
      } else {
        // API unreachable / failed → graceful fallback to mailto
        const body = [
          FR ? "Bonjour," : "Hello,",
          "",
          "— " + T.name + ": " + f.name,
          "— " + T.org + ": " + (f.org || "—"),
          "— " + T.email + ": " + f.email,
          "— " + T.phone + ": " + (f.phone || "—"),
          "— " + T.topic + ": " + f.topic,
          "",
          f.message,
          "",
          FR ? "Cordialement," : "Best regards,",
          f.name,
        ].join("\n");
        setStatus("error"); setErrMsg(res.error);
        // Optional: offer mailto fallback by setting the href after a delay
        window._emaFallbackMailto = buildMailto({ to: TO_EMAIL, subject, body });
      }
    }

    return (
      <section className="section" style={{ background: "var(--bg)" }}>
        <div className="wrap ema-2col" style={{ display: "grid", gridTemplateColumns: "minmax(0,.85fr) minmax(0,1.15fr)", gap: "clamp(32px,5vw,72px)" }}>
          <div data-reveal>
            <div className="eyebrow" style={{ marginBottom: 14 }}>{T.details}</div>
            <h3 className="display" style={{ fontSize: 32, margin: "0 0 24px" }}>{T.office}</h3>
            <div style={{ display: "flex", flexDirection: "column", gap: 18, fontSize: 16 }}>
              <ContactLine icon="pin" t={T.address} d={C.footer.address} />
              <ContactLine icon="mail" t="E-mail" d={C.footer.email} href={"mailto:" + C.footer.email} />
              <ContactLine icon="lock" t={T.compliance} d={T.complianceVal} />
            </div>
            <div style={{ marginTop: 30, padding: "22px 24px", background: "var(--bg-alt)", borderRadius: 8, border: "1px solid var(--hairline)" }}>
              <div className="eyebrow" style={{ color: "var(--accent-ink)", marginBottom: 8 }}>{T.hours}</div>
              <p style={{ margin: 0, color: "var(--ink-soft)", fontSize: 15 }}>{T.hoursVal}</p>
            </div>
          </div>

          <form data-reveal onSubmit={submit} noValidate style={{ "--rd": "120ms", background: "var(--surface)", border: "1px solid var(--hairline)", borderRadius: 10, padding: "clamp(28px,3.5vw,42px)", position: "relative" }}>
            <div className="eyebrow" style={{ marginBottom: 16 }}>{T.eyebrow}</div>
            <h3 className="display" style={{ fontSize: 28, margin: "0 0 26px" }}>{T.title}</h3>

            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18 }} className="ema-2col">
              <FormField label={T.name} required error={errs.name}>
                <TextInput value={f.name} onChange={set("name")} error={errs.name} autoComplete="name" />
              </FormField>
              <FormField label={T.org} error={errs.org}>
                <TextInput value={f.org} onChange={set("org")} autoComplete="organization" />
              </FormField>
              <FormField label={T.email} required error={errs.email}>
                <TextInput type="email" value={f.email} onChange={set("email")} error={errs.email} autoComplete="email" />
              </FormField>
              <FormField label={T.phone}>
                <TextInput type="tel" value={f.phone} onChange={set("phone")} autoComplete="tel" />
              </FormField>
              <FormField label={T.topic} full>
                <Select value={f.topic} onChange={set("topic")} options={T.reasons} />
              </FormField>
              <FormField label={T.message} required full error={errs.message}>
                <TextArea value={f.message} onChange={set("message")} rows={5} placeholder={T.placeholder} error={errs.message} />
              </FormField>
            </div>

            <label style={{ display: "flex", gap: 10, alignItems: "flex-start", marginTop: 22, fontSize: 13, color: errs.gdpr ? "#c0392b" : "var(--ink-soft)", cursor: "pointer" }}>
              <input type="checkbox" checked={gdpr} onChange={(e) => setGdpr(e.target.checked)} style={{ marginTop: 3, accentColor: "var(--gold-500)" }} />
              <span>{T.gdpr}</span>
            </label>

            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 26, flexWrap: "wrap", gap: 14 }}>
              <span style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: ".08em", color: "var(--slate-400)" }}>{FR ? "Réponse sous 48h ouvrées" : "Reply within 2 business days"}</span>
              <button type="submit" className="btn btn-gold" disabled={status === "sending"} style={{ opacity: status === "sending" ? .6 : 1, cursor: status === "sending" ? "wait" : "pointer" }}>
                {status === "sending" ? T.sending : T.send} {status !== "sending" && <Icon name="arrow" size={16} />}
              </button>
            </div>

            {status === "sent" && (
              <div role="status" style={{ marginTop: 22, padding: "14px 18px", background: "rgba(31,138,91,.08)", border: "1px solid rgba(31,138,91,.25)", borderRadius: 8, fontSize: 13.5, color: "var(--ink)", display: "flex", gap: 10, alignItems: "flex-start" }}>
                <span style={{ color: "#1f8a5b", flex: "none", marginTop: 1 }}><Icon name="check" size={18} /></span>
                <div>
                  <div style={{ fontWeight: 600, marginBottom: 3 }}>{T.successTitle}</div>
                  <div>{T.successBody}</div>
                </div>
              </div>
            )}
            {status === "error" && (
              <div role="alert" style={{ marginTop: 22, padding: "14px 18px", background: "rgba(192,57,43,.06)", border: "1px solid rgba(192,57,43,.28)", borderRadius: 8, fontSize: 13.5, color: "var(--ink)", display: "flex", gap: 10, alignItems: "flex-start" }}>
                <span style={{ color: "#c0392b", flex: "none", marginTop: 1, fontFamily: "var(--mono)", fontWeight: 700 }}>!</span>
                <div>
                  <div style={{ fontWeight: 600, marginBottom: 3 }}>{T.errorTitle}</div>
                  <div>{T.errorRetry} <a href={"mailto:" + TO_EMAIL} style={{ color: "var(--accent-ink)", fontWeight: 600 }}>{TO_EMAIL}</a>.{errMsg && <span style={{ color: "var(--slate-400)", marginLeft: 6, fontSize: 12 }}>({errMsg})</span>}</div>
                </div>
              </div>
            )}
          </form>
        </div>
      </section>
    );
  };

  function ContactLine({ icon, t, d, href }) {
    return (
      <div style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: 14, alignItems: "flex-start" }}>
        <span style={{ width: 36, height: 36, borderRadius: 99, background: "var(--bg-alt)", color: "var(--accent-ink)", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={icon} size={17} /></span>
        <div>
          <div style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--slate-400)" }}>{t}</div>
          {href ? <a href={href} style={{ color: "var(--accent-ink)", fontSize: 16 }}>{d}</a> : <div style={{ color: "var(--ink)", fontSize: 16 }}>{d}</div>}
        </div>
      </div>
    );
  }

  // ---------- ADHESION FORM ----------
  window.AdhesionForm = function AdhesionForm({ C, lang }) {
    const FR = lang === "fr";
    const T = useMemo(() => FR ? {
      eyebrow: "Adhésion", title: "Dossier d'adhésion",
      lede: "Composez votre dossier en quelques minutes : présentation, contacts, palier souhaité, vérification d'intégrité.",
      stepLabel: "Étape", of: "sur",
      steps: ["Organisation", "Contact référent", "Palier & projet", "Conformité & envoi"],
      // Step 1
      legalName: "Raison sociale", legalNamePh: "Société, association, institution",
      siret: "SIRET / Identifiant fiscal", country: "Pays",
      sector: "Secteur principal",
      sectors: ["Énergie", "Infrastructures", "Technologies", "Agriculture", "Santé", "Sécurité & défense", "Services financiers", "Autre"],
      headcount: "Effectif",
      heads: ["1–9 (TPE)", "10–49 (PME)", "50–249 (ETI)", "250–4 999 (Grand groupe)", "5 000+"],
      website: "Site web",
      // Step 2
      contactName: "Nom du référent", contactRole: "Fonction",
      contactEmail: "E-mail professionnel", contactPhone: "Téléphone",
      // Step 3
      tier: "Palier souhaité",
      tiers: [
        { id: "emergent", name: "Émergent", who: "Start-up / TPE" },
        { id: "business", name: "Business", who: "PME" },
        { id: "premium", name: "Premium", who: "ETI", featured: true },
        { id: "corporate", name: "Corporate", who: "Grand groupe" },
        { id: "partner", name: "Partenaire", who: "Stratégique / Sponsor" },
      ],
      motivation: "Présentation & motivations",
      motivationPh: "Votre activité, vos zones d'intervention en Europe / Irak / Moyen-Orient, et ce que vous attendez de l'Alliance.",
      interests: "Centres d'intérêt",
      interestList: ["Énergie", "Infrastructures", "Technologies", "Agriculture", "Diplomatie économique", "Forums & délégations"],
      // Step 4
      kyc: "J'accepte la procédure de vérification d'intégrité (KYC) à l'entrée.",
      ethics: "J'adhère à la charte éthique et de conformité (anti-corruption, Sapin II / AFA).",
      gdpr: "J'accepte le traitement RGPD de mes données pour le suivi de mon dossier.",
      back: "Précédent", next: "Suivant",
      send: "Envoyer le dossier", sending: "Envoi en cours…", pdf: "Télécharger en PDF",
      sentTitle: "Dossier transmis",
      sentBody: "Une confirmation vient d'être envoyée à votre adresse. Notre équipe étudie votre candidature et reviendra vers vous sous 5 jours ouvrés.",
      errorTitle: "Échec de l'envoi",
      errorRetry: "Réessayez dans un instant ou écrivez directement à",
      required: "Champ requis", invalidEmail: "E-mail invalide",
      subjectPrefix: "Dossier d'adhésion EMA",
      summary: "Récapitulatif",
      summaryNote: "Vérifiez votre dossier avant envoi. Vous pouvez revenir en arrière pour modifier.",
    } : {
      eyebrow: "Membership", title: "Membership application",
      lede: "Put your application together in minutes: profile, contacts, preferred tier, integrity checks.",
      stepLabel: "Step", of: "of",
      steps: ["Organization", "Primary contact", "Tier & project", "Compliance & send"],
      legalName: "Legal name", legalNamePh: "Company, association, institution",
      siret: "Tax ID / Registration", country: "Country",
      sector: "Primary sector",
      sectors: ["Energy", "Infrastructure", "Technology", "Agriculture", "Health", "Security & defense", "Financial services", "Other"],
      headcount: "Headcount",
      heads: ["1–9 (Micro)", "10–49 (SME)", "50–249 (Mid-cap)", "250–4,999 (Large)", "5,000+"],
      website: "Website",
      contactName: "Contact name", contactRole: "Role",
      contactEmail: "Work email", contactPhone: "Phone",
      tier: "Preferred tier",
      tiers: [
        { id: "emergent", name: "Emerging", who: "Start-up / Micro" },
        { id: "business", name: "Business", who: "SME" },
        { id: "premium", name: "Premium", who: "Mid-cap", featured: true },
        { id: "corporate", name: "Corporate", who: "Large group" },
        { id: "partner", name: "Partner", who: "Strategic / Sponsor" },
      ],
      motivation: "Profile & motivations",
      motivationPh: "Your activity, your areas of operation in Europe / Iraq / the Middle East, and what you expect from the Alliance.",
      interests: "Areas of interest",
      interestList: ["Energy", "Infrastructure", "Technology", "Agriculture", "Economic diplomacy", "Forums & delegations"],
      kyc: "I agree to the integrity check (KYC) on entry.",
      ethics: "I accept the ethics and compliance charter (anti-corruption, Sapin II / AFA).",
      gdpr: "I accept GDPR processing of my data to follow up on my application.",
      back: "Back", next: "Next",
      send: "Send my application", sending: "Sending…", pdf: "Download as PDF",
      sentTitle: "Application submitted",
      sentBody: "A confirmation has just been sent to your address. Our team is reviewing your application and will get back to you within 5 business days.",
      errorTitle: "Could not send",
      errorRetry: "Please try again in a moment, or write directly to",
      required: "Required", invalidEmail: "Invalid email",
      subjectPrefix: "EMA Membership application",
      summary: "Summary",
      summaryNote: "Review your application before submitting. You can step back to edit any section.",
    }, [FR]);

    const [step, setStep] = useState(0);
    const [f, setF] = useState({
      legalName: "", siret: "", country: FR ? "France" : "France",
      sector: T.sectors[0], headcount: T.heads[1], website: "",
      contactName: "", contactRole: "", contactEmail: "", contactPhone: "",
      tier: "premium", motivation: "", interests: [],
      kyc: false, ethics: false, gdpr: false,
    });
    const set = (k) => (v) => setF((p) => ({ ...p, [k]: v }));
    const toggleInterest = (it) => setF((p) => ({ ...p, interests: p.interests.includes(it) ? p.interests.filter((x) => x !== it) : [...p.interests, it] }));
    const [errs, setErrs] = useState({});
    const [status, setStatus] = useState("idle"); // idle | sending | sent | error
    const [errMsg, setErrMsg] = useState("");

    function validateStep(i) {
      const e = {};
      if (i === 0) {
        if (!f.legalName.trim()) e.legalName = T.required;
        if (!f.country.trim()) e.country = T.required;
      }
      if (i === 1) {
        if (!f.contactName.trim()) e.contactName = T.required;
        if (!f.contactEmail.trim()) e.contactEmail = T.required;
        else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(f.contactEmail)) e.contactEmail = T.invalidEmail;
      }
      if (i === 2) {
        if (!f.motivation.trim()) e.motivation = T.required;
      }
      if (i === 3) {
        if (!f.kyc) e.kyc = T.required;
        if (!f.ethics) e.ethics = T.required;
        if (!f.gdpr) e.gdpr = T.required;
      }
      setErrs(e);
      return Object.keys(e).length === 0;
    }

    function goNext() {
      if (validateStep(step)) {
        setStep((s) => Math.min(s + 1, T.steps.length - 1));
        window.scrollTo({ top: document.getElementById("application").offsetTop - 90, behavior: "smooth" });
      }
    }
    function goBack() {
      setStep((s) => Math.max(s - 1, 0));
      window.scrollTo({ top: document.getElementById("application").offsetTop - 90, behavior: "smooth" });
    }

    function buildBody() {
      const tier = T.tiers.find((x) => x.id === f.tier);
      const lines = [
        FR ? "Madame, Monsieur," : "Dear EMA team,",
        "",
        FR ? "Veuillez trouver ci-dessous mon dossier d'adhésion à European Mesopotamia Alliance." : "Please find below my membership application to European Mesopotamia Alliance.",
        "",
        "═══ " + T.steps[0] + " ═══",
        "— " + T.legalName + ": " + f.legalName,
        "— " + T.siret + ": " + (f.siret || "—"),
        "— " + T.country + ": " + f.country,
        "— " + T.sector + ": " + f.sector,
        "— " + T.headcount + ": " + f.headcount,
        "— " + T.website + ": " + (f.website || "—"),
        "",
        "═══ " + T.steps[1] + " ═══",
        "— " + T.contactName + ": " + f.contactName,
        "— " + T.contactRole + ": " + (f.contactRole || "—"),
        "— " + T.contactEmail + ": " + f.contactEmail,
        "— " + T.contactPhone + ": " + (f.contactPhone || "—"),
        "",
        "═══ " + T.steps[2] + " ═══",
        "— " + T.tier + ": " + tier.name + " (" + tier.who + ")",
        "— " + T.interests + ": " + (f.interests.join(", ") || "—"),
        "",
        T.motivation + ":",
        f.motivation,
        "",
        "═══ " + T.steps[3] + " ═══",
        "— KYC: " + (f.kyc ? "✓" : "✗"),
        "— " + (FR ? "Charte éthique" : "Ethics charter") + ": " + (f.ethics ? "✓" : "✗"),
        "— RGPD: " + (f.gdpr ? "✓" : "✗"),
        "",
        FR ? "Cordialement," : "Best regards,",
        f.contactName + (f.contactRole ? " — " + f.contactRole : ""),
        f.legalName,
      ];
      return lines.join("\n");
    }

    async function submit() {
      if (!validateStep(3)) return;
      const tier = T.tiers.find((x) => x.id === f.tier);
      const fields = {
        legal_name: f.legalName, tax_id: f.siret, country: f.country,
        sector: f.sector, headcount: f.headcount, website: f.website,
        contact_name: f.contactName, contact_role: f.contactRole,
        contact_email: f.contactEmail, contact_phone: f.contactPhone,
        tier: tier.name, tier_who: tier.who,
        interests: f.interests.join(", "),
        motivation: f.motivation,
        kyc: !!f.kyc, ethics: !!f.ethics, gdpr: !!f.gdpr,
      };

      setStatus("sending");
      const res = await sendMail({
        kind: "adhesion", lang, fields,
        sender: { name: f.contactName, email: f.contactEmail },
      });
      if (res.ok) {
        setStatus("sent");
      } else {
        setStatus("error"); setErrMsg(res.error);
        window._emaFallbackMailto = buildMailto({
          to: TO_EMAIL,
          subject: T.subjectPrefix + " · " + tier.name + " — " + f.legalName,
          body: buildBody(),
        });
      }
    }

    function downloadPdf() {
      const tier = T.tiers.find((x) => x.id === f.tier);
      openPdfWindow({
        lang, title: T.title,
        blocks: [
          { type: "section", title: T.steps[0] },
          { type: "row", label: T.legalName, value: f.legalName },
          { type: "row", label: T.siret, value: f.siret },
          { type: "row", label: T.country, value: f.country },
          { type: "row", label: T.sector, value: f.sector },
          { type: "row", label: T.headcount, value: f.headcount },
          { type: "row", label: T.website, value: f.website },
          { type: "section", title: T.steps[1] },
          { type: "row", label: T.contactName, value: f.contactName },
          { type: "row", label: T.contactRole, value: f.contactRole },
          { type: "row", label: T.contactEmail, value: f.contactEmail },
          { type: "row", label: T.contactPhone, value: f.contactPhone },
          { type: "section", title: T.steps[2] },
          { type: "row", label: T.tier, value: tier.name + " (" + tier.who + ")" },
          { type: "row", label: T.interests, value: f.interests.join(", ") },
          { type: "longtext", label: T.motivation, value: f.motivation },
          { type: "section", title: T.steps[3] },
          { type: "row", label: "KYC", value: f.kyc ? (FR ? "Accepté" : "Accepted") : (FR ? "Non" : "No") },
          { type: "row", label: FR ? "Éthique" : "Ethics", value: f.ethics ? (FR ? "Accepté" : "Accepted") : (FR ? "Non" : "No") },
          { type: "row", label: "RGPD", value: f.gdpr ? (FR ? "Accepté" : "Accepted") : (FR ? "Non" : "No") },
        ],
      });
    }

    return (
      <section id="application" className="section" style={{ background: "var(--bg)", scrollMarginTop: 80 }}>
        <div className="wrap">
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24, flexWrap: "wrap", marginBottom: 36 }}>
            <div data-reveal style={{ maxWidth: 640 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
                <span className="kicker-rule"></span>
                <span className="eyebrow">{T.eyebrow}</span>
              </div>
              <h2 className="display" style={{ fontSize: "clamp(30px,3.6vw,46px)", margin: 0 }}>{T.title}</h2>
              <p className="lede" style={{ marginTop: 14, fontSize: 18 }}>{T.lede}</p>
            </div>
            <div data-reveal style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--slate-400)" }}>
              {T.stepLabel} <span style={{ color: "var(--gold-600)", fontWeight: 600 }}>{String(step + 1).padStart(2, "0")}</span> {T.of} {String(T.steps.length).padStart(2, "0")}
            </div>
          </div>

          {/* Stepper */}
          <div data-reveal style={{ display: "grid", gridTemplateColumns: `repeat(${T.steps.length}, 1fr)`, gap: 0, marginBottom: 36, background: "var(--surface)", border: "1px solid var(--hairline)", borderRadius: 10, overflow: "hidden" }} className="ema-stepper">
            {T.steps.map((s, i) => {
              const done = i < step, active = i === step;
              return (
                <button key={i} type="button" onClick={() => i < step && setStep(i)} disabled={i > step}
                  style={{ display: "flex", alignItems: "center", gap: 12, padding: "18px 20px", background: active ? "var(--navy-900)" : "transparent", color: active ? "#fff" : (done ? "var(--ink)" : "var(--slate-400)"), borderRight: i < T.steps.length - 1 ? "1px solid var(--hairline)" : "none", textAlign: "left", cursor: i < step ? "pointer" : "default", border: "none", fontFamily: "var(--sans)" }}>
                  <span style={{ width: 28, height: 28, borderRadius: 99, flex: "none", display: "flex", alignItems: "center", justifyContent: "center", background: active ? "var(--gold-500)" : (done ? "var(--gold-500)" : "var(--bg-alt)"), color: active || done ? "#fff" : "var(--slate-400)", fontFamily: "var(--mono)", fontSize: 12, fontWeight: 600 }}>
                    {done ? <Icon name="check" size={14} /> : String(i + 1).padStart(2, "0")}
                  </span>
                  <span style={{ fontSize: 13.5, fontWeight: active ? 600 : 500, letterSpacing: ".005em" }}>{s}</span>
                </button>
              );
            })}
          </div>

          <div data-reveal style={{ background: "var(--surface)", border: "1px solid var(--hairline)", borderRadius: 10, padding: "clamp(28px,3.5vw,44px)" }}>
            {/* STEP 0 — Organization */}
            {step === 0 && (
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="ema-2col">
                <FormField label={T.legalName} required full error={errs.legalName}>
                  <TextInput value={f.legalName} onChange={set("legalName")} placeholder={T.legalNamePh} error={errs.legalName} />
                </FormField>
                <FormField label={T.siret}>
                  <TextInput value={f.siret} onChange={set("siret")} />
                </FormField>
                <FormField label={T.country} required error={errs.country}>
                  <TextInput value={f.country} onChange={set("country")} error={errs.country} />
                </FormField>
                <FormField label={T.sector}>
                  <Select value={f.sector} onChange={set("sector")} options={T.sectors} />
                </FormField>
                <FormField label={T.headcount}>
                  <Select value={f.headcount} onChange={set("headcount")} options={T.heads} />
                </FormField>
                <FormField label={T.website} full>
                  <TextInput type="url" value={f.website} onChange={set("website")} placeholder="https://" />
                </FormField>
              </div>
            )}

            {/* STEP 1 — Primary contact */}
            {step === 1 && (
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="ema-2col">
                <FormField label={T.contactName} required error={errs.contactName}>
                  <TextInput value={f.contactName} onChange={set("contactName")} error={errs.contactName} autoComplete="name" />
                </FormField>
                <FormField label={T.contactRole}>
                  <TextInput value={f.contactRole} onChange={set("contactRole")} />
                </FormField>
                <FormField label={T.contactEmail} required error={errs.contactEmail}>
                  <TextInput type="email" value={f.contactEmail} onChange={set("contactEmail")} error={errs.contactEmail} autoComplete="email" />
                </FormField>
                <FormField label={T.contactPhone}>
                  <TextInput type="tel" value={f.contactPhone} onChange={set("contactPhone")} autoComplete="tel" />
                </FormField>
              </div>
            )}

            {/* STEP 2 — Tier & project */}
            {step === 2 && (
              <div style={{ display: "flex", flexDirection: "column", gap: 26 }}>
                <div>
                  <div style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--slate-400)", marginBottom: 12 }}>{T.tier}</div>
                  <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 10 }} className="ema-tier-cards">
                    {T.tiers.map((tt, i) => {
                      const active = f.tier === tt.id;
                      return (
                        <button key={tt.id} type="button" onClick={() => set("tier")(tt.id)}
                          style={{ textAlign: "left", padding: "18px 16px 16px", borderRadius: 8, border: active ? "1px solid var(--navy-900)" : "1px solid var(--hairline)", background: active ? "var(--navy-900)" : "var(--bg)", color: active ? "#fff" : "var(--ink)", cursor: "pointer", position: "relative", transition: "border-color .15s, transform .15s", fontFamily: "var(--sans)" }}>
                          <div style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", color: active ? "var(--gold-300)" : "var(--slate-400)" }}>{String(i + 1).padStart(2, "0")}</div>
                          <div className="display" style={{ fontSize: 20, marginTop: 4 }}>{tt.name}</div>
                          <div style={{ fontSize: 12, color: active ? "rgba(255,255,255,.7)" : "var(--ink-soft)", marginTop: 2 }}>{tt.who}</div>
                          {active && <span style={{ position: "absolute", top: 12, right: 12, color: "var(--gold-500)", display: "flex" }}><Icon name="check" size={16} /></span>}
                        </button>
                      );
                    })}
                  </div>
                </div>

                <FormField label={T.motivation} required error={errs.motivation} full>
                  <TextArea value={f.motivation} onChange={set("motivation")} rows={7} placeholder={T.motivationPh} error={errs.motivation} />
                </FormField>

                <div>
                  <div style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--slate-400)", marginBottom: 12 }}>{T.interests}</div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                    {T.interestList.map((it) => {
                      const on = f.interests.includes(it);
                      return (
                        <button key={it} type="button" onClick={() => toggleInterest(it)}
                          style={{ padding: "8px 14px", borderRadius: 99, border: on ? "1px solid var(--gold-500)" : "1px solid var(--hairline)", background: on ? "rgba(184,144,47,.1)" : "var(--bg)", color: on ? "var(--accent-ink)" : "var(--ink-soft)", fontSize: 13.5, fontFamily: "var(--sans)", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 6 }}>
                          {on && <Icon name="check" size={13} />} {it}
                        </button>
                      );
                    })}
                  </div>
                </div>
              </div>
            )}

            {/* STEP 3 — Compliance & send */}
            {step === 3 && (
              <div style={{ display: "flex", flexDirection: "column", gap: 26 }}>
                {/* Summary card */}
                <div style={{ background: "var(--bg-alt)", border: "1px solid var(--hairline)", borderRadius: 8, padding: "22px 24px" }}>
                  <div className="eyebrow" style={{ marginBottom: 10 }}>{T.summary}</div>
                  <p style={{ margin: "0 0 18px", fontSize: 14, color: "var(--ink-soft)" }}>{T.summaryNote}</p>
                  <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "10px 24px", fontSize: 14 }} className="ema-2col">
                    <Summary k={T.legalName} v={f.legalName} />
                    <Summary k={T.country} v={f.country} />
                    <Summary k={T.sector} v={f.sector} />
                    <Summary k={T.headcount} v={f.headcount} />
                    <Summary k={T.contactName} v={f.contactName + (f.contactRole ? " — " + f.contactRole : "")} />
                    <Summary k={T.contactEmail} v={f.contactEmail} />
                    <Summary k={T.tier} v={T.tiers.find((x) => x.id === f.tier).name} />
                    <Summary k={T.interests} v={f.interests.join(", ") || "—"} />
                  </div>
                </div>

                <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                  <Check checked={f.kyc} onChange={set("kyc")} label={T.kyc} err={errs.kyc} />
                  <Check checked={f.ethics} onChange={set("ethics")} label={T.ethics} err={errs.ethics} />
                  <Check checked={f.gdpr} onChange={set("gdpr")} label={T.gdpr} err={errs.gdpr} />
                </div>

                {status === "sent" && (
                  <div role="status" style={{ padding: "16px 20px", background: "rgba(31,138,91,.08)", border: "1px solid rgba(31,138,91,.25)", borderRadius: 8, fontSize: 14, color: "var(--ink)", display: "flex", gap: 12, alignItems: "flex-start" }}>
                    <span style={{ color: "#1f8a5b", flex: "none", marginTop: 2 }}><Icon name="check" size={20} /></span>
                    <div>
                      <div style={{ fontWeight: 600, marginBottom: 4 }}>{T.sentTitle}</div>
                      <div>{T.sentBody}</div>
                    </div>
                  </div>
                )}
                {status === "error" && (
                  <div role="alert" style={{ padding: "16px 20px", background: "rgba(192,57,43,.06)", border: "1px solid rgba(192,57,43,.28)", borderRadius: 8, fontSize: 14, color: "var(--ink)", display: "flex", gap: 12, alignItems: "flex-start" }}>
                    <span style={{ color: "#c0392b", flex: "none", marginTop: 2, fontFamily: "var(--mono)", fontWeight: 700, fontSize: 18 }}>!</span>
                    <div>
                      <div style={{ fontWeight: 600, marginBottom: 4 }}>{T.errorTitle}</div>
                      <div>{T.errorRetry} <a href={"mailto:" + TO_EMAIL} style={{ color: "var(--accent-ink)", fontWeight: 600 }}>{TO_EMAIL}</a>.{errMsg && <span style={{ color: "var(--slate-400)", marginLeft: 6, fontSize: 12 }}>({errMsg})</span>}</div>
                    </div>
                  </div>
                )}
              </div>
            )}

            {/* Nav row */}
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 32, flexWrap: "wrap", gap: 14, paddingTop: 24, borderTop: "1px solid var(--hairline)" }}>
              <button type="button" onClick={goBack} disabled={step === 0}
                className="btn"
                style={{ opacity: step === 0 ? .35 : 1, cursor: step === 0 ? "not-allowed" : "pointer", border: "1px solid var(--hairline)", background: "transparent", color: "var(--ink)" }}>
                <span style={{ display: "inline-flex", transform: "scaleX(-1)" }}><Icon name="arrow" size={16} /></span> {T.back}
              </button>

              <div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
                {step === T.steps.length - 1 ? (
                  <React.Fragment>
                    <button type="button" onClick={downloadPdf} className="btn" style={{ border: "1px solid var(--navy-900)", color: "var(--navy-900)", background: "transparent" }}>
                      <Icon name="doc" size={16} /> {T.pdf}
                    </button>
                    <button type="button" onClick={submit} className="btn btn-gold" disabled={status === "sending"} style={{ opacity: status === "sending" ? .6 : 1, cursor: status === "sending" ? "wait" : "pointer" }}>
                      {status === "sending" ? T.sending : T.send} {status !== "sending" && <Icon name="arrow" size={16} />}
                    </button>
                  </React.Fragment>
                ) : (
                  <button type="button" onClick={goNext} className="btn btn-navy">
                    {T.next} <Icon name="arrow" size={16} />
                  </button>
                )}
              </div>
            </div>
          </div>
        </div>
      </section>
    );
  };

  function Summary({ k, v }) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 2, paddingBlock: 4 }}>
        <span style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--slate-400)" }}>{k}</span>
        <span style={{ color: "var(--ink)" }}>{v || "—"}</span>
      </div>
    );
  }

  function Check({ checked, onChange, label, err }) {
    return (
      <label style={{ display: "flex", gap: 12, alignItems: "flex-start", padding: "14px 16px", border: "1px solid " + (err ? "#c0392b" : (checked ? "var(--gold-500)" : "var(--hairline)")), borderRadius: 8, background: checked ? "rgba(184,144,47,.04)" : "var(--bg)", cursor: "pointer", transition: "all .15s" }}>
        <input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} style={{ marginTop: 3, accentColor: "var(--gold-500)", flex: "none" }} />
        <span style={{ fontSize: 14, color: err ? "#c0392b" : "var(--ink)", lineHeight: 1.4 }}>{label}</span>
      </label>
    );
  }
})();
