// -----------------------------------------------------------------------------
// Food-Ka — Agrégateur de produits d'épicerie (province de Québec)
// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
// pages/Product.tsx : fiche produit — galerie packshot, bloc prix (solde,
//   prix unitaire), description, étiquettes, historique de prix et
//   « Comparer les prix » (même produit chez les autres bannières).
//   Mobile-first : galerie → prix → comparaison ; CTA source sticky en bas.
// -----------------------------------------------------------------------------
import { useEffect, useRef, useState } from "react";
import { Link, useParams } from "react-router-dom";
import {
  Product, ProductDetail,
  discountPct, fetchProduct, fetchSources, fmtPrice, fmtTs,
  registerSourceNames, sourceName,
} from "../api";
import SourceLogo from "../components/SourceLogo";

const NBSP = " ";

// --- Galerie avec balayage natif (scroll-snap) + compteur + plein écran -----
function Galerie({ images, titre }: { images: string[]; titre: string }) {
  const [idx, setIdx] = useState(0);
  const [zoom, setZoom] = useState(false);
  const track = useRef<HTMLDivElement>(null);

  const onScroll = () => {
    const el = track.current;
    if (el) setIdx(Math.round(el.scrollLeft / el.clientWidth));
  };
  const goto = (i: number) =>
    track.current?.scrollTo({ left: i * track.current.clientWidth, behavior: "smooth" });

  if (images.length === 0)
    return <div className="carousel"><div className="noimg carousel-empty">🛒</div></div>;

  return (
    <>
      <div className="carousel packshot">
        <div className="carousel-track" ref={track} onScroll={onScroll}>
          {images.map((u, i) => (
            <img
              key={u} src={u} loading={i === 0 ? "eager" : "lazy"}
              alt={`${titre} — image ${i + 1} de ${images.length}`}
              onClick={() => setZoom(true)}
            />
          ))}
        </div>
        {images.length > 1 && (
          <span className="carousel-count" aria-live="polite">{idx + 1}/{images.length}</span>
        )}
        {idx > 0 && (
          <button className="carousel-nav prev" aria-label="Image précédente" onClick={() => goto(idx - 1)}>‹</button>
        )}
        {idx < images.length - 1 && (
          <button className="carousel-nav next" aria-label="Image suivante" onClick={() => goto(idx + 1)}>›</button>
        )}
      </div>
      {images.length > 1 && (
        <div className="thumbs">
          {images.map((u, i) => (
            <button key={u} className={i === idx ? "on" : ""} onClick={() => goto(i)}
                    aria-label={`Image ${i + 1}`}>
              <img src={u} alt="" loading="lazy" />
            </button>
          ))}
        </div>
      )}
      {zoom && (
        <div className="lightbox" onClick={() => setZoom(false)} role="dialog" aria-label="Image agrandie">
          <img src={images[idx]} alt="" />
        </div>
      )}
    </>
  );
}

// --- Rangée de comparaison inter-bannières -----------------------------------
function CompareRow({ p, best }: { p: Product; best: boolean }) {
  const pct = discountPct(p);
  const img = p.images && p.images.length > 0 ? p.images[0] : null;
  return (
    <li className={best ? "best" : ""}>
      <Link to={`/produit/${encodeURIComponent(p.uid)}`} className="cmp-link">
        <span className="cmp-img packshot">
          {img ? <img src={img} alt="" loading="lazy" /> : <span className="noimg">🛒</span>}
        </span>
        <span className="cmp-main">
          <span className="cmp-name">{p.name}</span>
          <span className="cmp-meta">
            {[p.brand, p.size_label].filter(Boolean).join(" · ")}
          </span>
          <SourceLogo source={p.source} size={18} name="short" />
        </span>
        <span className="cmp-price">
          <b>{fmtPrice(p.price, p.price_label)}</b>
          {p.on_sale && p.regular_price != null && (
            <s className="price-old">{fmtPrice(p.regular_price)}</s>
          )}
          {pct != null && <em className="baisse-pct">−{pct} %</em>}
          {best && <span className="cmp-best">meilleur prix</span>}
          {p.unit_price_label && <span className="cmp-unit">{p.unit_price_label}</span>}
        </span>
      </Link>
    </li>
  );
}

export default function ProductPage() {
  const { uid } = useParams<{ uid: string }>();
  const [p, setP] = useState<ProductDetail | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetchSources().then((r) => registerSourceNames(r.sources)).catch(() => {});
    if (!uid) return;
    setP(null);
    setError(null);
    fetchProduct(uid).then(setP).catch((e) => setError(String(e)));
    window.scrollTo(0, 0);
  }, [uid]);

  if (error)
    return (
      <div className="notice container">
        <div className="big">⚠️</div>
        <h2>Produit introuvable</h2>
        <p>{error}</p>
        <Link className="btn btn-primary" to="/">Retour aux produits</Link>
      </div>
    );

  if (!p)
    return (
      <div className="container detail">
        <div className="fiche" aria-busy="true">
          <div className="skel"><div className="sk-img" /></div>
          <div className="skel"><div className="sk-line" /><div className="sk-line" /><div className="sk-line short" /></div>
        </div>
      </div>
    );

  const pct = discountPct(p);
  const updated = p.updated_at
    ? new Date(p.updated_at * 1000).toLocaleDateString("fr-CA", {
        day: "numeric", month: "long", year: "numeric" }) : null;

  // chips clés
  const chips: string[] = [];
  if (p.size_label) chips.push(p.size_label);
  if (p.category) chips.push(p.category);
  if (p.on_sale) chips.push(pct != null ? `Solde −${pct}${NBSP}%` : "En solde");
  if (p.in_stock === true) chips.push("En stock");
  if (p.in_stock === false) chips.push("Rupture de stock");

  // comparaison triée du moins cher au plus cher (prix inconnus à la fin)
  const compare = [...(p.compare ?? [])].sort((a, b) => {
    if (a.price == null) return 1;
    if (b.price == null) return -1;
    return a.price - b.price;
  });
  const bestPrice = compare.find((c) => c.price != null)?.price ?? null;

  const hist = (p.price_history ?? []).filter((h) => h.price != null);
  const baissePrix = hist.length >= 2 && hist[0].price !== hist[1].price
    ? { de: hist[1].price!, a: hist[0].price! } : null;

  return (
    <div className="container detail">
      <nav className="crumbs" aria-label="Fil d'Ariane">
        <Link to="/">Produits</Link> ›
        {p.category && (
          <Link to={`/?category=${encodeURIComponent(p.category)}`}>{p.category}</Link>
        )} ›
        <span>{p.name}</span>
      </nav>

      <div className="fiche">
        {/* ------- colonne gauche (desktop) : galerie, description, pratique -- */}
        <div className="f-col">
          <section className="f-bloc f-galerie" aria-label="Images du produit">
            <Galerie images={p.images ?? []} titre={p.name} />
          </section>

          <section className="f-bloc f-desc" id="description">
            <h2>Description</h2>
            {p.description
              ? <p style={{ color: "var(--ink-2)" }}>{p.description}</p>
              : <p className="fine">La bannière ne fournit pas de description pour ce produit.</p>}
            {p.keywords.length > 0 && (
              <div className="amenity-row" style={{ marginTop: 12 }}>
                {p.keywords.map((k) => (
                  <span className="amenity confirmed" key={k}>{k}</span>
                ))}
              </div>
            )}
          </section>

          <section className="f-bloc f-pratique">
            <h2>Détails pratiques</h2>
            <div className="kv">
              <div className="cell"><div className="k">Bannière</div><div className="v">{sourceName(p.source)}</div></div>
              {p.brand && (
                <div className="cell"><div className="k">Marque</div><div className="v">{p.brand}</div></div>
              )}
              {p.size_label && (
                <div className="cell"><div className="k">Format</div><div className="v">{p.size_label}</div></div>
              )}
              {p.category_raw && (
                <div className="cell"><div className="k">Rayon (source)</div><div className="v">{p.category_raw}</div></div>
              )}
              {p.price_label && (
                <div className="cell"><div className="k">Prix affiché</div><div className="v">{p.price_label}</div></div>
              )}
              {updated && (
                <div className="cell"><div className="k">Synchronisé</div><div className="v">{updated}</div></div>
              )}
            </div>
            {baissePrix && (
              <div className={`prix-histo ${baissePrix.a < baissePrix.de ? "down" : "up"}`}>
                {baissePrix.a < baissePrix.de ? "📉" : "📈"} Prix passé de{" "}
                {fmtPrice(baissePrix.de)} à <b>{fmtPrice(baissePrix.a)}</b>
              </div>
            )}
            {hist.length > 1 && (
              <details className="texte-original">
                <summary>Historique de prix ({hist.length} relevés)</summary>
                <ul className="histo-prix-liste">
                  {hist.map((h) => (
                    <li key={h.ts}>
                      <span className="hp-date">{fmtTs(h.ts)}</span>
                      <b className="hp-prix">{fmtPrice(h.price)}</b>
                    </li>
                  ))}
                </ul>
              </details>
            )}
          </section>
        </div>

        {/* ------- colonne droite (desktop) : prix, comparaison --------------- */}
        <div className="f-col">
          <section className="f-bloc f-hero">
            <div className="price">
              {fmtPrice(p.price, p.price_label)}
              {p.on_sale && p.regular_price != null && (
                <s className="price-old big">{fmtPrice(p.regular_price)}</s>
              )}
            </div>
            {p.on_sale && (
              <div className="deal-badge deal-good">
                🔥 En solde{pct != null && <> — épargnez {pct}{NBSP}%</>}
              </div>
            )}
            {p.unit_price_label && <div className="unit-price">{p.unit_price_label}</div>}
            <h1>{p.name}</h1>
            <div className="loc">
              {[p.brand, p.size_label].filter(Boolean).join(" · ")}
            </div>
            <div className="chips-scroll" role="list" aria-label="Caractéristiques clés">
              {chips.map((c) => <span className="chip-key" role="listitem" key={c}>{c}</span>)}
            </div>
            <a className="cta cta-desktop" href={p.url}
               target="_blank" rel="noopener noreferrer">
              <SourceLogo source={p.source} size={24} fallback="hide" />
              Voir chez {sourceName(p.source)} ↗
            </a>
            <p className="fine">
              Prix affiché par la bannière lors de la dernière synchronisation —
              vérifiez en magasin ou sur la fiche originale.
            </p>
          </section>

          <section className="f-bloc f-compare" id="comparer">
            <h2>Comparer les prix</h2>
            {compare.length > 0 ? (
              <>
                <p className="q-sub">
                  Produits similaires chez les autres bannières, du moins cher au plus cher.
                </p>
                <ul className="cmp-list">
                  {compare.map((c) => (
                    <CompareRow key={c.uid} p={c}
                                best={bestPrice != null && c.price === bestPrice} />
                  ))}
                </ul>
              </>
            ) : (
              <p className="fine">
                Aucun produit comparable trouvé chez les autres bannières pour l'instant.
              </p>
            )}
          </section>
        </div>
      </div>

      <div className="fine f-foot">
        {updated && <>Dernière synchronisation : {updated}. </>}
        Les prix et disponibilités sont ceux affichés par la source — chaque fiche
        renvoie à la page produit originale.
      </div>

      {/* CTA sticky mobile — toujours visible */}
      <div className="cta-sticky">
        <span className="cta-sticky-prix">
          {fmtPrice(p.price, p.price_label)}
          {p.unit_price_label && <small> {p.unit_price_label}</small>}
        </span>
        <a className="cta" href={p.url} target="_blank" rel="noopener noreferrer">
          <SourceLogo source={p.source} size={20} fallback="hide" />
          Voir chez {sourceName(p.source)} ↗
        </a>
      </div>
    </div>
  );
}
