/* ============================================================
   AfricaMart — RFQ Board
   ============================================================ */
function RFQPage({ nav, showToast }) {
  const [posting, setPosting] = useState(false);
  const [cat, setCat] = useState("");
  const [rfqs, setRfqs] = useState(AM.RFQS);
  const [responding, setResponding] = useState(null);
  const list = rfqs.filter(r => !cat || r.cat === cat);

  useEffect(() => {
    if (!window.supabaseClient || !DB.rfq.getOpenRFQs) return;
    DB.rfq.getOpenRFQs(cat || null).then(setRfqs).catch(() => {});
  }, [cat]);

  return (
    <div className="route-anim">
      {/* header band */}
      <div style={{ background: "var(--navy-800)", color: "#fff" }}>
        <div className="wrap" style={{ padding: "40px 24px", display: "flex", gap: 24, alignItems: "center", justifyContent: "space-between", flexWrap: "wrap" }}>
          <div>
            <Breadcrumb trail={[["Home", () => nav("home")], ["RFQ Board"]]} />
            <h1 style={{ fontSize: 32, marginTop: 12, color: "#fff" }}>Request for Quotation board</h1>
            <p style={{ color: "var(--navy-200)", marginTop: 8, maxWidth: 540, lineHeight: 1.55 }}>Post what you need and let verified suppliers across Africa come to you with their best offers.</p>
          </div>
          <button className="btn btn-gold btn-lg" onClick={() => setPosting(true)}><Icon name="plus" size={18} /> Post an RFQ</button>
        </div>
      </div>

      <div className="wrap" style={{ padding: "28px 24px 64px" }}>
        {/* AI matching — live */}
        <div style={{ border: "1px solid var(--gold-300)", background: "var(--gold-50)", borderRadius: 12, padding: "14px 18px", display: "flex", alignItems: "center", gap: 12, marginBottom: 22, flexWrap: "wrap" }}>
          <span className="ai-chip"><Icon name="sparkles" size={13} /> AI RFQ Matching</span>
          <span style={{ fontSize: 14 }}>Post an RFQ and our AI instantly routes it to the <b>best-match suppliers</b> by category, location and track record.</span>
          <span className="badge badge-green" style={{ marginLeft: "auto" }}><Icon name="zap" size={11} /> Live</span>
        </div>

        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 18, flexWrap: "wrap" }}>
          <b style={{ fontSize: 16 }}>{list.length} open RFQs</b>
          <select className="select" value={cat} onChange={e => setCat(e.target.value)} style={{ width: "auto", marginLeft: "auto", fontWeight: 600 }}>
            <option value="">All categories</option>
            {AM.CATEGORIES.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
          </select>
        </div>

        {list.length === 0 && (
          <div className="card" style={{ padding: 32, textAlign: "center", color: "var(--ink-500)" }}>
            No open RFQs{cat ? " in this category" : ""} right now — check back soon, or post your own above.
          </div>
        )}

        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          {list.map(r => {
            const ct = AM.catById[r.cat];
            const co = AM.countryByCode[r.country];
            return (
              <div key={r.id} className="card rfq-card" style={{ padding: 22, display: "flex", gap: 20, alignItems: "flex-start" }}>
                <CatIcon cat={ct} size={24} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
                    <h3 style={{ fontSize: 17 }}>{r.title}</h3>
                    <span className="badge badge-green">Open</span>
                  </div>
                  <p className="muted" style={{ fontSize: 14, marginTop: 6, lineHeight: 1.55 }}>{r.desc}</p>
                  <div style={{ display: "flex", gap: 18, marginTop: 12, flexWrap: "wrap", fontSize: 13, color: "var(--ink-600)" }}>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Icon name="package" size={15} style={{ color: "var(--ink-400)" }} /> {r.qty}</span>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Flag code={r.country} size={13} /> {co.name}</span>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Icon name="building-2" size={15} style={{ color: "var(--ink-400)" }} /> {r.buyer}</span>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Icon name="calendar" size={15} style={{ color: "var(--ink-400)" }} /> Deadline {r.deadline}</span>
                  </div>
                </div>
                <div style={{ textAlign: "right", flexShrink: 0, display: "flex", flexDirection: "column", gap: 8, alignItems: "flex-end" }}>
                  <div className="muted" style={{ fontSize: 12 }}>{r.posted}</div>
                  <div style={{ fontWeight: 700, fontSize: 14 }}>{r.quotes} quotes</div>
                  <button className="btn btn-navy btn-sm" onClick={() => setResponding(r)}>Respond</button>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {posting && <RFQModal onClose={() => setPosting(false)} showToast={showToast} nav={nav} />}
      {responding && <QuoteModal rfq={responding} onClose={() => setResponding(null)} showToast={showToast} nav={nav} />}
    </div>
  );
}

function RFQModal({ onClose, showToast, nav, initial }) {
  const [f, setF] = useState({ product: "", category: "", quantity: "", destination: "", deadline: "", details: "", ...initial });
  const set = k => e => setF(prev => ({ ...prev, [k]: e.target.value }));
  const [match, setMatch] = useState({ status: "idle" });
  const [authUser, setAuthUser] = useState(null);
  const [session, setSession] = useState(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [turnstileToken, setTurnstileToken] = useState("");
  const turnstileRef = useRef(null);
  const widgetIdRef = useRef(null);

  useEffect(() => {
    if (!window.supabaseClient) return;
    DB.auth.getSession().then(s => { if (s?.user) { setAuthUser(s.user); setSession(s); } }).catch(() => {});
  }, []);

  // Render the Cloudflare Turnstile widget once its script has loaded
  // (same pattern as InquiryForm in store.page.jsx).
  useEffect(() => {
    let cancelled = false;
    let timer = null;
    const tryRender = () => {
      if (cancelled) return;
      if (!window.turnstile || !turnstileRef.current) {
        timer = setTimeout(tryRender, 200);
        return;
      }
      widgetIdRef.current = window.turnstile.render(turnstileRef.current, {
        sitekey: window.AM_CONFIG.TURNSTILE_SITE_KEY,
        callback: token => setTurnstileToken(token),
        "expired-callback": () => setTurnstileToken(""),
        "error-callback": () => setTurnstileToken(""),
      });
    };
    tryRender();
    return () => {
      cancelled = true;
      if (timer) clearTimeout(timer);
      if (window.turnstile && widgetIdRef.current != null) {
        window.turnstile.remove(widgetIdRef.current);
        widgetIdRef.current = null;
      }
    };
  }, []);

  const runMatch = async () => {
    if (!f.product && !f.category) { showToast("Add a product or category first"); return; }
    setMatch({ status: "loading" });
    try {
      const data = await AMAI.matchSuppliers(f);
      setMatch({ status: data.matches.length ? "done" : "empty", data });
    } catch (e) { setMatch({ status: "error" }); }
  };
  const canAI = window.AMAI && AMAI.available();

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError("");
    if (!window.supabaseClient || !DB.rfq) {
      onClose();
      showToast("RFQ posted — suppliers notified");
      return;
    }
    if (!authUser) {
      onClose();
      showToast("Please log in to post an RFQ");
      nav("auth", { mode: "login" });
      return;
    }
    if (!turnstileToken) {
      setError("Please complete the verification check below.");
      return;
    }
    setBusy(true);
    try {
      const buyer = await DB.auth.ensureBuyerRecord(authUser);
      const meta = authUser.user_metadata || {};
      const category = AM.CATEGORIES.find(c => c.name === f.category);
      const country = AM.COUNTRIES.find(c => c.name === f.destination);
      const rfqRow = await DB.rfq.submitRFQ({
        title: f.product,
        category_id: category ? category.id : null,
        quantity_text: f.quantity,
        destination_country: country ? country.code : null,
        buyer_id: buyer.id,
        buyer_name: meta.name || meta.full_name || authUser.email,
        deadline: f.deadline || null,
        description: f.details || null,
        turnstileToken,
      }, session.access_token);
      fetch("/api/notify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ event: "rfq_posted", rfqId: rfqRow?.id }),
      }).catch(() => {});
      onClose();
      showToast("RFQ posted — suppliers notified");
    } catch (err) {
      setError(err.message || "Could not post RFQ. Please try again.");
      if (window.turnstile && widgetIdRef.current != null) {
        window.turnstile.reset(widgetIdRef.current);
        setTurnstileToken("");
      }
    } finally {
      setBusy(false);
    }
  };

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 80, background: "rgba(13,27,42,.55)", backdropFilter: "blur(3px)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 }}>
      <form onClick={e => e.stopPropagation()} onSubmit={handleSubmit}
        className="route-anim thin-scroll" style={{ background: "#fff", borderRadius: 16, width: "min(560px,100%)", maxHeight: "90vh", overflow: "auto", boxShadow: "var(--sh-lg)" }}>
        <div style={{ padding: "20px 24px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "center", position: "sticky", top: 0, background: "#fff", zIndex: 1 }}>
          <h3 style={{ fontSize: 19 }}>Post a request for quotation</h3>
          <button type="button" onClick={onClose} style={{ marginLeft: "auto" }}><Icon name="x" size={22} style={{ color: "var(--ink-500)" }} /></button>
        </div>
        <div style={{ padding: 24, display: "flex", flexDirection: "column", gap: 16 }}>
          <div><label className="field-label">Product needed</label><input className="input" value={f.product} onChange={set("product")} placeholder="e.g. Deformed steel rebar Y16" required /></div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label className="field-label">Category</label><select className="select" value={f.category} onChange={set("category")} required><option value="" disabled>Select…</option>{AM.CATEGORIES.map(c => <option key={c.id} value={c.name}>{c.name}</option>)}</select></div>
            <div><label className="field-label">Quantity</label><input className="input" value={f.quantity} onChange={set("quantity")} placeholder="e.g. 80 MT" required /></div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label className="field-label">Destination country</label><select className="select" value={f.destination} onChange={set("destination")} required><option value="" disabled>Select…</option>{AM.COUNTRIES.map(c => <option key={c.code} value={c.name}>{c.name}</option>)}</select></div>
            <div><label className="field-label">Deadline</label><input className="input" type="date" value={f.deadline} onChange={set("deadline")} required /></div>
          </div>
          <div><label className="field-label">Details</label><textarea className="textarea" rows="3" value={f.details} onChange={set("details")} placeholder="Specs, standards, delivery terms…" /></div>

          {/* AI matching */}
          {canAI && (
            <div style={{ border: "1px solid var(--gold-300)", background: "var(--gold-50)", borderRadius: 12, padding: 16 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
                <span className="ai-chip"><Icon name="sparkles" size={12} /> AI</span>
                <span style={{ fontSize: 13.5, fontWeight: 600 }}>Preview your best-match suppliers</span>
                <button type="button" onClick={runMatch} disabled={match.status === "loading"} className="btn btn-navy btn-sm" style={{ marginLeft: "auto" }}>
                  <Icon name={match.status === "loading" ? "loader-circle" : "wand-sparkles"} size={14} className={match.status === "loading" ? "spin" : ""} /> {match.status === "loading" ? "Matching…" : "Find matches"}
                </button>
              </div>
              {match.status === "error" && <div className="muted" style={{ fontSize: 13, marginTop: 10, display: "flex", gap: 6, alignItems: "center" }}><Icon name="info" size={13} /> AI matching is unavailable right now.</div>}
              {match.status === "empty" && <div className="muted" style={{ fontSize: 13, marginTop: 10 }}>No strong supplier match yet — your RFQ will still reach the full network.</div>}
              {match.status === "done" && (
                <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 8 }}>
                  {match.data.note && <div style={{ fontSize: 13, color: "var(--ink-700)", lineHeight: 1.5 }}>{match.data.note}</div>}
                  {match.data.matches.map((m, i) => (
                    <div key={i} onClick={() => { onClose(); nav("store", { slug: m.rec.slug }); }} style={{ display: "flex", alignItems: "center", gap: 12, background: "#fff", border: "1px solid var(--border)", borderRadius: 10, padding: "10px 12px", cursor: "pointer" }}>
                      <span style={{ width: 40, flexShrink: 0, textAlign: "center", fontWeight: 800, fontSize: 13.5, color: "var(--gold-700)" }}>{m.score}<span style={{ fontSize: 9 }}>%</span></span>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontWeight: 700, fontSize: 13.5, display: "flex", alignItems: "center", gap: 6 }}><Flag code={m.rec.country} size={12} /> {m.rec.name}</div>
                        <div className="muted" style={{ fontSize: 12, marginTop: 2 }}>{m.reason}</div>
                      </div>
                      <Icon name="arrow-right" size={15} style={{ color: "var(--ink-400)", flexShrink: 0 }} />
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          <div ref={turnstileRef} />

          {error && <div style={{ padding: "8px 12px", borderRadius: 8, background: "var(--red-50)", color: "var(--red-600)", fontSize: 13 }}>{error}</div>}
        </div>
        <div style={{ padding: "16px 24px", borderTop: "1px solid var(--border)", display: "flex", gap: 12, justifyContent: "flex-end", position: "sticky", bottom: 0, background: "#fff" }}>
          <button type="button" className="btn btn-ghost" onClick={onClose}>Cancel</button>
          <button type="submit" className="btn btn-gold" disabled={busy}>
            {busy ? <Icon name="loader-circle" size={16} className="spin" /> : <Icon name="send" size={16} />} Post RFQ
          </button>
        </div>
      </form>
    </div>
  );
}

/* ---------- Supplier: respond to an RFQ with a quote ---------- */
function QuoteModal({ rfq, onClose, showToast, nav }) {
  const [f, setF] = useState({ price: "", leadTime: "", message: "" });
  const set = k => e => setF(prev => ({ ...prev, [k]: e.target.value }));
  const [authUser, setAuthUser] = useState(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    if (!window.supabaseClient) return;
    DB.auth.getSession().then(session => { if (session?.user) setAuthUser(session.user); }).catch(() => {});
  }, []);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError("");
    if (!window.supabaseClient || !DB.rfq) {
      onClose();
      showToast("Quote sent to buyer");
      return;
    }
    if (!authUser) {
      onClose();
      showToast("Please log in as a supplier to respond");
      nav("auth", { mode: "login" });
      return;
    }
    setBusy(true);
    try {
      const supplier = await DB.auth.ensureSupplierRecord(authUser);
      await DB.rfq.submitQuote(rfq.id, supplier.id, {
        priceUSD: f.price ? parseFloat(f.price) : null,
        leadTime: f.leadTime,
        message: f.message || null,
      });
      onClose();
      showToast("Quote sent to buyer");
    } catch (err) {
      setError(err.message || "Could not send quote. Please try again.");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 80, background: "rgba(13,27,42,.55)", backdropFilter: "blur(3px)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 }}>
      <form onClick={e => e.stopPropagation()} onSubmit={handleSubmit}
        className="route-anim thin-scroll" style={{ background: "#fff", borderRadius: 16, width: "min(480px,100%)", maxHeight: "90vh", overflow: "auto", boxShadow: "var(--sh-lg)" }}>
        <div style={{ padding: "20px 24px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "center", position: "sticky", top: 0, background: "#fff", zIndex: 1 }}>
          <div>
            <h3 style={{ fontSize: 19 }}>Respond with a quote</h3>
            <div className="muted" style={{ fontSize: 13, marginTop: 2 }}>{rfq.title}</div>
          </div>
          <button type="button" onClick={onClose} style={{ marginLeft: "auto" }}><Icon name="x" size={22} style={{ color: "var(--ink-500)" }} /></button>
        </div>
        <div style={{ padding: 24, display: "flex", flexDirection: "column", gap: 16 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label className="field-label">Your price (USD)</label><input className="input" type="number" min="0" step="0.01" value={f.price} onChange={set("price")} placeholder="e.g. 620" required /></div>
            <div><label className="field-label">Lead time</label><input className="input" value={f.leadTime} onChange={set("leadTime")} placeholder="e.g. 3-4 weeks" required /></div>
          </div>
          <div><label className="field-label">Message to buyer</label><textarea className="textarea" rows="4" value={f.message} onChange={set("message")} placeholder="Specs, terms, certifications, anything that strengthens your offer…" /></div>
          {error && <div style={{ padding: "8px 12px", borderRadius: 8, background: "var(--red-50)", color: "var(--red-600)", fontSize: 13 }}>{error}</div>}
        </div>
        <div style={{ padding: "16px 24px", borderTop: "1px solid var(--border)", display: "flex", gap: 12, justifyContent: "flex-end", position: "sticky", bottom: 0, background: "#fff" }}>
          <button type="button" className="btn btn-ghost" onClick={onClose}>Cancel</button>
          <button type="submit" className="btn btn-gold" disabled={busy}>
            {busy ? <Icon name="loader-circle" size={16} className="spin" /> : <Icon name="send" size={16} />} Send quote
          </button>
        </div>
      </form>
    </div>
  );
}

/* ---------- Buyer: view quotes received on an RFQ, accept/decline ---------- */
function QuotesModal({ rfq, onClose, showToast }) {
  const [quotes, setQuotes] = useState(null);
  const [rfqStatus, setRfqStatus] = useState(rfq.status);
  const [busyId, setBusyId] = useState(null);

  useEffect(() => {
    if (!window.supabaseClient || !DB.rfq || !DB.rfq.getQuotesForRFQ) { setQuotes([]); return; }
    DB.rfq.getQuotesForRFQ(rfq.id).then(setQuotes).catch(() => setQuotes([]));
  }, [rfq.id]);

  const accept = async (quoteId) => {
    setBusyId(quoteId);
    try {
      await DB.rfq.acceptQuote(rfq.id, quoteId);
      setQuotes(qs => qs.map(qt => qt.id === quoteId ? { ...qt, status: "accepted" } : (qt.status === "pending" ? { ...qt, status: "declined" } : qt)));
      setRfqStatus("awarded");
      showToast("Quote accepted — RFQ awarded");
    } catch (err) {
      showToast("Could not accept quote. Please try again.");
    } finally {
      setBusyId(null);
    }
  };

  const decline = async (quoteId) => {
    setBusyId(quoteId);
    try {
      await DB.rfq.declineQuote(quoteId);
      setQuotes(qs => qs.map(qt => qt.id === quoteId ? { ...qt, status: "declined" } : qt));
      showToast("Quote declined");
    } catch (err) {
      showToast("Could not decline quote. Please try again.");
    } finally {
      setBusyId(null);
    }
  };

  const statusBadge = { pending: "badge-blue", accepted: "badge-green", declined: "badge-gray" };

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 80, background: "rgba(13,27,42,.55)", backdropFilter: "blur(3px)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 }}>
      <div onClick={e => e.stopPropagation()}
        className="route-anim thin-scroll" style={{ background: "#fff", borderRadius: 16, width: "min(640px,100%)", maxHeight: "90vh", overflow: "auto", boxShadow: "var(--sh-lg)" }}>
        <div style={{ padding: "20px 24px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "center", position: "sticky", top: 0, background: "#fff", zIndex: 1 }}>
          <div>
            <h3 style={{ fontSize: 19 }}>Quotes received</h3>
            <div className="muted" style={{ fontSize: 13, marginTop: 2 }}>{rfq.title}</div>
          </div>
          <button type="button" onClick={onClose} style={{ marginLeft: "auto" }}><Icon name="x" size={22} style={{ color: "var(--ink-500)" }} /></button>
        </div>
        <div style={{ padding: 24, display: "flex", flexDirection: "column", gap: 14 }}>
          {quotes === null && <div className="muted" style={{ padding: "12px 0", textAlign: "center" }}><Icon name="loader-circle" size={18} className="spin" /></div>}
          {quotes !== null && quotes.length === 0 && (
            <div className="muted" style={{ padding: "24px 0", textAlign: "center" }}>No quotes yet — suppliers will respond here as they come in.</div>
          )}
          {quotes !== null && quotes.map(quote => (
            <div key={quote.id} className="card" style={{ padding: 16 }}>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 12, flexWrap: "wrap" }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 6, fontWeight: 700 }}>
                    {quote.supplier.name || "Supplier"}
                    {quote.supplier.verified && <Icon name="badge-check" size={14} style={{ color: "var(--gold-600)" }} />}
                  </div>
                  <div className="muted" style={{ fontSize: 12.5, display: "flex", alignItems: "center", gap: 6, marginTop: 2 }}>
                    {quote.supplier.country && <Flag code={quote.supplier.country} size={12} />}
                    {quote.supplier.rating != null && <><Stars value={quote.supplier.rating} size={11} /> {quote.supplier.rating}</>}
                    <span>· {quote.posted}</span>
                  </div>
                </div>
                <div style={{ textAlign: "right" }}>
                  <div style={{ fontSize: 20, fontWeight: 800, color: "var(--navy-800)" }}>{quote.priceUSD != null ? fmtPrice(quote.priceUSD, "USD") : "—"}</div>
                  <div className="muted" style={{ fontSize: 12.5 }}>{quote.leadTime || "—"}</div>
                </div>
              </div>
              {quote.message && <p style={{ fontSize: 13.5, lineHeight: 1.55, marginTop: 10, color: "var(--ink-700)" }}>{quote.message}</p>}
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 12 }}>
                <span className={"badge " + (statusBadge[quote.status] || "badge-gray")}>{quote.status.charAt(0).toUpperCase() + quote.status.slice(1)}</span>
                {quote.status === "pending" && rfqStatus === "open" && (
                  <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
                    <button className="btn btn-ghost btn-sm" disabled={busyId === quote.id} onClick={() => decline(quote.id)}>Decline</button>
                    <button className="btn btn-gold btn-sm" disabled={busyId === quote.id} onClick={() => accept(quote.id)}>
                      {busyId === quote.id ? <Icon name="loader-circle" size={14} className="spin" /> : <Icon name="check" size={14} />} Accept
                    </button>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { RFQPage, RFQModal, QuoteModal, QuotesModal });
