/**
 * Oveyo PWA V8.0.1 — Refonte design page-share
 * ===============================================
 *
 * Corrections V8.0.1 :
 *   - Icônes Lucide blanches dans boxes plus petites (40×40, pas 56×56)
 *   - Safe-area-inset-top pour ne pas être collé sous le status bar iOS
 *   - Couleurs cohérentes avec page-home (navy pour bouton primary)
 *   - Photos/picker : design uniforme bg-white + border #EAEEF4
 *   - Pas d'emoji rendus comme icônes (l'emoji 🏪 affiche un logo Apple coloré
 *     qui ne correspond pas au DA Oveyo) → on utilise les icônes Lucide
 *   - Espacement cohérent (px-5, gap-3)
 *   - Plus d'aération sur les formulaires
 *
 * Composants exposés sur window :
 *   - SharePicker
 *   - QuartierForm, EnseigneForm, StationForm, PharmacieForm
 */

// ============================================================
// Helper : safe-area-top pour ne pas être collé au status bar
// ============================================================
const SAFE_TOP = {
  paddingTop: 'calc(env(safe-area-inset-top, 0px) + 16px)',
};


// ============================================================
// SharePicker — page principale "Tu signales quoi ?"
// ============================================================
const SharePicker = ({ state, setState, setActiveTab, onLoginRequired }) => {
  const { ArrowLeft, ChevronRight, Store, Fuel, Pill, ShoppingBasket, Camera } = window.LucideReact || {};

  // Fix 0.10 — On NE force PLUS la modal Login au mount du SharePicker.
  // L'utilisateur peut explorer les 4 catégories sans être loggé. Les
  // sous-formulaires (Quartier/Enseigne/Station/Pharmacie) demanderont
  // l'auth au moment de submit. Cadenas visuel reste sur les boutons.
  const isLoggedIn = !!state?.user?.session_token;

  const [categories, setCategories] = React.useState([]);
  const [selectedCategory, setSelectedCategory] = React.useState(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    (async () => {
      try {
        const r = await fetch('/api/pwa/categories');
        if (r.ok) {
          const d = await r.json();
          setCategories(d.categories || []);
        }
      } catch (e) { /* silent */ }
      finally { setLoading(false); }
    })();
  }, []);

  // Mapping slug → composant Lucide (icône blanche dans une box colorée)
  const ICON_FOR = {
    quartier:  ShoppingBasket,
    enseigne:  Store,
    station:   Fuel,
    pharmacie: Pill,
  };

  if (selectedCategory) {
    const props = {
      state,
      setState,
      setActiveTab,
      onLoginRequired,
      onBack: () => setSelectedCategory(null),
      category: selectedCategory,
    };
    if (selectedCategory.slug === 'quartier' && window.QuartierForm)  return <window.QuartierForm  {...props} />;
    if (selectedCategory.slug === 'enseigne' && window.EnseigneForm)  return <window.EnseigneForm  {...props} />;
    if (selectedCategory.slug === 'station'  && window.StationForm)   return <window.StationForm   {...props} />;
    if (selectedCategory.slug === 'pharmacie'&& window.PharmacieForm) return <window.PharmacieForm {...props} />;
    /* V8.1-PHOTO-ENABLED V8.1 : routing vers PhotoForm */
    if (selectedCategory.slug === 'photo'    && window.PhotoForm)     return <window.PhotoForm     {...props} />;

    return (
      <div className="px-5" style={SAFE_TOP}>
        <button onClick={() => setSelectedCategory(null)} className="flex items-center gap-1.5 text-sm font-bold text-slate mb-4">
          <ArrowLeft size={18} /> Retour
        </button>
        <div className="bg-white rounded-2xl p-5 text-center" style={{ border: '1px solid #EAEEF4' }}>
          <p className="text-sm text-slate">Formulaire en cours de chargement…</p>
        </div>
      </div>
    );
  }

  return (
    <div className="px-5 pb-28" style={SAFE_TOP}>
      {/* V8.0.2-FIXES V8.0.2 : intitulé adouci + plus d'espacement */}
      <div className="mb-7">
        <h1 className="font-display font-bold text-2xl text-ink leading-tight">Que veux-tu partager ?</h1>
        <p className="text-sm text-slate mt-1.5 leading-snug">Choisis le type de prix que tu souhaites partager</p>
      </div>

      {loading && (
        <div className="text-center py-8 text-sm text-slate">Chargement…</div>
      )}

      {!loading && categories.length === 0 && (
        <div className="bg-white rounded-2xl p-5 text-center" style={{ border: '1px solid #FEE2E2' }}>
          <p className="text-sm text-orange">Impossible de charger les catégories. Réessaie plus tard.</p>
        </div>
      )}

      <div className="space-y-3">
        {categories.map((cat) => {
          const Icon = ICON_FOR[cat.slug];
          return (
            <button
              key={cat.slug}
              onClick={() => setSelectedCategory(cat)}
              className="w-full bg-white rounded-2xl p-4 flex items-center gap-3 text-left active:opacity-70 transition-opacity"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div
                className="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
                style={{ background: cat.color || '#102A43' }}
              >
                {Icon && <Icon size={20} strokeWidth={2.2} className="text-white" />}
              </div>
              <div className="flex-1 min-w-0">
                <div className="font-display font-bold text-[15px] text-ink leading-tight">{cat.label_fr}</div>
                <div className="text-xs text-slate mt-0.5 leading-snug">{cat.description}</div>
              </div>
              <ChevronRight size={18} className="text-slate flex-shrink-0" strokeWidth={2.2} />
            </button>
          );
        })}

        {/* V8.1-PHOTO-ENABLED V8.1 : Photo activée — extract multi-produits via Claude Vision */}
        <button
          onClick={() => setSelectedCategory({ slug: 'photo', label_fr: 'Photographier des prix', icon: '📸', color: '#9333EA' })}
          className="w-full bg-white rounded-2xl p-4 flex items-center gap-3 text-left active:opacity-70 transition-opacity"
          style={{ border: '1px solid #E9D5FF' }}
        >
          <div
            className="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
            style={{ background: '#9333EA' }}
          >
            <Camera size={20} strokeWidth={2.2} className="text-white" />
          </div>
          <div className="flex-1 min-w-0">
            <div className="font-display font-bold text-[15px] text-ink leading-tight">
              Photographier <span className="text-[9px] font-bold uppercase tracking-wider ml-1 px-1.5 py-0.5 rounded" style={{ background: '#FAF5FF', color: '#9333EA' }}>NOUVEAU</span>
            </div>
            <div className="text-xs text-slate mt-0.5 leading-snug">Ticket, rayon, flyer — extrait tous les prix d'un coup ✨</div>
          </div>
          <ChevronRight size={18} className="text-slate flex-shrink-0" strokeWidth={2.2} />
        </button>
      </div>

      <div className="mt-6 px-2 text-[11px] text-slate text-center leading-relaxed">
        Tes partages aident toute la communauté à payer le juste prix au Sénégal 🇸🇳
      </div>
    </div>
  );
};


// ============================================================
// Helpers communs aux 4 formulaires
// ============================================================
const FormHeader = ({ onBack, icon: Icon, title, color, step, totalSteps, subtitle }) => {
  const { ArrowLeft } = window.LucideReact || {};
  return (
    <>
      <button onClick={onBack} className="flex items-center gap-1.5 text-sm font-bold text-slate mb-4">
        <ArrowLeft size={18} strokeWidth={2.2} /> Retour
      </button>
      <div className="flex items-center gap-3 mb-4">
        <div
          className="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
          style={{ background: color }}
        >
          {Icon && <Icon size={20} strokeWidth={2.2} className="text-white" />}
        </div>
        <div className="flex-1 min-w-0">
          <h1 className="font-display font-bold text-lg text-ink leading-tight">{title}</h1>
          {step && totalSteps && (
            <p className="text-[11px] text-slate mt-0.5">Étape {step}/{totalSteps}{subtitle ? ` · ${subtitle}` : ''}</p>
          )}
        </div>
      </div>
    </>
  );
};


// ============================================================
// QUARTIER — wrapper du ReportPage existant
// ============================================================
const QuartierForm = ({ state, setState, setActiveTab, onLoginRequired, onBack, category }) => {
  const { ArrowLeft } = window.LucideReact || {};

  React.useEffect(() => {
    setState((s) => ({
      ...s,
      _share_context: { category_slug: 'quartier', branch_id: null },
    }));
  }, []);

  const ReportPage = window.ReportPage;
  if (!ReportPage) {
    return <div className="p-5 text-sm text-slate" style={SAFE_TOP}>Formulaire en cours de chargement…</div>;
  }

  return (
    <div>
      <div className="px-5 pb-2" style={SAFE_TOP}>
        <button onClick={onBack} className="flex items-center gap-1.5 text-sm font-bold text-slate">
          <ArrowLeft size={18} strokeWidth={2.2} /> Retour
        </button>
      </div>
      <ReportPage
        state={state}
        setState={setState}
        setActiveTab={setActiveTab}
        onLoginRequired={onLoginRequired}
      />
    </div>
  );
};


// ============================================================
// ENSEIGNE — 4 étapes : brand → branch → product → price
// ============================================================
const EnseigneForm = ({ state, setState, setActiveTab, onLoginRequired, onBack, category }) => {
  const { ChevronRight, Store, Plus, MapPin, Navigation } = window.LucideReact || {};
  const flash = window.OveyoUI?.useFlash ? window.OveyoUI.useFlash() : { show: () => {} };

  const [step, setStep] = React.useState('brand');
  const [brands, setBrands] = React.useState([]);
  const [branches, setBranches] = React.useState([]);
  const [products, setProducts] = React.useState([]);
  const [selectedBrand, setSelectedBrand] = React.useState(null);
  const [selectedBranch, setSelectedBranch] = React.useState(null);
  const [selectedProduct, setSelectedProduct] = React.useState(null);
  const [price, setPrice] = React.useState('');
  const [available, setAvailable] = React.useState(true);
  const [submitting, setSubmitting] = React.useState(false);
  const [quantity, setQuantity] = React.useState(''); // Sprint 3 - quantite libre
  const [showGpsPrompt, setShowGpsPrompt] = React.useState(false);

  // V9.2.4 — Catalogue ouvert dans flow Enseigne
  const [pendingNewProduct, setPendingNewProduct] = React.useState(null);
  const [newProductName, setNewProductName] = React.useState('');
  const [newProductCategory, setNewProductCategory] = React.useState('alimentaire');
  const [gpsPromptDone, setGpsPromptDone] = React.useState(false);
  const [showCreateBranch, setShowCreateBranch] = React.useState(false);
  const [newBranchName, setNewBranchName] = React.useState('');

  // V10.7.0 — État Localisation : quartier + GPS
  const [neighborhood, setNeighborhood] = React.useState('');
  const [gettingGps, setGettingGps] = React.useState(false);

  // V10.7.0 — Pré-remplit le quartier depuis la succursale sélectionnée
  React.useEffect(() => {
    if (selectedBranch?.neighborhood_name) {
      setNeighborhood(selectedBranch.neighborhood_name);
    }
  }, [selectedBranch]);

  // V10.7.0 — Bouton GPS : récupère la géolocalisation
  const askGps = () => {
    if (!navigator.geolocation) {
      flash.show('error', 'Géolocalisation non supportée');
      return;
    }
    setGettingGps(true);
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setState((s) => ({
          ...s,
          user: {
            ...s.user,
            geolocation: { lat: pos.coords.latitude, lng: pos.coords.longitude, ts: Date.now() },
          },
        }));
        setGettingGps(false);
        flash.show('success', 'Position OK');
      },
      (err) => {
        setGettingGps(false);
        const msg = err.code === 1 ? 'Autorise la géolocalisation dans Réglages'
          : err.code === 2 ? 'Position indisponible'
          : 'Erreur de géolocalisation';
        flash.show('error', msg);
      },
      { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
    );
  };

  const isLoggedIn = !!state.user?.session_token;

  React.useEffect(() => {
    fetch('/api/pwa/brands?category=enseigne')
      .then((r) => r.json())
      .then((d) => {
        // Filtrer les brands non pertinents pour le picker
        const filtered = (d.brands || []).filter((b) =>
          !['sococim', 'peyrissac'].includes(b.slug)
        );
        setBrands(filtered);
      })
      .catch(() => setBrands([]));
  }, []);

  React.useEffect(() => {
    if (!selectedBrand) return;
    fetch(`/api/pwa/branches?brand_id=${selectedBrand.id}`)
      .then((r) => r.json())
      .then((d) => setBranches(d.branches || []))
      .catch(() => setBranches([]));
  }, [selectedBrand]);

  React.useEffect(() => {
    if (step !== 'product' || products.length > 0) return;
    fetch('/api/pwa/catalog')
      .then((r) => r.json())
      .then((d) => {
        const allProducts = d.products || [];
        // V9.1.1 — Boutique : exclut energie sauf gaz 2,7kg et 6kg (vendus en quartier)
        const BOUTIQUE_GAZ_SLUGS = ['gaz-2-7kg', 'gaz'];
        const filtered = allProducts.filter(p =>
          p.category_slug !== 'energie' || BOUTIQUE_GAZ_SLUGS.includes(p.slug)
        );
        setProducts(filtered);
      })
      .catch(() => setProducts([]));
  }, [step]);

  const createBranchInline = async () => {
    if (!newBranchName.trim()) return;
    if (!isLoggedIn) { onLoginRequired?.(); return; }
    try {
      const userGeo = state.user?.geolocation || null;
      const r = await fetch('/api/pwa/branches', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + state.user.session_token },
        body: JSON.stringify({
          brand_id: selectedBrand.id,
          name: newBranchName.trim(),
          lat: userGeo?.lat || null,
          lng: userGeo?.lng || null,
        }),
      });
      const d = await r.json();
      if (d.ok && d.branch_id) {
        const b = { id: d.branch_id, name: newBranchName.trim(), verified: false, source: 'crowdsource' };
        setBranches((p) => [b, ...p]);
        setSelectedBranch(b);
        setShowCreateBranch(false);
        setNewBranchName('');
        setStep('product');
        flash.show('success', 'Succursale ajoutée — sera vérifiée');
      } else {
        flash.show('error', 'Impossible de créer la succursale');
      }
    } catch (e) { flash.show('error', 'Erreur réseau'); }
  };

  const submitObservation = async () => {
    if (!isLoggedIn) { onLoginRequired?.(); return; }
    const priceInt = parseInt(price, 10);
    if (!priceInt || priceInt < 1) { flash.show('error', 'Saisis un prix valide'); return; }
    // Sprint 3 - GPS pressant : si pas de GPS et pas encore demande, ouvrir la sheet
    if (!state.user?.geolocation && !gpsPromptDone) {
      setShowGpsPrompt(true);
      return;
    }
    setSubmitting(true);
    try {
      const userGeo = state.user?.geolocation || null;
      // V10.7.0 — priorité au quartier saisi/auto-rempli, fallback sur user
      const ngName = neighborhood.trim() || state.user.neighborhood_slug || null;
      const payload = {
        product_id: selectedProduct?.id || null,
        price: priceInt,
        available: available ? 1 : 0,
        is_abuse: 0,
        shop_name: selectedBranch?.name || selectedBrand.name,
        reported_by: state.user.phone || 'pwa-anonymous',
        neighborhood_name: ngName,
        category_slug: 'enseigne',
        brand_id: selectedBrand?.id || null,
        branch_id: selectedBranch?.id || null,
        shop_lat: userGeo?.lat || null,
        shop_lng: userGeo?.lng || null,
        quantity_label: quantity.trim() || null,
      };

      // V9.2.4 — Si nouveau produit : route vers /api/pwa/product-submission
      const isNewProduct = !!pendingNewProduct;
      const endpoint = isNewProduct ? '/api/pwa/product-submission' : '/api/pwa/observation';
      const submissionPayload = isNewProduct ? {
        proposed_name: pendingNewProduct.name,
        proposed_category_slug: pendingNewProduct.category_slug,
        price: priceInt,
        shop_name_raw: selectedBranch?.name || selectedBrand.name,
        neighborhood_name_raw: ngName,
        brand_id: selectedBrand?.id || null,
        branch_id: selectedBranch?.id || null,
        shop_lat: userGeo?.lat ?? null,
        shop_lng: userGeo?.lng ?? null,
      } : payload;

      const r = await fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + (state?.user?.session_token || ''),
        },
        body: JSON.stringify(submissionPayload),
      });
      if (r.ok) {
        if (isNewProduct) {
          flash.show('success', 'Produit soumis ! On l\'ajoute après vérification.');
        } else {
          flash.show('success', `Prix ${selectedBrand.name} enregistré !`);
        }
        setActiveTab?.('home');
      } else {
        // V8.6.1.2-ERR-DETAIL-ENS : lire detail backend pour message clair
        let msg = "Erreur lors de l'envoi";
        try {
          const errBody = await r.json();
          if (typeof errBody?.detail === 'string') msg = errBody.detail;
          else if (Array.isArray(errBody?.detail) && errBody.detail[0]?.msg) {
            const f = errBody.detail[0];
            const field = Array.isArray(f.loc) ? f.loc[f.loc.length - 1] : '';
            msg = field ? `${field}: ${f.msg}` : f.msg;
          }
        } catch {}
        flash.show('error', msg);
      }
    } catch (e) { flash.show('error', 'Erreur réseau'); }
    finally { setSubmitting(false); }
  };

  const goBack = () => {
    // V9.2.4 — depuis 'price' avec nouveau produit, retour au form newProduct
    if (step === 'price' && pendingNewProduct) setStep('newProduct');
    else if (step === 'price')   setStep('product');
    else if (step === 'newProduct') setStep('product');
    else if (step === 'product')  setStep('branch');
    else if (step === 'branch')   setStep('brand');
    else onBack();
  };

  const stepNum = step === 'brand' ? 1 : step === 'branch' ? 2 : step === 'product' ? 3 : 4;

  return (
    <div className="px-5 pb-28" style={SAFE_TOP}>
      <FormHeader
        onBack={goBack}
        icon={Store}
        title="Enseigne nationale"
        color="#7C3AED"
        step={stepNum}
        totalSteps={4}
      />

      {/* Step 1 — pick brand : pas d'icône emoji moche, juste la couleur de la marque */}
      {step === 'brand' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quelle enseigne ?</h2>
          {brands.map((b) => (
            <button
              key={b.id}
              onClick={() => { setSelectedBrand(b); setStep('branch'); }}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div
                className="w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0"
                style={{ background: b.color || '#7C3AED' }}
              >
                <Store size={18} strokeWidth={2.2} className="text-white" />
              </div>
              <div className="flex-1 font-bold text-sm text-ink">{b.name}</div>
              <ChevronRight size={18} className="text-slate" />
            </button>
          ))}
        </div>
      )}

      {/* Step 2 — pick branch */}
      {step === 'branch' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quelle succursale {selectedBrand.name} ?</h2>

          <button
            onClick={() => { setSelectedBranch(null); setSelectedProduct(null); setPrice(''); setAvailable(true); setStep('product'); }}
            className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
            style={{ border: '1px dashed #DDE3EC' }}
          >
            <div className="flex-1 text-sm text-slate italic">Pas précis / Je ne sais pas</div>
            <ChevronRight size={18} className="text-slate" />
          </button>

          {branches.map((br) => (
            <button
              key={br.id}
              onClick={() => { setSelectedBranch(br); setSelectedProduct(null); setPrice(''); setAvailable(true); setStep('product'); }}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div className="w-2 h-2 rounded-full flex-shrink-0" style={{ background: br.verified ? '#16A34A' : '#9AA5B5' }} />
              <div className="flex-1 min-w-0">
                <div className="font-bold text-sm text-ink truncate">{br.name}</div>
                {br.neighborhood_name && (
                  <div className="text-[11px] text-slate flex items-center gap-1 mt-0.5">
                    <MapPin size={10} /> {br.neighborhood_name}
                  </div>
                )}
              </div>
              <ChevronRight size={18} className="text-slate" />
            </button>
          ))}

          {!showCreateBranch ? (
            <button
              onClick={() => setShowCreateBranch(true)}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left mt-2"
              style={{ border: '1px solid #F4632B' }}
            >
              <Plus size={18} strokeWidth={2.4} style={{ color: '#F4632B' }} />
              <span className="font-bold text-sm" style={{ color: '#F4632B' }}>Ajouter une succursale</span>
            </button>
          ) : (
            <div className="bg-white rounded-xl p-4 space-y-2.5 mt-2" style={{ border: '1px solid #F4632B' }}>
              <p className="text-[11px] text-slate">Ex : {selectedBrand.name} Yoff</p>
              <input
                type="text"
                value={newBranchName}
                onChange={(e) => setNewBranchName(e.target.value)}
                placeholder={`Nom de la succursale ${selectedBrand.name}`}
                className="w-full px-3 py-2.5 rounded-lg text-sm outline-none"
                style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
                autoFocus
              />
              <div className="flex gap-2">
                <button
                  onClick={() => { setShowCreateBranch(false); setNewBranchName(''); }}
                  className="flex-1 px-3 py-2.5 rounded-lg text-sm font-bold"
                  style={{ background: '#F1F4F9', color: '#5B6B7E' }}
                >
                  Annuler
                </button>
                <button
                  onClick={createBranchInline}
                  disabled={!newBranchName.trim()}
                  className="flex-1 px-3 py-2.5 rounded-lg text-sm font-bold text-white"
                  style={{ background: '#F4632B', opacity: newBranchName.trim() ? 1 : 0.4 }}
                >
                  Créer
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Step 3 — pick product */}
      {step === 'product' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quel produit ?</h2>

          {/* V9.2.4 — Bouton catalogue ouvert */}
          <button
            onClick={() => { setNewProductName(''); setStep('newProduct'); }}
            className="w-full flex items-center justify-center gap-2 py-3 rounded-xl text-sm font-bold mb-2"
            style={{ background: '#FFF4ED', border: '1.5px dashed #F4632B', color: '#F4632B' }}
          >
            <Plus size={18} strokeWidth={2.5} />
            Mon produit n'est pas dans la liste
          </button>

          <div className="space-y-1.5 max-h-[60vh] overflow-y-auto pb-4" style={{ WebkitOverflowScrolling: 'touch' }}>
            {products
              .filter((p) => !['super', 'gasoil', 'essence_ord', 'essence_pirogue', 'petrole_lampant', 'gaz_2_7kg', 'gaz_9kg', 'gaz_12_5kg', 'gaz_38kg'].includes(p.slug))
              .map((p) => (
                <button
                  key={p.id}
                  onClick={() => { setSelectedProduct(p); setStep('price'); }}
                  className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
                  style={{ border: '1px solid #EAEEF4' }}
                >
                  <div className="w-10 h-10 rounded-lg flex items-center justify-center text-xl flex-shrink-0" style={{ background: '#F1F4F9' }}>
                    {p.icon}
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="font-bold text-sm text-ink truncate">{p.name_fr}</div>
                    <div className="text-[11px] text-slate">{p.unit}{p.price_official ? ` · officiel ${p.price_official} F` : ''}</div>
                  </div>
                  <ChevronRight size={18} className="text-slate" />
                </button>
              ))}
          </div>
        </div>
      )}

      {/* V9.2.4 — Step newProduct : saisie produit non listé (Enseigne) */}
      {step === 'newProduct' && (
        <div className="space-y-3">
          <h2 className="font-bold text-sm text-ink mb-1">Nouveau produit chez {selectedBrand?.name || 'l\'enseigne'}</h2>
          <p className="text-xs text-slate mb-2">Décris-le, on l'ajoute après vérification.</p>

          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Nom du produit *</label>
            <input
              type="text"
              value={newProductName}
              onChange={(e) => setNewProductName(e.target.value)}
              placeholder="Ex: Détergent OMO 1kg"
              maxLength={200}
              className="w-full mt-2 px-4 py-3 rounded-xl text-sm outline-none"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              autoFocus
            />
          </div>

          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider mb-2 block">Catégorie *</label>
            <div className="grid grid-cols-2 gap-2">
              {[
                { slug: 'alimentaire', label: '🛒 Alimentaire' },
                { slug: 'legumes',     label: '🥬 Légumes & Fruits' },
                { slug: 'boulangerie', label: '🍞 Boulangerie' },
                { slug: 'hygiene',     label: '🧴 Hygiène' },
                { slug: 'bebe',        label: '👶 Bébé' },
                { slug: 'medicaments', label: '💊 Médicaments' },
              ].map((cat) => (
                <button
                  key={cat.slug}
                  type="button"
                  onClick={() => setNewProductCategory(cat.slug)}
                  className="px-3 py-2.5 rounded-xl text-xs font-bold text-left"
                  style={{
                    background: newProductCategory === cat.slug ? '#7C3AED' : 'white',
                    color: newProductCategory === cat.slug ? 'white' : '#031B47',
                    border: '1px solid ' + (newProductCategory === cat.slug ? '#7C3AED' : '#DDE3EC'),
                  }}
                >
                  {cat.label}
                </button>
              ))}
            </div>
          </div>

          <button
            onClick={() => {
              const name = newProductName.trim();
              if (name.length < 2) { flash.show('error', 'Donne un nom au produit'); return; }
              setPendingNewProduct({ name, category_slug: newProductCategory });
              setStep('price');
            }}
            disabled={!newProductName.trim()}
            className="w-full py-3.5 rounded-xl text-sm font-bold mt-2"
            style={{
              background: newProductName.trim() ? '#7C3AED' : '#E5EAF0',
              color: newProductName.trim() ? 'white' : '#94A3B8',
            }}
          >
            Continuer →
          </button>
        </div>
      )}

      {/* Step 4 — saisir prix */}
      {step === 'price' && (selectedProduct || pendingNewProduct) && (
        <div className="space-y-3">
          <h2 className="font-bold text-sm text-ink mb-1">Prix {selectedBrand.name} pour {pendingNewProduct ? pendingNewProduct.name : selectedProduct.name_fr}</h2>
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Prix observé (FCFA)</label>
            <input
              type="number"
              inputMode="numeric"
              value={price}
              onChange={(e) => setPrice(e.target.value)}
              placeholder="Ex : 165"
              className="w-full mt-2 px-4 py-3 rounded-xl text-lg font-bold outline-none"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              autoFocus
            />
          </div>
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold uppercase tracking-wider text-slate">État</label>
            <div className="mt-1.5 flex rounded-xl overflow-hidden" style={{ border: '1px solid #DDE3EC' }}>
              <button
                type="button"
                onClick={() => setAvailable(true)}
                className="flex-1 py-3 text-xs font-bold flex items-center justify-center gap-1"
                style={{
                  background: available ? '#E8F5E9' : 'white',
                  color: available ? '#15803D' : '#6B7891',
                }}
              >
                ✓ Dispo
              </button>
              <button
                type="button"
                onClick={() => setAvailable(false)}
                className="flex-1 py-3 text-xs font-bold"
                style={{
                  background: !available ? '#FEEEE3' : 'white',
                  color: !available ? '#F4632B' : '#6B7891',
                }}
              >
                × Rupture
              </button>
            </div>
          </div>

          {/* Sprint 3 - Quantite (optionnel) */}
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">
              Quantité <span className="font-normal lowercase text-slate/70">(optionnel)</span>
            </label>
            <input
              type="text"
              value={quantity}
              onChange={(e) => setQuantity(e.target.value)}
              placeholder="ex: 500g, 1L, 2 pièces"
              maxLength={30}
              className="w-full mt-2 px-4 py-3 rounded-xl outline-none text-sm"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
            />
          </div>

          {/* V10.7.0 — Bloc Localisation : quartier (auto-rempli depuis succursale ou GPS) */}
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Quartier</label>
            <div className="mt-2 flex gap-2">
              <input
                type="text"
                value={neighborhood}
                onChange={(e) => setNeighborhood(e.target.value)}
                placeholder="Ex: Almadies, Plateau, Mermoz…"
                className="flex-1 px-4 py-3 rounded-xl outline-none text-sm"
                style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              />
              <button
                type="button"
                onClick={askGps}
                disabled={gettingGps}
                className="px-3 py-3 rounded-xl flex items-center gap-1.5 text-sm font-bold flex-shrink-0"
                style={{
                  background: state.user?.geolocation ? '#E8F5E9' : '#FEEEE3',
                  color: state.user?.geolocation ? '#15803D' : '#F4632B',
                  opacity: gettingGps ? 0.6 : 1,
                }}
                title="Récupérer ma position GPS"
              >
                {Navigation && <Navigation size={16} strokeWidth={2.4} />}
                {gettingGps ? '…' : (state.user?.geolocation ? 'OK' : 'GPS')}
              </button>
            </div>
            <p className="text-[10px] text-slate mt-2 leading-snug">
              {state.user?.geolocation
                ? '✓ Position partagée — la carte affichera ce prix'
                : '💡 Active le GPS pour que ton prix apparaisse sur la carte'}
            </p>
          </div>

          <button
            onClick={submitObservation}
            disabled={submitting || !price}
            className="w-full px-5 py-4 rounded-2xl font-bold text-white shadow-md"
            style={{ background: price && !submitting ? '#102A43' : '#DDE3EC' }}
          >
            {submitting ? 'Envoi…' : 'Valider le prix'}
          </button>
        </div>
      )}
      {/* Sprint 3 - GPS pressant */}
      {window.OveyoSheets?.GpsPrompt && (
        <window.OveyoSheets.GpsPrompt
          open={showGpsPrompt}
          onClose={() => setShowGpsPrompt(false)}
          onActivated={(coords) => {
            setState((s) => ({ ...s, user: { ...s.user, geolocation: { ...coords, ts: Date.now() } } }));
            setShowGpsPrompt(false);
            setGpsPromptDone(true);
            setTimeout(() => submitObservation(), 100);
          }}
          onContinueWithoutGps={() => {
            setShowGpsPrompt(false);
            setGpsPromptDone(true);
            setTimeout(() => submitObservation(), 100);
          }}
        />
      )}
    </div>
  );
};


// ============================================================
// STATION — flow station avec auto-check CRSE
// ============================================================
const StationForm = ({ state, setState, setActiveTab, onLoginRequired, onBack, category }) => {
  const { ChevronRight, Fuel, Plus, AlertTriangle, Check, MapPin, Navigation } = window.LucideReact || {};
  const flash = window.OveyoUI?.useFlash ? window.OveyoUI.useFlash() : { show: () => {} };

  const [step, setStep] = React.useState('brand');
  const [brands, setBrands] = React.useState([]);
  const [branches, setBranches] = React.useState([]);
  const [stationProducts, setStationProducts] = React.useState([]);
  // V9.2.5 — Catalogue ouvert dans flow Station (catégorie auto: 'energie')
  const [pendingNewProduct, setPendingNewProduct] = React.useState(null);
  const [newProductName, setNewProductName] = React.useState('');
  const [selectedBrand, setSelectedBrand] = React.useState(null);
  const [selectedBranch, setSelectedBranch] = React.useState(null);
  const [selectedProduct, setSelectedProduct] = React.useState(null);
  const [price, setPrice] = React.useState('');
  const [crseCheck, setCrseCheck] = React.useState(null);
  const [submitting, setSubmitting] = React.useState(false);
  const [showGpsPrompt, setShowGpsPrompt] = React.useState(false); // Sprint 3 - GPS
  const [gpsPromptDone, setGpsPromptDone] = React.useState(false); // Sprint 3 - flag
  const [available, setAvailable] = React.useState(true);
  const [newBranchName, setNewBranchName] = React.useState('');
  const [showCreateBranch, setShowCreateBranch] = React.useState(false);

  // V10.7.0 — Localisation
  const [neighborhood, setNeighborhood] = React.useState('');
  const [gettingGps, setGettingGps] = React.useState(false);

  React.useEffect(() => {
    if (selectedBranch?.neighborhood_name) {
      setNeighborhood(selectedBranch.neighborhood_name);
    }
  }, [selectedBranch]);

  const askGps = () => {
    if (!navigator.geolocation) {
      flash.show('error', 'Géolocalisation non supportée');
      return;
    }
    setGettingGps(true);
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setState((s) => ({
          ...s,
          user: {
            ...s.user,
            geolocation: { lat: pos.coords.latitude, lng: pos.coords.longitude, ts: Date.now() },
          },
        }));
        setGettingGps(false);
        flash.show('success', 'Position OK');
      },
      (err) => {
        setGettingGps(false);
        const msg = err.code === 1 ? 'Autorise la géolocalisation dans Réglages'
          : err.code === 2 ? 'Position indisponible'
          : 'Erreur de géolocalisation';
        flash.show('error', msg);
      },
      { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
    );
  };

  const isLoggedIn = !!state.user?.session_token;

  React.useEffect(() => {
    fetch('/api/pwa/brands?category=station')
      .then((r) => r.json())
      .then((d) => setBrands(d.brands || []))
      .catch(() => setBrands([]));
  }, []);

  React.useEffect(() => {
    if (!selectedBrand) return;
    fetch(`/api/pwa/branches?brand_id=${selectedBrand.id}`)
      .then((r) => r.json())
      .then((d) => setBranches(d.branches || []))
      .catch(() => setBranches([]));
  }, [selectedBrand]);

  React.useEffect(() => {
    if (step !== 'product' || stationProducts.length > 0) return;
    fetch('/api/pwa/crse/active')
      .then((r) => r.json())
      .then((d) => setStationProducts(d.prices || []))
      .catch(() => setStationProducts([]));
  }, [step]);

  React.useEffect(() => {
    if (!selectedProduct || !price || parseInt(price, 10) < 1) {
      setCrseCheck(null);
      return;
    }
    const t = setTimeout(() => {
      fetch('/api/pwa/crse/check', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          product_slug: selectedProduct.product_slug,
          observed_price: parseInt(price, 10),
        }),
      })
        .then((r) => r.json())
        .then((d) => setCrseCheck(d))
        .catch(() => setCrseCheck(null));
    }, 400);
    return () => clearTimeout(t);
  }, [price, selectedProduct]);

  const createBranchInline = async () => {
    if (!newBranchName.trim()) return;
    if (!isLoggedIn) { onLoginRequired?.(); return; }
    try {
      const userGeo = state.user?.geolocation || null;
      const r = await fetch('/api/pwa/branches', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + state.user.session_token },
        body: JSON.stringify({
          brand_id: selectedBrand.id,
          name: newBranchName.trim(),
          lat: userGeo?.lat || null,
          lng: userGeo?.lng || null,
        }),
      });
      const d = await r.json();
      if (d.ok && d.branch_id) {
        const b = { id: d.branch_id, name: newBranchName.trim(), verified: false };
        setBranches((p) => [b, ...p]);
        setSelectedBranch(b);
        setShowCreateBranch(false);
        setNewBranchName('');
        setStep('product');
      }
    } catch (e) { flash.show('error', 'Erreur réseau'); }
  };

  const submitObservation = async () => {
    if (!isLoggedIn) { onLoginRequired?.(); return; }
    const priceInt = parseInt(price, 10);
    if (!priceInt || priceInt < 1) { flash.show('error', 'Saisis un prix valide'); return; }
    // Sprint 3 - GPS pressant
    if (!state.user?.geolocation && !gpsPromptDone) {
      setShowGpsPrompt(true);
      return;
    }
    setSubmitting(true);
    try {
      const userGeo = state.user?.geolocation || null;
      const isAbuse = crseCheck && crseCheck.compliance === 'above' ? 1 : 0;
      // Sprint 3 - Conformite CRSE: 1=conforme, 0=non conforme, null=pas de prix CRSE
      let crseCompliant = null;
      if (crseCheck && crseCheck.has_crse) {
        crseCompliant = crseCheck.compliance === 'above' ? 0 : 1;
      }
      // V10.7.0 — Quartier saisi prioritaire
      const ngName = neighborhood.trim() || state.user.neighborhood_slug || null;
      const payload = {
        product_id: selectedProduct?.product_id || null,
        price: priceInt,
        available: available ? 1 : 0,
        is_abuse: isAbuse,
        crse_compliant: crseCompliant,
        shop_name: selectedBranch?.name || selectedBrand.name,
        reported_by: state.user.phone || 'pwa-anonymous',
        neighborhood_name: ngName,
        category_slug: 'station',
        brand_id: selectedBrand?.id || null,
        branch_id: selectedBranch?.id || null,
        shop_lat: userGeo?.lat || null,
        shop_lng: userGeo?.lng || null,
      };

      // V9.2.5 — Si nouveau produit Station : route vers /api/pwa/product-submission
      const isNewProduct = !!pendingNewProduct;
      const endpoint = isNewProduct ? '/api/pwa/product-submission' : '/api/pwa/observation';
      const submissionPayload = isNewProduct ? {
        proposed_name: pendingNewProduct.name,
        proposed_category_slug: 'energie',
        price: priceInt,
        shop_name_raw: selectedBranch?.name || selectedBrand.name,
        neighborhood_name_raw: ngName,
        brand_id: selectedBrand?.id || null,
        branch_id: selectedBranch?.id || null,
        shop_lat: userGeo?.lat ?? null,
        shop_lng: userGeo?.lng ?? null,
      } : payload;

      const r = await fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + (state?.user?.session_token || ''),
        },
        body: JSON.stringify(submissionPayload),
      });
      if (r.ok) {
        if (isNewProduct) {
          flash.show('success', 'Produit soumis ! On l\'ajoute après vérification.');
        } else {
          flash.show('success', `Prix ${selectedBrand.name} enregistré !`);
        }
        setActiveTab?.('home');
      } else {
        // V8.6.1.2-ERR-DETAIL-STA : lire detail backend pour message clair
        let msg = "Erreur lors de l'envoi";
        try {
          const errBody = await r.json();
          if (typeof errBody?.detail === 'string') msg = errBody.detail;
          else if (Array.isArray(errBody?.detail) && errBody.detail[0]?.msg) {
            const f = errBody.detail[0];
            const field = Array.isArray(f.loc) ? f.loc[f.loc.length - 1] : '';
            msg = field ? `${field}: ${f.msg}` : f.msg;
          }
        } catch {}
        flash.show('error', msg);
      }
    } catch (e) { flash.show('error', 'Erreur réseau'); }
    finally { setSubmitting(false); }
  };

  const goBack = () => {
    // V9.2.4 — depuis 'price' avec nouveau produit, retour au form newProduct
    if (step === 'price' && pendingNewProduct) setStep('newProduct');
    else if (step === 'price')   setStep('product');
    else if (step === 'newProduct') setStep('product');
    else if (step === 'product')  setStep('branch');
    else if (step === 'branch')   setStep('brand');
    else onBack();
  };

  const stepNum = step === 'brand' ? 1 : step === 'branch' ? 2 : step === 'product' ? 3 : 4;

  return (
    <div className="px-5 pb-28" style={SAFE_TOP}>
      <FormHeader
        onBack={goBack}
        icon={Fuel}
        title="Station-service"
        color="#2563EB"
        step={stepNum}
        totalSteps={4}
      />

      {step === 'brand' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quelle station ?</h2>
          {brands.map((b) => (
            <button
              key={b.id}
              onClick={() => { setSelectedBrand(b); setStep('branch'); }}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div
                className="w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0"
                style={{ background: b.color || '#2563EB' }}
              >
                <Fuel size={18} strokeWidth={2.2} className="text-white" />
              </div>
              <div className="flex-1 font-bold text-sm text-ink">{b.name}</div>
              <ChevronRight size={18} className="text-slate" />
            </button>
          ))}
        </div>
      )}

      {step === 'branch' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quelle station {selectedBrand.name} ?</h2>
          <button
            onClick={() => { setSelectedBranch(null); setSelectedProduct(null); setPrice(''); setAvailable(true); setStep('product'); }}
            className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
            style={{ border: '1px dashed #DDE3EC' }}
          >
            <div className="flex-1 text-sm text-slate italic">Pas précis</div>
            <ChevronRight size={18} className="text-slate" />
          </button>
          {branches.map((br) => (
            <button
              key={br.id}
              onClick={() => { setSelectedBranch(br); setSelectedProduct(null); setPrice(''); setAvailable(true); setStep('product'); }}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div className="w-2 h-2 rounded-full flex-shrink-0" style={{ background: br.verified ? '#16A34A' : '#9AA5B5' }} />
              <div className="flex-1 min-w-0">
                <div className="font-bold text-sm text-ink truncate">{br.name}</div>
                {br.neighborhood_name && (
                  <div className="text-[11px] text-slate flex items-center gap-1 mt-0.5">
                    <MapPin size={10} /> {br.neighborhood_name}
                  </div>
                )}
              </div>
              <ChevronRight size={18} className="text-slate" />
            </button>
          ))}
          {!showCreateBranch ? (
            <button
              onClick={() => setShowCreateBranch(true)}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left mt-2"
              style={{ border: '1px solid #2563EB' }}
            >
              <Plus size={18} strokeWidth={2.4} style={{ color: '#2563EB' }} />
              <span className="font-bold text-sm" style={{ color: '#2563EB' }}>Ajouter une station</span>
            </button>
          ) : (
            <div className="bg-white rounded-xl p-4 space-y-2.5 mt-2" style={{ border: '1px solid #2563EB' }}>
              <input
                type="text"
                value={newBranchName}
                onChange={(e) => setNewBranchName(e.target.value)}
                placeholder={`Ex : ${selectedBrand.name} Yoff`}
                className="w-full px-3 py-2.5 rounded-lg text-sm outline-none"
                style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
                autoFocus
              />
              <div className="flex gap-2">
                <button
                  onClick={() => { setShowCreateBranch(false); setNewBranchName(''); }}
                  className="flex-1 px-3 py-2.5 rounded-lg text-sm font-bold"
                  style={{ background: '#F1F4F9', color: '#5B6B7E' }}
                >
                  Annuler
                </button>
                <button
                  onClick={createBranchInline}
                  disabled={!newBranchName.trim()}
                  className="flex-1 px-3 py-2.5 rounded-lg text-sm font-bold text-white"
                  style={{ background: '#2563EB', opacity: newBranchName.trim() ? 1 : 0.4 }}
                >
                  Créer
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      {step === 'product' && (
        <div className="space-y-2">
          <h2 className="font-bold text-sm text-ink mb-1">Quel produit ?</h2>

          {/* V9.2.5 — Bouton catalogue ouvert (Station) */}
          <button
            onClick={() => { setNewProductName(''); setStep('newProduct'); }}
            className="w-full flex items-center justify-center gap-2 py-3 rounded-xl text-sm font-bold mb-2"
            style={{ background: '#FFF4ED', border: '1.5px dashed #F4632B', color: '#F4632B' }}
          >
            <Plus size={18} strokeWidth={2.5} />
            Mon produit n'est pas dans la liste
          </button>

          {stationProducts.map((p) => (
            <button
              key={p.product_id}
              onClick={() => { setSelectedProduct(p); setStep('price'); }}
              className="w-full bg-white rounded-xl p-3 flex items-center gap-3 text-left active:opacity-70"
              style={{ border: '1px solid #EAEEF4' }}
            >
              <div className="w-10 h-10 rounded-lg flex items-center justify-center text-xl flex-shrink-0" style={{ background: '#F1F4F9' }}>
                {p.icon}
              </div>
              <div className="flex-1 min-w-0">
                <div className="font-bold text-sm text-ink truncate">{p.product_name}</div>
                <div className="text-[11px] text-slate">CRSE {p.price} F · {p.unit}</div>
              </div>
              <ChevronRight size={18} className="text-slate" />
            </button>
          ))}
        </div>
      )}

      {/* V9.2.5 — Step newProduct : saisie produit non listé (Station, catégorie forcée 'energie') */}
      {step === 'newProduct' && (
        <div className="space-y-3">
          <h2 className="font-bold text-sm text-ink mb-1">Nouveau produit chez {selectedBrand?.name || 'la station'}</h2>
          <p className="text-xs text-slate mb-2">Carburant, gaz, additif… Décris-le, on l'ajoute après vérification.</p>

          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Nom du produit *</label>
            <input
              type="text"
              value={newProductName}
              onChange={(e) => setNewProductName(e.target.value)}
              placeholder="Ex: Gasoil pirogue 5L"
              maxLength={200}
              className="w-full mt-2 px-4 py-3 rounded-xl text-sm outline-none"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              autoFocus
            />
          </div>

          <button
            onClick={() => {
              const name = newProductName.trim();
              if (name.length < 2) { flash.show('error', 'Donne un nom au produit'); return; }
              setPendingNewProduct({ name, category_slug: 'energie' });
              setStep('price');
            }}
            disabled={!newProductName.trim()}
            className="w-full py-3.5 rounded-xl text-sm font-bold mt-2"
            style={{
              background: newProductName.trim() ? '#F4632B' : '#E5EAF0',
              color: newProductName.trim() ? 'white' : '#94A3B8',
            }}
          >
            Continuer →
          </button>
        </div>
      )}

      {step === 'price' && (selectedProduct || pendingNewProduct) && (
        <div className="space-y-3">
          <h2 className="font-bold text-sm text-ink mb-1">
            Prix observé pour {pendingNewProduct ? pendingNewProduct.name : selectedProduct.product_name}
          </h2>
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Prix à la pompe (FCFA)</label>
            <input
              type="number"
              inputMode="numeric"
              value={price}
              onChange={(e) => setPrice(e.target.value)}
              placeholder={selectedProduct?.price ? `CRSE : ${selectedProduct.price} F` : 'Ex: 800'}
              className="w-full mt-2 px-4 py-3 rounded-xl text-lg font-bold outline-none"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              autoFocus
            />
          </div>

          {crseCheck && crseCheck.has_crse && (
            <div
              className="rounded-2xl p-3 flex items-start gap-2.5"
              style={{
                background: crseCheck.compliance === 'above' ? '#FEF3F2' :
                            crseCheck.compliance === 'below' ? '#EFF6FF' : '#ECFDF5',
                border: '1px solid ' + (
                  crseCheck.compliance === 'above' ? '#FECACA' :
                  crseCheck.compliance === 'below' ? '#BFDBFE' : '#A7F3D0'
                ),
              }}
            >
              {crseCheck.compliance === 'above' ? (
                <AlertTriangle size={18} style={{ color: '#B91C1C' }} className="flex-shrink-0 mt-0.5" />
              ) : crseCheck.compliance === 'below' ? (
                <Check size={18} style={{ color: '#1E40AF' }} className="flex-shrink-0 mt-0.5" />
              ) : (
                <Check size={18} style={{ color: '#15803D' }} className="flex-shrink-0 mt-0.5" />
              )}
              <div className="flex-1 text-xs">
                <div className="font-bold leading-tight" style={{
                  color: crseCheck.compliance === 'above' ? '#B91C1C' :
                         crseCheck.compliance === 'below' ? '#1E40AF' : '#15803D',
                }}>
                  {crseCheck.message}
                </div>
              </div>
            </div>
          )}

          {/* V10.7.0 — Bloc Localisation : quartier + GPS pour la station */}
          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Quartier</label>
            <div className="mt-2 flex gap-2">
              <input
                type="text"
                value={neighborhood}
                onChange={(e) => setNeighborhood(e.target.value)}
                placeholder="Ex: Almadies, Plateau, Mermoz…"
                className="flex-1 px-4 py-3 rounded-xl outline-none text-sm"
                style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
              />
              <button
                type="button"
                onClick={askGps}
                disabled={gettingGps}
                className="px-3 py-3 rounded-xl flex items-center gap-1.5 text-sm font-bold flex-shrink-0"
                style={{
                  background: state.user?.geolocation ? '#E8F5E9' : '#FEEEE3',
                  color: state.user?.geolocation ? '#15803D' : '#F4632B',
                  opacity: gettingGps ? 0.6 : 1,
                }}
              >
                {Navigation && <Navigation size={16} strokeWidth={2.4} />}
                {gettingGps ? '…' : (state.user?.geolocation ? 'OK' : 'GPS')}
              </button>
            </div>
            <p className="text-[10px] text-slate mt-2 leading-snug">
              {state.user?.geolocation
                ? '✓ Position partagée'
                : '💡 Active le GPS pour la carte'}
            </p>
          </div>

          <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
            <label className="text-[11px] font-bold uppercase tracking-wider text-slate">État</label>
            <div className="mt-1.5 flex rounded-xl overflow-hidden" style={{ border: '1px solid #DDE3EC' }}>
              <button
                type="button"
                onClick={() => setAvailable(true)}
                className="flex-1 py-3 text-xs font-bold flex items-center justify-center gap-1"
                style={{
                  background: available ? '#E8F5E9' : 'white',
                  color: available ? '#15803D' : '#6B7891',
                }}
              >
                ✓ Dispo
              </button>
              <button
                type="button"
                onClick={() => setAvailable(false)}
                className="flex-1 py-3 text-xs font-bold"
                style={{
                  background: !available ? '#FEEEE3' : 'white',
                  color: !available ? '#F4632B' : '#6B7891',
                }}
              >
                × Rupture
              </button>
            </div>
          </div>

          <button
            onClick={submitObservation}
            disabled={submitting || !price}
            className="w-full px-5 py-4 rounded-2xl font-bold text-white shadow-md"
            style={{
              background: price && !submitting
                ? (crseCheck?.compliance === 'above' ? '#B91C1C' : '#102A43')
                : '#DDE3EC',
            }}
          >
            {submitting ? 'Envoi…' : 'Confirmer le prix'}
          </button>
        </div>
      )}
      {/* Sprint 3 - GPS pressant */}
      {window.OveyoSheets?.GpsPrompt && (
        <window.OveyoSheets.GpsPrompt
          open={showGpsPrompt}
          onClose={() => setShowGpsPrompt(false)}
          onActivated={(coords) => {
            setState((s) => ({ ...s, user: { ...s.user, geolocation: { ...coords, ts: Date.now() } } }));
            setShowGpsPrompt(false);
            setGpsPromptDone(true);
            setTimeout(() => submitObservation(), 100);
          }}
          onContinueWithoutGps={() => {
            setShowGpsPrompt(false);
            setGpsPromptDone(true);
            setTimeout(() => submitObservation(), 100);
          }}
        />
      )}
    </div>
  );
};


// ============================================================
// PHARMACIE — formulaire simple, design cohérent
// ============================================================
const PharmacieForm = ({ state, setState, setActiveTab, onLoginRequired, onBack, category }) => {
  const { Pill } = window.LucideReact || {};
  const flash = window.OveyoUI?.useFlash ? window.OveyoUI.useFlash() : { show: () => {} };

  const [pharmacyName, setPharmacyName] = React.useState('');
  const [medName, setMedName] = React.useState('');
  const [price, setPrice] = React.useState('');
  const [available, setAvailable] = React.useState(true);
  const [submitting, setSubmitting] = React.useState(false);
  // V8.6.1.2-PHARMACY-NEIGHBORHOOD : champ Quartier (texte libre)
  const [neighborhoodInput, setNeighborhoodInput] = React.useState(state?.user?.neighborhood_slug || '');
  // V10.7.0 — GPS button state
  const [gettingGpsPharma, setGettingGpsPharma] = React.useState(false);

  const askGpsPharma = () => {
    if (!navigator.geolocation) {
      flash.show('error', 'Géolocalisation non supportée');
      return;
    }
    setGettingGpsPharma(true);
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setState((s) => ({
          ...s,
          user: {
            ...s.user,
            geolocation: { lat: pos.coords.latitude, lng: pos.coords.longitude, ts: Date.now() },
          },
        }));
        setGettingGpsPharma(false);
        flash.show('success', 'Position OK');
      },
      (err) => {
        setGettingGpsPharma(false);
        const msg = err.code === 1 ? 'Autorise la géolocalisation dans Réglages'
          : err.code === 2 ? 'Position indisponible'
          : 'Erreur de géolocalisation';
        flash.show('error', msg);
      },
      { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
    );
  };

  const isLoggedIn = !!state.user?.session_token;

  const submit = async () => {
    if (!isLoggedIn) { onLoginRequired?.(); return; }
    if (!pharmacyName.trim() || !medName.trim() || !parseInt(price, 10)) {
      flash.show('error', 'Remplis tous les champs');
      return;
    }
    setSubmitting(true);
    try {
      const userGeo = state.user?.geolocation || null;
      // V8.6.1.2-PHARMACY-NEIGHBORHOOD : quartier saisi prioritaire sur profil
      const ngName = neighborhoodInput && neighborhoodInput.trim()
        ? neighborhoodInput.trim()
        : (state.user?.neighborhood_slug || null);
      const payload = {
        product_id: 118, // Sprint 2 - produit 'Medicament' generique (slug: medicament-generique). Le vrai nom du medicament est dans pharmacy_drug.
        price: parseInt(price, 10),
        available: available ? 1 : 0,
        is_abuse: 0,
        shop_name: `${pharmacyName.trim()} — ${medName.trim()}`,
        reported_by: state.user.phone || 'pwa-anonymous',
        neighborhood_name: ngName,
        category_slug: 'pharmacie',
        shop_lat: userGeo?.lat || null,
        shop_lng: userGeo?.lng || null,
        pharmacy_drug: medName.trim(),
      };
      const r = await fetch('/api/pwa/observation', {
        method: 'POST',
        // V8.6.2-FETCH-AUTH V8.6.2 : ajoute Bearer token (backend exige session)
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + (state?.user?.session_token || ''),
        },
        body: JSON.stringify(payload),
      });
      if (r.ok) {
        flash.show('success', 'Prix médicament enregistré');
        setActiveTab?.('home');
      } else {
        // V8.6.1.2-ERR-DETAIL-PHA : lire detail backend pour message clair
        let msg = "Erreur lors de l'envoi";
        try {
          const errBody = await r.json();
          if (typeof errBody?.detail === 'string') msg = errBody.detail;
          else if (Array.isArray(errBody?.detail) && errBody.detail[0]?.msg) {
            const f = errBody.detail[0];
            const field = Array.isArray(f.loc) ? f.loc[f.loc.length - 1] : '';
            msg = field ? `${field}: ${f.msg}` : f.msg;
          }
        } catch {}
        flash.show('error', msg);
      }
    } catch (e) { flash.show('error', 'Erreur réseau'); }
    finally { setSubmitting(false); }
  };

  return (
    <div className="px-5 pb-28" style={SAFE_TOP}>
      <FormHeader
        onBack={onBack}
        icon={Pill}
        title="Pharmacie"
        color="#15803D"
      />

      <p className="text-xs text-slate mb-4 -mt-1">Partage un prix de médicament</p>

      <div className="space-y-3">
        <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
          <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Pharmacie</label>
          <input
            type="text"
            value={pharmacyName}
            onChange={(e) => setPharmacyName(e.target.value)}
            placeholder="Ex : Pharmacie Eden"
            className="w-full mt-2 px-3 py-2.5 rounded-lg text-sm outline-none"
            style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
          />
        </div>
        <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
          <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Quartier</label>
          <div className="mt-2 flex gap-2">
            <input
              type="text"
              value={neighborhoodInput}
              onChange={(e) => setNeighborhoodInput(e.target.value)}
              placeholder="Ex : Mermoz, Yoff, Saly..."
              className="flex-1 px-3 py-2.5 rounded-lg text-sm outline-none"
              style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
            />
            {/* V10.7.0 — Bouton GPS */}
            <button
              type="button"
              onClick={askGpsPharma}
              disabled={gettingGpsPharma}
              className="px-3 rounded-lg flex items-center gap-1 text-xs font-bold flex-shrink-0"
              style={{
                background: state.user?.geolocation ? '#E8F5E9' : '#FEEEE3',
                color: state.user?.geolocation ? '#15803D' : '#F4632B',
                opacity: gettingGpsPharma ? 0.6 : 1,
              }}
            >
              {window.LucideReact?.Navigation && <window.LucideReact.Navigation size={14} strokeWidth={2.4} />}
              {gettingGpsPharma ? '…' : (state.user?.geolocation ? 'OK' : 'GPS')}
            </button>
          </div>
        </div>
        <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
          <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Nom du médicament</label>
          <input
            type="text"
            value={medName}
            onChange={(e) => setMedName(e.target.value)}
            placeholder="Ex : Doliprane 500mg"
            className="w-full mt-2 px-3 py-2.5 rounded-lg text-sm outline-none"
            style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
          />
        </div>
        <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
          <label className="text-[11px] font-bold text-slate uppercase tracking-wider">Prix (FCFA)</label>
          <input
            type="number"
            inputMode="numeric"
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            placeholder="Ex : 1500"
            className="w-full mt-2 px-3 py-2.5 rounded-lg text-sm font-bold outline-none"
            style={{ background: '#F1F4F9', border: '1px solid #EAEEF4' }}
          />
        </div>
        <div className="bg-white rounded-2xl p-4" style={{ border: '1px solid #EAEEF4' }}>
          <label className="text-[11px] font-bold uppercase tracking-wider text-slate">État</label>
          <div className="mt-1.5 flex rounded-xl overflow-hidden" style={{ border: '1px solid #DDE3EC' }}>
            <button
              type="button"
              onClick={() => setAvailable(true)}
              className="flex-1 py-3 text-xs font-bold flex items-center justify-center gap-1"
              style={{
                background: available ? '#E8F5E9' : 'white',
                color: available ? '#15803D' : '#6B7891',
              }}
            >
              ✓ Dispo
            </button>
            <button
              type="button"
              onClick={() => setAvailable(false)}
              className="flex-1 py-3 text-xs font-bold"
              style={{
                background: !available ? '#FEEEE3' : 'white',
                color: !available ? '#F4632B' : '#6B7891',
              }}
            >
              × Rupture
            </button>
          </div>
        </div>
        <button
          onClick={submit}
          disabled={submitting}
          className="w-full px-5 py-4 rounded-2xl font-bold text-white shadow-md"
          style={{ background: submitting ? '#DDE3EC' : '#102A43' }}
        >
          {submitting ? 'Envoi…' : 'Valider le prix'}
        </button>
      </div>
    </div>
  );
};


// Export
window.SharePicker    = SharePicker;
window.QuartierForm   = QuartierForm;
window.EnseigneForm   = EnseigneForm;
window.StationForm    = StationForm;
window.PharmacieForm  = PharmacieForm;
