// Caffè Italia · avis produits
// ============================
// Un avis = une ligne dans `reviews`, rattachée à un compte ET à un achat.
// La règle « seuls les clients qui ont commandé peuvent noter » est tenue
// par la policy RLS `reviews_insert_buyer` (public.has_purchased) : le code
// ci-dessous ne fait que masquer le formulaire quand il sait déjà que
// l'insert serait refusé. La vérité reste côté base.
//
// Variantes : les SKU d'un même `variantGroup` (50 / 100 capsules) partagent
// leurs avis — on lit sur tous les ids du groupe, on écrit sur le SKU affiché.

const { useState: _rvUseState, useEffect: _rvUseEffect, useCallback: _rvUseCallback } = React;

const _rvL = (fr, it) => (window.__LANG__ === "it" ? it : fr);

// Une commande compte comme achat une fois payée — pas au moment du panier.
const PURCHASED_STATUSES = ["paid", "shipped", "delivered"];

// ─── Lecture ──────────────────────────────────────────────────────────────
window.fetchReviews = async function fetchReviews(productIds){
  if (!window.sb || !productIds || productIds.length === 0) return [];
  const { data, error } = await window.sb
    .from("reviews")
    .select("id, product_id, user_id, author_name, rating, body, created_at")
    .in("product_id", productIds)
    .order("created_at", { ascending: false });
  if (error) { console.warn("[reviews] read failed:", error.message); return []; }
  return data || [];
};

// A-t-on acheté l'un de ces SKU ? Deux requêtes simples plutôt qu'une
// jointure imbriquée : les policies RLS limitent déjà `orders` au client.
window.hasPurchasedAny = async function hasPurchasedAny(productIds){
  if (!window.sb || !productIds || productIds.length === 0) return false;
  const { data: sess } = await window.sb.auth.getSession();
  const uid = sess?.session?.user?.id;
  if (!uid) return false;
  const { data: orders, error: oErr } = await window.sb
    .from("orders").select("id").eq("user_id", uid).in("status", PURCHASED_STATUSES);
  if (oErr || !orders || orders.length === 0) return false;
  const { data: items, error: iErr } = await window.sb
    .from("order_items").select("product_id")
    .in("order_id", orders.map(o => o.id))
    .in("product_id", productIds)
    .limit(1);
  if (iErr) return false;
  return (items || []).length > 0;
};

// Hook partagé : la note moyenne sert aussi à l'en-tête de la fiche produit
// et au libellé de l'onglet, pas seulement à la liste.
function useReviews(productIds){
  const key = (productIds || []).join(",");
  const [state, setState] = _rvUseState({ key: null, rows: [], loading: true });

  const load = _rvUseCallback(async () => {
    const rows = await window.fetchReviews(productIds);
    setState({ key, rows, loading: false });
  }, [key]);

  _rvUseEffect(() => {
    let cancelled = false;
    setState(s => ({ key, rows: s.key === key ? s.rows : [], loading: true }));
    (async () => {
      const rows = await window.fetchReviews(key ? key.split(",") : []);
      if (!cancelled) setState({ key, rows, loading: false });
    })();
    return () => { cancelled = true; };
  }, [key]);

  const fresh = state.key === key;
  const rows  = fresh ? state.rows : [];
  const count = rows.length;
  const avg   = count ? rows.reduce((s, r) => s + r.rating, 0) / count : null;
  return { rows, count, avg, loading: !fresh || state.loading, reload: load };
}

// ─── Étoiles ──────────────────────────────────────────────────────────────
function Stars({ value, size = 14 }){
  const full = Math.round(value || 0);
  return (
    <span aria-label={`${(value || 0).toFixed(1)} / 5`} style={{color:"var(--rosso)",fontSize:size,letterSpacing:".08em",whiteSpace:"nowrap"}}>
      {"★".repeat(full)}<span style={{opacity:.28}}>{"★".repeat(Math.max(0, 5 - full))}</span>
    </span>
  );
}

function StarPicker({ value, onChange }){
  return (
    <div role="radiogroup" aria-label={_rvL("Note","Voto")} style={{display:"flex",gap:4}}>
      {[1,2,3,4,5].map(n => (
        <button key={n} type="button" role="radio" aria-checked={value===n}
          onClick={()=>onChange(n)} aria-label={`${n} / 5`}
          style={{fontSize:26,lineHeight:1,padding:"2px 2px",color:"var(--rosso)",opacity:n<=value?1:.25}}>★</button>
      ))}
    </div>
  );
}

// ─── Formulaire ───────────────────────────────────────────────────────────
function ReviewForm({ productId, session, existing, onSaved }){
  const [rating, setRating] = _rvUseState(existing ? existing.rating : 0);
  const [body,   setBody]   = _rvUseState(existing ? (existing.body || "") : "");
  const [name,   setName]   = _rvUseState(
    existing ? (existing.author_name || "") : (session?.user?.user_metadata?.full_name || ""));
  const [saving, setSaving] = _rvUseState(false);
  const [err,    setErr]    = _rvUseState(null);

  const submit = async (e) => {
    e.preventDefault();
    if (!rating) { setErr(_rvL("Choisissez une note.","Scegli un voto.")); return; }
    setErr(null); setSaving(true);
    const row = {
      product_id: productId,
      user_id:    session.user.id,
      author_name: (name || "").trim() || _rvL("Client","Cliente"),
      rating,
      body: (body || "").trim() || null,
      updated_at: new Date().toISOString(),
    };
    const { error } = await window.sb.from("reviews").upsert(row, { onConflict: "product_id,user_id" });
    setSaving(false);
    if (error) { setErr(error.message); return; }
    onSaved();
  };

  return (
    <form onSubmit={submit} style={{padding:22,background:"var(--paper-2)",borderRadius:4}}>
      <div className="eyebrow">{existing ? _rvL("Modifier mon avis","Modifica la mia recensione") : _rvL("Laisser un avis","Lascia una recensione")}</div>
      <div style={{marginTop:12}}><StarPicker value={rating} onChange={setRating}/></div>
      <label style={{display:"block",marginTop:14}}>
        <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
          {_rvL("Nom affiché","Nome visualizzato")}
        </span>
        <input type="text" value={name} onChange={(e)=>setName(e.target.value)} maxLength={60}
          placeholder={_rvL("Giulia, Paris 11e","Giulia, Napoli")}
          style={{width:"100%",padding:"12px 14px",fontSize:14,fontFamily:"inherit",background:"var(--paper)",color:"var(--ink)",border:"1px solid var(--hairline-strong)",borderRadius:6,outline:"none",boxSizing:"border-box"}}/>
      </label>
      <label style={{display:"block",marginTop:12}}>
        <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
          {_rvL("Votre avis","La tua recensione")}
        </span>
        <textarea value={body} onChange={(e)=>setBody(e.target.value)} rows={4} maxLength={1200}
          style={{width:"100%",padding:"12px 14px",fontSize:14,fontFamily:"inherit",background:"var(--paper)",color:"var(--ink)",border:"1px solid var(--hairline-strong)",borderRadius:6,outline:"none",boxSizing:"border-box",resize:"vertical"}}/>
      </label>
      {err && (
        <div style={{padding:"10px 12px",marginTop:12,background:"rgba(220,40,50,.12)",border:"1px solid var(--rosso)",borderRadius:6,color:"var(--rosso)",fontSize:13}}>{err}</div>
      )}
      <button type="submit" disabled={saving} className="btn btn-rosso" style={{marginTop:14,opacity:saving?.6:1}}>
        {saving ? _rvL("Envoi…","Invio…") : _rvL("Publier mon avis","Pubblica la recensione")}
      </button>
      <div style={{fontSize:11.5,color:"var(--muted)",marginTop:10}}>
        {_rvL("Le nom affiché est public. Un seul avis par produit et par compte.",
           "Il nome visualizzato è pubblico. Una sola recensione per prodotto e per account.")}
      </div>
    </form>
  );
}

// ─── Panneau complet (onglet « Avis » de la fiche produit) ────────────────
function ReviewsPanel({ productId, groupIds, reviews, navigate }){
  const session = useSession();               // undefined = en cours de chargement
  const [purchased, setPurchased] = _rvUseState(null);   // null = pas encore su

  _rvUseEffect(() => {
    let cancelled = false;
    if (session === undefined) return;
    if (!session) { setPurchased(false); return; }
    setPurchased(null);
    (async () => {
      const ok = await window.hasPurchasedAny(groupIds);
      if (!cancelled) setPurchased(ok);
    })();
    return () => { cancelled = true; };
  }, [session ? session.user.id : String(session), groupIds.join(",")]);

  const rows = reviews.rows;
  const mine = session ? rows.find(r => r.user_id === session.user.id) : null;

  const fmtDate = (iso) => {
    try { return new Date(iso).toLocaleDateString(window.__LANG__ === "it" ? "it-IT" : "fr-FR",
      { year:"numeric", month:"long", day:"numeric" }); }
    catch { return ""; }
  };

  return (
    <div style={{gridColumn:"1 / -1"}}>
      {/* Résumé */}
      <div style={{display:"flex",alignItems:"center",gap:16,flexWrap:"wrap",marginBottom:22}}>
        {reviews.count > 0 ? (
          <>
            <span className="display" style={{fontSize:40}}>{reviews.avg.toFixed(1).replace(".",",")}</span>
            <div>
              <Stars value={reviews.avg} size={16}/>
              <div style={{fontSize:13,color:"var(--muted)",marginTop:2}}>
                {reviews.count} {reviews.count > 1 ? _rvL("avis","recensioni") : _rvL("avis","recensione")}
              </div>
            </div>
          </>
        ) : (
          <div style={{fontSize:14.5,color:"var(--muted)"}}>
            {reviews.loading
              ? _rvL("Chargement des avis…","Caricamento delle recensioni…")
              : _rvL("Aucun avis pour l'instant. Soyez le premier à en laisser un.",
                  "Nessuna recensione per ora. Sii il primo a lasciarne una.")}
          </div>
        )}
      </div>

      {/* Écrire un avis · l'état dépend de la session ET de l'achat */}
      <div style={{marginBottom:26,maxWidth:680}}>
        {session === undefined || purchased === null ? (
          <div style={{fontSize:13.5,color:"var(--muted)"}}>{_rvL("Vérification…","Verifica…")}</div>
        ) : !session ? (
          <div style={{padding:"16px 18px",border:"1px dashed var(--hairline-strong)",borderRadius:4,display:"flex",alignItems:"center",justifyContent:"space-between",gap:14,flexWrap:"wrap"}}>
            <span style={{fontSize:14}}>
              {_rvL("Connectez-vous pour laisser un avis sur ce produit.",
                 "Accedi per lasciare una recensione su questo prodotto.")}
            </span>
            <button onClick={()=>navigate({page:"account"})} className="btn btn-ghost btn-sm">
              {_rvL("Se connecter","Accedi")}
            </button>
          </div>
        ) : purchased ? (
          <ReviewForm productId={productId} session={session} existing={mine} onSaved={reviews.reload}/>
        ) : (
          <div style={{padding:"16px 18px",border:"1px dashed var(--hairline-strong)",borderRadius:4,fontSize:14,color:"var(--muted)"}}>
            {_rvL("Seuls les clients ayant déjà commandé ce produit peuvent laisser un avis.",
               "Solo i clienti che hanno già ordinato questo prodotto possono lasciare una recensione.")}
          </div>
        )}
      </div>

      {/* Liste */}
      {rows.length > 0 && (
        <div style={{display:"grid",gridTemplateColumns:"repeat(2,1fr)",gap:14}} className="reviews-list">
          {rows.map(r => (
            <div key={r.id} style={{padding:22,background:"var(--paper-2)",borderRadius:4}}>
              <Stars value={r.rating}/>
              {r.body && <p className="serif" style={{fontSize:18,marginTop:8,lineHeight:1.35}}>« {r.body} »</p>}
              <div style={{fontSize:12,color:"var(--muted)",marginTop:8}}>
                · {r.author_name || _rvL("Client","Cliente")} · {fmtDate(r.created_at)}
                <span style={{marginLeft:8,color:"var(--rosso)",fontWeight:600}}>{_rvL("Achat vérifié","Acquisto verificato")}</span>
              </div>
            </div>
          ))}
          <style>{`@media (max-width:780px){.reviews-list{grid-template-columns:1fr !important}}`}</style>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { useReviews, Stars, StarPicker, ReviewForm, ReviewsPanel });
