// WhatsApp-style support chatbot widget
function Chatbot() {
  const [open, setOpen] = React.useState(false);
  const [messages, setMessages] = React.useState([]);
  const [typing, setTyping] = React.useState(false);
  const [step, setStep] = React.useState("welcome");
  const [input, setInput] = React.useState("");
  const [showBadge, setShowBadge] = React.useState(true);
  const [onbData, setOnbData] = React.useState({});
  const [cameraOn, setCameraOn] = React.useState(false);
  const [geoLoading, setGeoLoading] = React.useState(false);
  const [pickedCoords, setPickedCoords] = React.useState(null);
  const [pickerZoom, setPickerZoom] = React.useState(1);
  const bodyRef = React.useRef(null);
  const fileRef = React.useRef(null);
  const videoRef = React.useRef(null);
  const streamRef = React.useRef(null);

  const time = () => {
    const d = new Date();
    return d.toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit" });
  };

  const pushBot = (text, opts = {}) => {
    return new Promise((resolve) => {
      setTyping(true);
      const delay = opts.delay ?? 700;
      setTimeout(() => {
        setTyping(false);
        setMessages((m) => [...m, { from: "in", text, time: time() }]);
        resolve();
      }, delay);
    });
  };

  const pushUser = (text, opts = {}) => {
    setMessages((m) => [...m, { from: "out", text, time: time(), image: opts.image, map: opts.map }]);
  };

  // Initial welcome flow
  React.useEffect(() => {
    if (open && messages.length === 0) {
      (async () => {
        await pushBot("👋 Bonjour ! Je suis Awa, votre conseillère MouNa.", { delay: 500 });
        await pushBot("Comment puis-je vous aider aujourd'hui ?", { delay: 800 });
        setStep("menu");
      })();
    }
  }, [open]);

  // Hide notification badge once opened
  React.useEffect(() => {
    if (open) setShowBadge(false);
  }, [open]);

  // Auto-scroll body
  React.useEffect(() => {
    if (bodyRef.current) {
      bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
    }
  }, [messages, typing]);

  // Camera + photo + geolocation helpers (for in-chat onboarding)
  const startCamera = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" } });
      streamRef.current = stream;
      setCameraOn(true);
      setTimeout(() => {
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
          videoRef.current.play();
        }
      }, 60);
    } catch (e) {
      await pushBot("Impossible d'accéder à la caméra. Essayez le téléversement de fichier.", { delay: 300 });
    }
  };
  const stopCamera = () => {
    streamRef.current?.getTracks().forEach((t) => t.stop());
    streamRef.current = null;
    setCameraOn(false);
  };
  const capturePhoto = async () => {
    if (!videoRef.current) return;
    const c = document.createElement("canvas");
    c.width = videoRef.current.videoWidth;
    c.height = videoRef.current.videoHeight;
    c.getContext("2d").drawImage(videoRef.current, 0, 0);
    const dataUrl = c.toDataURL("image/jpeg", 0.7);
    stopCamera();
    pushUser("📷 Selfie capturé", { image: dataUrl });
    setOnbData((d) => ({ ...d, photo: dataUrl }));
    setStep(null);
    await pushBot("✓ Parfait, photo enregistrée et chiffrée.", { delay: 700 });
    await pushBot("Quelle est votre *adresse email* ?", { delay: 800 });
    setStep("onb-email");
  };
  const onFileChange = (e) => {
    const file = e.target.files?.[0];
    e.target.value = ""; // reset so same file can be reselected
    if (!file) return;
    const reader = new FileReader();
    reader.onload = async () => {
      const dataUrl = reader.result;
      pushUser("📁 Photo téléversée", { image: dataUrl });
      setOnbData((d) => ({ ...d, photo: dataUrl }));
      setStep(null);
      await pushBot("✓ Photo enregistrée !", { delay: 700 });
      await pushBot("Quelle est votre *adresse email* ?", { delay: 800 });
      setStep("onb-email");
    };
    reader.readAsDataURL(file);
  };
  const handleGPSResult = async (coords) => {
    setOnbData((d) => ({ ...d, coords }));
    pushUser(`📍 ${coords.lat.toFixed(5)}, ${coords.lng.toFixed(5)} (±${coords.accuracy}m)`, { map: coords });
    setStep(null);
    await pushBot("✓ Position confirmée. Vous êtes dans notre zone de couverture fibre.", { delay: 900 });
    await pushBot(`📩 Code OTP envoyé à *${onbData.email}* et par SMS au *${onbData.phone}*.`, { delay: 1200 });
    await pushBot("Entrez le code à *6 chiffres* reçu.", { delay: 700 });
    setStep("onb-otp");
  };
  const requestGPS = () => {
    if (!navigator.geolocation) {
      handleGPSResult({ lat: 9.5092, lng: -13.7122, accuracy: 30 });
      return;
    }
    setGeoLoading(true);
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setGeoLoading(false);
        handleGPSResult({
          lat: pos.coords.latitude,
          lng: pos.coords.longitude,
          accuracy: Math.round(pos.coords.accuracy),
        });
      },
      () => {
        setGeoLoading(false);
        handleGPSResult({ lat: 9.5092, lng: -13.7122, accuracy: 30 });
      },
      { enableHighAccuracy: true, timeout: 8000 }
    );
  };
  React.useEffect(() => () => stopCamera(), []);

  // Finalize: simulate processing, create account ID + transaction ID, show success
  const finalizeOnboarding = async (timing) => {
    setStep(null);
    if (timing === "instant") {
      await pushBot("Vérification de la transaction…", { delay: 1400 });
    }
    const accountId = "MN-" + Math.floor(100000 + Math.random() * 899999);
    const txPrefix = timing === "instant" ? "TX-" : "INV-";
    const txId = txPrefix + Math.floor(100000 + Math.random() * 899999);
    setOnbData((d) => ({ ...d, accountId, txId }));
    const offerLine = onbData.offer ? `\nForfait : *${onbData.offer.name}* (${onbData.offer.price})` : "";
    const txLabel = timing === "instant" ? "Transaction" : "Facture";
    const statusLine = timing === "instant" ? "✓ Paiement confirmé · forfait activé" : "📅 Paiement différé · facture à régler sous 7 jours après installation";
    await pushBot(
      `🎉 *Compte créé !*\n\nIdentifiant : *${accountId}*${offerLine}\n${txLabel} : *${txId}*\n\n${statusLine}\n\nUn email vient de partir vers *${onbData.email}* avec un lien pour définir votre mot de passe.`,
      { delay: 1200 }
    );
    setStep("onb-success");
  };

  const choose = async (key) => {
    if (key === "offres") {
      pushUser("Voir les offres internet");
      setStep(null);
      await pushBot("Parfait ! Voici nos 3 forfaits fibre :", { delay: 600 });
      await pushBot("🟢 *Start* — 100 Mbps · 150.000 GNF/mois\n🟣 *Pro* — 500 Mbps · 350.000 GNF/mois\n⚡ *Ultra* — 1 Gbps · 650.000 GNF/mois");
      await pushBot("Tous nos forfaits incluent le Wi-Fi 6, l'installation gratuite et le support 24/7.", { delay: 900 });
      setStep("after-offres");
    } else if (key === "eligibilite") {
      pushUser("Vérifier mon éligibilité");
      setStep(null);
      await pushBot("Très bien ! Pouvez-vous m'indiquer votre commune ou quartier à Conakry ?", { delay: 700 });
      setStep("ask-address");
    } else if (key === "business") {
      pushUser("Solutions entreprises");
      setStep(null);
      await pushBot("Excellente question. Nous proposons :", { delay: 600 });
      await pushBot("• Connectivité dédiée (fibre symétrique + SLA)\n• Cloud & hébergement local\n• Cybersécurité managée\n• Infogérance IT 24/7");
      await pushBot("Souhaitez-vous qu'un de nos commerciaux B2B vous rappelle ?", { delay: 800 });
      setStep("biz-callback");
    } else if (key === "support") {
      pushUser("J'ai un problème technique");
      setStep(null);
      await pushBot("Désolée pour la gêne 🙏. Pouvez-vous me décrire brièvement le problème ?", { delay: 700 });
      setStep("free-support");
    } else if (key === "agent") {
      pushUser("Parler à un agent humain");
      setStep(null);
      await pushBot("Bien sûr ! Je transfère votre conversation à un conseiller…", { delay: 700 });
      await pushBot("✓ Karim, conseiller MouNa, prendra le relais dans un instant. Temps d'attente : ~2 min.", { delay: 1500 });
      setStep("waiting-agent");
    } else if (key === "souscrire") {
      pushUser("Souscrire en 3 min");
      setStep(null);
      await pushBot("Excellent choix 🚀 Je vais ouvrir votre compte MouNa en quelques minutes.", { delay: 700 });
      await pushBot("D'abord — pour qui ouvrez-vous ce compte ?", { delay: 900 });
      setStep("onb-type");
    } else if (key === "onb-individual") {
      pushUser("Pour moi (Particulier)");
      setOnbData((d) => ({ ...d, type: "individual" }));
      setStep(null);
      await pushBot("Très bien ! Quel est votre *nom complet* ?", { delay: 700 });
      setStep("onb-name");
    } else if (key === "onb-corporate") {
      pushUser("Pour mon entreprise");
      setOnbData((d) => ({ ...d, type: "corporate" }));
      setStep(null);
      await pushBot("Parfait ! Quelle est la *raison sociale* de votre entreprise ?", { delay: 700 });
      setStep("onb-name");
    } else if (key && key.startsWith("onb-commune-")) {
      const commune = key.replace("onb-commune-", "");
      pushUser(commune);
      setOnbData((d) => ({ ...d, commune }));
      setStep(null);
      await pushBot("Et l'*adresse complète* (rue, immeuble, étage, repère) ?", { delay: 700 });
      setStep("onb-address");
    } else if (key === "yes-eligible") {
      pushUser("Oui, je veux être rappelé(e)");
      setStep(null);
      await pushBot("Super 🎉. Un conseiller vous rappellera dans les 2 prochaines heures. Bonne journée !", { delay: 700 });
      setStep("end");
    } else if (key === "no-eligible") {
      pushUser("Non merci");
      setStep(null);
      await pushBot("Pas de souci ! Je reste à votre disposition si besoin.", { delay: 600 });
      setStep("menu");
    } else if (key === "biz-yes") {
      pushUser("Oui, rappelez-moi");
      setStep(null);
      await pushBot("Pouvez-vous me laisser votre numéro et le nom de votre entreprise ?", { delay: 700 });
      setStep("biz-info");
    } else if (key === "back-menu") {
      pushUser("Retour au menu");
      setStep("menu");
    } else if (key === "onb-upload") {
      fileRef.current?.click();
    } else if (key === "onb-camera") {
      pushUser("📷 Prendre un selfie");
      setStep("onb-camera-active");
      startCamera();
    } else if (key === "onb-capture") {
      capturePhoto();
    } else if (key === "onb-cancel-camera") {
      stopCamera();
      setStep("onb-photo");
    } else if (key === "onb-skip-photo") {
      pushUser("Passer cette étape");
      setStep(null);
      await pushBot("Pas de souci, vous pourrez l'ajouter plus tard depuis votre espace client.", { delay: 600 });
      await pushBot("Quelle est votre *adresse email* ?", { delay: 800 });
      setStep("onb-email");
    } else if (key === "onb-use-gps") {
      pushUser("📍 Utiliser ma position");
      requestGPS();
    } else if (key === "onb-pick-map") {
      pushUser("🗺️ Choisir sur la carte");
      setStep(null);
      await pushBot("Touchez la carte pour placer votre adresse précisément.", { delay: 500 });
      setPickedCoords(null);
      setStep("onb-gps-pick");
    } else if (key === "onb-confirm-pick") {
      if (pickedCoords) {
        handleGPSResult(pickedCoords);
        setPickedCoords(null);
      }
    } else if (key === "onb-skip-gps") {
      pushUser("Continuer sans GPS");
      setOnbData((d) => ({ ...d, coords: { lat: 9.5092, lng: -13.7122, accuracy: 0, fallback: true } }));
      setStep(null);
      await pushBot("Pas de problème, votre adresse écrite suffit pour le moment.", { delay: 600 });
      await pushBot(`📩 Code OTP envoyé à *${onbData.email}* et par SMS au *${onbData.phone}*.`, { delay: 1100 });
      await pushBot("Entrez le code à *6 chiffres* reçu.", { delay: 700 });
      setStep("onb-otp");
    } else if (key && key.startsWith("onb-offer-")) {
      const id = key.replace("onb-offer-", "");
      const offers = {
        start: { id: "start", name: "Mouna Start", speed: "100 Mbps", price: "150.000 GNF/mois" },
        pro: { id: "pro", name: "Mouna Pro", speed: "500 Mbps", price: "350.000 GNF/mois" },
        ultra: { id: "ultra", name: "Mouna Ultra", speed: "1 Gbps", price: "650.000 GNF/mois" },
      };
      const off = offers[id];
      pushUser(`${off.name} — ${off.speed}`);
      setOnbData((d) => ({ ...d, offer: off }));
      setStep(null);
      await pushBot(`✓ Excellent choix : *${off.name}* (${off.price}).`, { delay: 700 });
      await pushBot("Comment souhaitez-vous régler ?", { delay: 900 });
      setStep("onb-timing");
    } else if (key === "onb-pay-now") {
      pushUser("⚡ Payer maintenant");
      setOnbData((d) => ({ ...d, paymentTiming: "instant" }));
      setStep(null);
      await pushBot("Quel moyen de paiement préférez-vous ?", { delay: 700 });
      setStep("onb-method");
    } else if (key === "onb-pay-later") {
      pushUser("📅 Payer plus tard");
      setOnbData((d) => ({ ...d, paymentTiming: "later" }));
      setStep(null);
      await pushBot("Traitement de votre commande…", { delay: 800 });
      await finalizeOnboarding("later");
    } else if (key === "onb-pm-card") {
      pushUser("💳 Carte bancaire");
      setOnbData((d) => ({ ...d, paymentMethod: "card" }));
      setStep(null);
      await pushBot("Entrez votre *numéro de carte* (16 chiffres, espaces autorisés).", { delay: 700 });
      setStep("onb-card-number");
    } else if (key === "onb-pm-om") {
      pushUser("🟠 Orange Money");
      setOnbData((d) => ({ ...d, paymentMethod: "om" }));
      setStep(null);
      await pushBot("Entrez votre *numéro Orange Money* (+224 6XX…)", { delay: 700 });
      setStep("onb-mm-phone");
    } else if (key === "onb-pm-momo") {
      pushUser("🟡 MTN MoMo");
      setOnbData((d) => ({ ...d, paymentMethod: "momo" }));
      setStep(null);
      await pushBot("Entrez votre *numéro MTN MoMo* (+224 6XX…)", { delay: 700 });
      setStep("onb-mm-phone");
    }
  };

  const sendInput = async () => {
    const text = input.trim();
    if (!text) return;
    pushUser(text);
    setInput("");

    if (step === "ask-address") {
      setStep(null);
      await pushBot(`Merci ! Je vérifie la couverture pour "${text}"…`, { delay: 700 });
      await pushBot("✓ Bonne nouvelle — votre zone est éligible jusqu'à *1 Gbps* en fibre.", { delay: 1500 });
      await pushBot("Souhaitez-vous être rappelé(e) gratuitement pour planifier l'installation ?", { delay: 700 });
      setStep("confirm-eligible");
    } else if (step === "free-support") {
      setStep(null);
      await pushBot("Merci pour ces précisions. Un technicien va examiner votre ligne.", { delay: 900 });
      await pushBot("Pouvez-vous me confirmer votre numéro client ou de téléphone ?", { delay: 800 });
      setStep("support-id");
    } else if (step === "support-id") {
      setStep(null);
      await pushBot("Parfait ✓. Ticket #MN-" + Math.floor(10000 + Math.random()*89999) + " ouvert. Un technicien vous contactera sous 30 min.", { delay: 900 });
      setStep("end");
    } else if (step === "biz-info") {
      setStep(null);
      await pushBot("Merci ! Demande transmise à notre équipe B2B. Un commercial vous rappellera sous 24h ouvrées.", { delay: 900 });
      setStep("end");
    } else if (step === "onb-name") {
      setOnbData((d) => ({ ...d, name: text }));
      setStep(null);
      await pushBot(`Enchantée *${text.split(" ")[0]}* 👋`, { delay: 600 });
      if (onbData.type === "corporate") {
        await pushBot("Quelle est votre *adresse email* professionnelle ?", { delay: 800 });
        setStep("onb-email");
      } else {
        await pushBot("Avant de continuer — pouvez-vous ajouter une *photo de profil* (ou selfie) pour vérifier votre identité ?", { delay: 800 });
        setStep("onb-photo");
      }
    } else if (step === "onb-email") {
      const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(text);
      if (!emailOk) {
        await pushBot("Hmm, cet email semble invalide. Pouvez-vous le retaper ?", { delay: 600 });
        return;
      }
      setOnbData((d) => ({ ...d, email: text }));
      setStep(null);
      await pushBot("Et votre *numéro de téléphone* (format +224) ?", { delay: 700 });
      setStep("onb-phone");
    } else if (step === "onb-phone") {
      const phoneOk = /[+0-9 ]{8,}/.test(text);
      if (!phoneOk) {
        await pushBot("Numéro invalide — réessayez (ex. +224 628 12 34 56).", { delay: 600 });
        return;
      }
      setOnbData((d) => ({ ...d, phone: text }));
      setStep(null);
      await pushBot("Dans quelle *commune* souhaitez-vous l'installation ?", { delay: 700 });
      setStep("onb-commune");
    } else if (step === "onb-address") {
      setOnbData((d) => ({ ...d, address: text }));
      setStep(null);
      await pushBot(`✓ Adresse enregistrée.`, { delay: 600 });
      await pushBot("Activez votre *position GPS* pour confirmer le lieu d'installation — cela nous aide à valider la couverture fibre.", { delay: 900 });
      setStep("onb-gps");
    } else if (step === "onb-otp") {
      const otpOk = /^\d{6}$/.test(text.replace(/\s+/g, ""));
      if (!otpOk) {
        await pushBot("Le code doit contenir 6 chiffres. Réessayez.", { delay: 600 });
        return;
      }
      setStep(null);
      await pushBot("Vérification du code…", { delay: 700 });
      await pushBot("✓ Code validé !", { delay: 1200 });
      await pushBot("Choisissez maintenant votre forfait Internet 📶", { delay: 900 });
      setStep("onb-offer");
    } else if (step === "onb-card-number") {
      const digits = text.replace(/\s/g, "");
      if (!/^\d{16}$/.test(digits)) {
        await pushBot("Le numéro doit contenir exactement 16 chiffres. Réessayez.", { delay: 600 });
        return;
      }
      setOnbData((d) => ({ ...d, card: { ...(d.card || {}), number: digits } }));
      setStep(null);
      await pushBot("Maintenant le *nom sur la carte* (tel qu'écrit).", { delay: 700 });
      setStep("onb-card-name");
    } else if (step === "onb-card-name") {
      setOnbData((d) => ({ ...d, card: { ...(d.card || {}), name: text } }));
      setStep(null);
      await pushBot("Date d'*expiration* au format MM/AA (ex. 12/27).", { delay: 700 });
      setStep("onb-card-exp");
    } else if (step === "onb-card-exp") {
      if (!/^\d{2}\/\d{2}$/.test(text)) {
        await pushBot("Format invalide. Utilisez MM/AA, ex. 12/27.", { delay: 600 });
        return;
      }
      setOnbData((d) => ({ ...d, card: { ...(d.card || {}), exp: text } }));
      setStep(null);
      await pushBot("Et le *CVV* (3 chiffres au dos de la carte).", { delay: 700 });
      setStep("onb-card-cvv");
    } else if (step === "onb-card-cvv") {
      if (!/^\d{3,4}$/.test(text.replace(/\s/g, ""))) {
        await pushBot("Le CVV doit contenir 3 ou 4 chiffres. Réessayez.", { delay: 600 });
        return;
      }
      setOnbData((d) => ({ ...d, card: { ...(d.card || {}), cvv: text } }));
      setStep(null);
      await pushBot("🔒 Traitement du paiement…", { delay: 900 });
      await finalizeOnboarding("instant");
    } else if (step === "onb-mm-phone") {
      if (!/^[+0-9 ]{8,}$/.test(text)) {
        await pushBot("Numéro invalide — utilisez chiffres et + (min. 8 caractères).", { delay: 600 });
        return;
      }
      const mmLabel = onbData.paymentMethod === "om" ? "Orange Money" : "MTN MoMo";
      setOnbData((d) => ({ ...d, mm: { phone: text } }));
      setStep(null);
      await pushBot(`📱 Une notification USSD a été envoyée à *${text}*. Validez-la sur votre téléphone (${mmLabel}).`, { delay: 900 });
      await finalizeOnboarding("instant");
    } else {
      // Generic fallback
      setStep(null);
      await pushBot("Merci pour votre message. Souhaitez-vous que je vous oriente vers une de nos options ?", { delay: 700 });
      setStep("menu");
    }
  };

  const onKey = (e) => {
    if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendInput(); }
  };

  const renderQuickReplies = () => {
    if (step === "menu") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("souscrire")}>🚀 Souscrire en 3 min <span className="arr">›</span></button>
          <button onClick={() => choose("offres")}>📶 Voir les offres internet <span className="arr">›</span></button>
          <button onClick={() => choose("eligibilite")}>📍 Vérifier mon éligibilité <span className="arr">›</span></button>
          <button onClick={() => choose("business")}>🏢 Solutions entreprises <span className="arr">›</span></button>
          <button onClick={() => choose("support")}>🛠️ J'ai un problème technique <span className="arr">›</span></button>
          <button onClick={() => choose("agent")}>👤 Parler à un agent humain <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-type") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-individual")}>👤 Pour moi (Particulier) <span className="arr">›</span></button>
          <button onClick={() => choose("onb-corporate")}>🏢 Pour mon entreprise <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-photo") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-upload")}>📁 Téléverser une photo <span className="arr">›</span></button>
          <button onClick={() => choose("onb-camera")}>📷 Prendre un selfie <span className="arr">›</span></button>
          <button onClick={() => choose("onb-skip-photo")}>Passer cette étape <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-camera-active") {
      return (
        <div className="wa-camera-card">
          <video ref={videoRef} muted playsInline className="wa-camera-video" />
          <div className="wa-quick-replies">
            <button onClick={() => choose("onb-capture")}>📸 Capturer la photo <span className="arr">›</span></button>
            <button onClick={() => choose("onb-cancel-camera")}>Annuler <span className="arr">›</span></button>
          </div>
        </div>
      );
    }
    if (step === "onb-gps") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-use-gps")} disabled={geoLoading}>
            {geoLoading ? "📍 Localisation…" : "📍 Utiliser ma position actuelle"} <span className="arr">›</span>
          </button>
          <button onClick={() => choose("onb-pick-map")} disabled={geoLoading}>
            🗺️ Choisir sur la carte <span className="arr">›</span>
          </button>
          <button onClick={() => choose("onb-skip-gps")} disabled={geoLoading}>
            Continuer sans GPS <span className="arr">›</span>
          </button>
        </div>
      );
    }
    if (step === "onb-gps-pick") {
      const handleMapClick = (e) => {
        if (e.target.closest("button")) return;
        const rect = e.currentTarget.getBoundingClientRect();
        const vx = (e.clientX - rect.left) / rect.width;
        const vy = (e.clientY - rect.top) / rect.height;
        const z = pickerZoom;
        const wx = Math.max(0, Math.min(1, 0.5 + (vx - 0.5) / z));
        const wy = Math.max(0, Math.min(1, 0.5 + (vy - 0.5) / z));
        const lng = -13.80 + wx * 0.25;
        const lat = 9.65 - wy * 0.20;
        setPickedCoords({ lat, lng, accuracy: 50, x: wx * 100, y: wy * 100, picked: true });
      };
      const pinVx = pickedCoords ? 50 + (pickedCoords.x - 50) * pickerZoom : 50;
      const pinVy = pickedCoords ? 50 + (pickedCoords.y - 50) * pickerZoom : 50;
      const pinInView = pinVx >= 0 && pinVx <= 100 && pinVy >= 0 && pinVy <= 100;
      return (
        <div className="wa-map-picker">
          <div className="wa-map-picker-canvas" onClick={handleMapClick}>
            <div className="wa-map-picker-inner" style={{ transform: `scale(${pickerZoom})` }}>
              <div className="wa-map-picker-roads"></div>
              <div className="wa-map-picker-labels">
                <span style={{ top: "18%", left: "12%" }}>Ratoma</span>
                <span style={{ top: "42%", left: "28%" }}>Dixinn</span>
                <span style={{ top: "62%", left: "52%" }}>Matam</span>
                <span style={{ top: "80%", left: "70%" }}>Kaloum</span>
                <span style={{ top: "30%", left: "62%" }}>Matoto</span>
              </div>
            </div>
            <div className="wa-zoom-ctrl">
              <button onClick={(e) => { e.stopPropagation(); setPickerZoom((z) => Math.min(4, +(z + 0.5).toFixed(2))); }} disabled={pickerZoom >= 4} aria-label="Zoom in">+</button>
              <button onClick={(e) => { e.stopPropagation(); setPickerZoom((z) => Math.max(1, +(z - 0.5).toFixed(2))); }} disabled={pickerZoom <= 1} aria-label="Zoom out">−</button>
            </div>
            {pickedCoords && pinInView && (
              <div className="wa-map-picker-pin" style={{ left: pinVx + "%", top: pinVy + "%" }}>
                <svg width="28" height="34" viewBox="0 0 24 30" fill="currentColor">
                  <path d="M12 0C5.4 0 0 5.4 0 12c0 9 12 18 12 18s12-9 12-18C24 5.4 18.6 0 12 0zm0 16.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"/>
                </svg>
              </div>
            )}
            {!pickedCoords && (
              <div className="wa-map-picker-hint">Touchez la carte pour placer votre position</div>
            )}
          </div>
          {pickedCoords && (
            <div className="wa-map-picker-coords mono">
              📍 {pickedCoords.lat.toFixed(5)}, {pickedCoords.lng.toFixed(5)} · {pickerZoom}×
            </div>
          )}
          <div className="wa-quick-replies">
            <button onClick={() => choose("onb-confirm-pick")} disabled={!pickedCoords}>
              ✓ Confirmer cette position <span className="arr">›</span>
            </button>
            <button onClick={() => { setPickedCoords(null); setPickerZoom(1); setStep("onb-gps"); }}>
              ← Retour <span className="arr">›</span>
            </button>
          </div>
        </div>
      );
    }
    if (step === "onb-commune") {
      return (
        <div className="wa-quick-replies">
          {["Kaloum","Dixinn","Matam","Ratoma","Matoto","Coyah","Dubréka"].map(c => (
            <button key={c} onClick={() => choose("onb-commune-" + c)}>📍 {c} <span className="arr">›</span></button>
          ))}
        </div>
      );
    }
    if (step === "onb-offer") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-offer-start")}>🟢 *Start* — 100 Mbps · 150.000 GNF <span className="arr">›</span></button>
          <button onClick={() => choose("onb-offer-pro")}>🟣 *Pro* — 500 Mbps · 350.000 GNF <span className="arr">›</span></button>
          <button onClick={() => choose("onb-offer-ultra")}>⚡ *Ultra* — 1 Gbps · 650.000 GNF <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-timing") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-pay-now")}>⚡ Payer maintenant <span className="arr">›</span></button>
          <button onClick={() => choose("onb-pay-later")}>📅 Payer plus tard (facture sous 7 jours) <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-method") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("onb-pm-card")}>💳 Carte bancaire (Visa / Mastercard) <span className="arr">›</span></button>
          <button onClick={() => choose("onb-pm-om")}>🟠 Orange Money <span className="arr">›</span></button>
          <button onClick={() => choose("onb-pm-momo")}>🟡 MTN Mobile Money <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "onb-success") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => window.open("https://selfcare.mounagroup.com", "_blank")}>🔐 Définir mon mot de passe <span className="arr">›</span></button>
          <button onClick={() => choose("back-menu")}>↩ Retour au menu <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "after-offres") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("eligibilite")}>📍 Vérifier l'éligibilité <span className="arr">›</span></button>
          <button onClick={() => choose("agent")}>👤 Parler à un conseiller <span className="arr">›</span></button>
          <button onClick={() => choose("back-menu")}>↩ Retour au menu <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "confirm-eligible") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("yes-eligible")}>✓ Oui, rappelez-moi <span className="arr">›</span></button>
          <button onClick={() => choose("no-eligible")}>Non merci <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "biz-callback") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("biz-yes")}>✓ Oui, rappelez-moi <span className="arr">›</span></button>
          <button onClick={() => choose("back-menu")}>↩ Retour au menu <span className="arr">›</span></button>
        </div>
      );
    }
    if (step === "end") {
      return (
        <div className="wa-quick-replies">
          <button onClick={() => choose("back-menu")}>↩ Retour au menu <span className="arr">›</span></button>
        </div>
      );
    }
    return null;
  };

  const inputEnabled = step === "ask-address" || step === "free-support" || step === "support-id" || step === "biz-info" || step === "waiting-agent" || step === "onb-name" || step === "onb-email" || step === "onb-phone" || step === "onb-address" || step === "onb-otp" || step === "onb-card-number" || step === "onb-card-name" || step === "onb-card-exp" || step === "onb-card-cvv" || step === "onb-mm-phone" || step === null;
  const inputPlaceholder = (() => {
    if (step === "ask-address") return "Votre commune ou quartier…";
    if (step === "free-support") return "Décrivez votre problème…";
    if (step === "support-id") return "Numéro client ou téléphone…";
    if (step === "biz-info") return "Entreprise + numéro…";
    if (step === "waiting-agent") return "Écrivez un message…";
    if (step === "onb-name") return onbData.type === "corporate" ? "Raison sociale…" : "Prénom et nom…";
    if (step === "onb-email") return "vous@exemple.com";
    if (step === "onb-phone") return "+224 6XX XX XX XX";
    if (step === "onb-address") return "Av. de la République, immeuble…";
    if (step === "onb-otp") return "Code à 6 chiffres";
    if (step === "onb-card-number") return "1234 5678 9012 3456";
    if (step === "onb-card-name") return "Nom sur la carte…";
    if (step === "onb-card-exp") return "MM/AA";
    if (step === "onb-card-cvv") return "CVV";
    if (step === "onb-mm-phone") return "+224 6XX XX XX XX";
    return "Tapez votre message…";
  })();

  // Format **bold** markup
  const renderText = (text) =>
    text.split("\n").map((line, i) => (
      <div key={i}>
        {line.split(/(\*[^*]+\*)/).map((part, j) =>
          part.startsWith("*") && part.endsWith("*")
            ? <strong key={j}>{part.slice(1, -1)}</strong>
            : <React.Fragment key={j}>{part}</React.Fragment>
        )}
      </div>
    ));

  return (
    <React.Fragment>
      <button className="wa-launcher" onClick={() => setOpen(true)} aria-label="Ouvrir le chat support">
        <Icons.WA size={30} />
        {showBadge && <span className="wa-badge">1</span>}
      </button>

      <div className={"wa-panel" + (open ? " open" : "")} role="dialog" aria-label="Chat support MouNa">
        <input ref={fileRef} type="file" accept="image/*" style={{ display: "none" }} onChange={onFileChange} />
        <div className="wa-header">
          <div className="wa-avatar">A</div>
          <div className="wa-header-info">
            <div className="wa-header-name">Support MouNa</div>
            <div className="wa-header-status">en ligne · répond en ~2 min</div>
          </div>
          <button className="wa-header-close" onClick={() => setOpen(false)} aria-label="Fermer">
            <Icons.Close size={18} />
          </button>
        </div>

        <div className="wa-body" ref={bodyRef}>
          <div className="wa-day-divider">Aujourd'hui</div>
          <div className="wa-banner">🔒 Les messages sont chiffrés de bout en bout</div>
          {messages.map((m, i) => (
            <div key={i} className={"wa-msg " + m.from + (m.image || m.map ? " has-media" : "")}>
              {m.image && <img src={m.image} className="wa-msg-img" alt="" />}
              {m.map && (
                <div className="wa-msg-map">
                  <div className="wa-msg-map-grid"></div>
                  <div className="wa-msg-map-pin">
                    <svg width="22" height="28" viewBox="0 0 24 30" fill="currentColor">
                      <path d="M12 0C5.4 0 0 5.4 0 12c0 9 12 18 12 18s12-9 12-18C24 5.4 18.6 0 12 0zm0 16.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"/>
                    </svg>
                  </div>
                </div>
              )}
              {m.text && renderText(m.text)}
              <div className="wa-msg-time">
                {m.time}
                {m.from === "out" && <span className="checks">✓✓</span>}
              </div>
            </div>
          ))}
          {typing && (
            <div className="wa-typing"><span></span><span></span><span></span></div>
          )}
          {!typing && renderQuickReplies()}
        </div>

        <div className="wa-input">
          <input
            type="text"
            placeholder={inputPlaceholder}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={onKey}
            disabled={!inputEnabled}
          />
          <button onClick={sendInput} disabled={!input.trim()} aria-label="Envoyer">
            <Icons.Send size={18} />
          </button>
        </div>
      </div>
    </React.Fragment>
  );
}

window.Chatbot = Chatbot;
