/* BoatsFun — Offres du moment : composants partagés (homepage + page publique).
   Charge /api/offers (backend = seule autorité sur les prix et la durée) et rend
   les cartes promotionnelles : badge du motif, heures libres début–fin, durée,
   prix normal barré, % de rabais, prix promotionnel, économie, note publique.
   Aucun montant n'est calculé ici — tout vient de l'API.
   Bilingue : formats de date/prix/heure et libellés localisés via BFI18N ;
   le motif est traduit à partir du CODE `reason` de l'API (l'API reste en français).
   Styles : classes .odm-* dans shared/styles.css. */

(function () {
  const { I } = window.BF;
  const { t, localize, LANG } = window.BFI18N;
  const LOCALE = LANG === 'en' ? 'en-CA' : 'fr-CA';

  // Motifs d'offre : libellés anglais par CODE (la valeur API ne change jamais).
  const REASON_EN = {
    last_minute: 'Last minute',
    cancellation: 'Last-minute cancellation',
    temporary_promotion: 'Temporary promotion',
    available_slot: 'Discounted time slot'
  };
  function offerReasonLabel(offer) {
    if (LANG === 'en') return REASON_EN[offer.reason] || 'Current offer';
    return offer.reasonLabel || 'Offre du moment';
  }

  // "2026-07-25" → "vendredi 25 juillet" / "Friday, July 25" (année ajoutée si différente).
  function formatOfferDate(iso) {
    if (!iso) return "";
    try {
      const d = new Date(iso + "T12:00:00");
      const opts = { weekday: "long", day: "numeric", month: "long" };
      if (d.getFullYear() !== new Date().getFullYear()) opts.year = "numeric";
      return d.toLocaleDateString(LOCALE, opts);
    } catch (e) { return iso; }
  }

  // 100000 → "1 000 $" (fr) / "$1,000" (en), cents affichés si nécessaire.
  function money(cents) {
    const v = (Number(cents) || 0) / 100;
    const opts = v % 1 === 0 ? {} : { minimumFractionDigits: 2, maximumFractionDigits: 2 };
    if (LANG === 'en') return `$${v.toLocaleString("en-CA", opts)}`;
    return `${v.toLocaleString("fr-CA", opts)} $`;
  }

  // "13:00" → "13h" (fr) / "1 p.m." (en) ; "12:30" → "12h30" / "12:30 p.m.".
  function hourLabel(hhmm) {
    const m = /^(\d{1,2}):(\d{2})$/.exec(String(hhmm || ""));
    if (!m) return hhmm || "";
    const h = Number(m[1]);
    if (LANG === 'en') {
      const suffix = h >= 12 ? 'p.m.' : 'a.m.';
      const h12 = h % 12 === 0 ? 12 : h % 12;
      return m[2] === "00" ? `${h12} ${suffix}` : `${h12}:${m[2]} ${suffix}`;
    }
    return m[2] === "00" ? `${h}h` : `${h}h${m[2]}`;
  }

  // 300 → "5 h" ; 270 → "4 h 30" (identique dans les deux langues).
  function durationLabel(minutes) {
    const mn = Number(minutes) || 0;
    const h = Math.floor(mn / 60);
    const r = mn % 60;
    return r === 0 ? `${h} h` : `${h} h ${String(r).padStart(2, "0")}`;
  }

  // Expiration : libellé court, jamais de faux compte à rebours.
  function expiryLabel(offer) {
    const fallback = LANG === 'en' ? "Limited offer" : "Offre limitée";
    if (!offer.expiresAt) return fallback;
    const d = new Date(offer.expiresAt);
    if (Number.isNaN(d.getTime())) return fallback;
    const day = d.toLocaleDateString(LOCALE, { day: "numeric", month: "long" });
    const time = d.toLocaleTimeString(LOCALE, { hour: "numeric", minute: "2-digit" });
    return LANG === 'en' ? `Expires on ${day} at ${time}` : `Expire le ${day} à ${time}`;
  }

  // Récupère les offres publiques disponibles (période encore libre).
  function fetchOffers() {
    return fetch("/api/offers")
      .then((r) => r.json())
      .then((b) => (b && b.ok && Array.isArray(b.offers))
        ? b.offers.filter((o) => o.available !== false)
        : [])
      .catch(() => []);
  }

  function OfferCard({ offer }) {
    const timesSep = LANG === 'en' ? ' to ' : ' à ';
    const times = offer.startTime && offer.endTime
      ? `${hourLabel(offer.startTime)}${timesSep}${hourLabel(offer.endTime)}`
      : (offer.timeLabel || "");
    return (
      <a className="odm-card" href={localize(offer.bookingUrl)}>
        <div className="odm-media">
          {offer.image
            ? <img src={offer.image} alt={offer.boatName} loading="lazy" />
            : <div className="odm-media-fallback" aria-hidden="true"><I.fleet width="28" /></div>}
          <span className="odm-badge">{offerReasonLabel(offer)}</span>
          {offer.discountPercent > 0 && (
            <span className="odm-save">−{offer.discountPercent} %</span>
          )}
        </div>
        <div className="odm-body">
          <h3 className="odm-name">{offer.title || offer.boatName}</h3>
          {offer.title && <p className="odm-boat">{offer.boatName}</p>}
          <p className="odm-when">
            <I.cal width="13" /> {formatOfferDate(offer.date)} · {times} ({durationLabel(offer.durationMinutes)})
          </p>
          <div className="odm-prices">
            <span className="odm-price-old">{money(offer.originalPriceCents)}</span>
            <span className="odm-price-new">{money(offer.promotionalPriceCents)}</span>
          </div>
          <p className="odm-total">
            {LANG === 'en'
              ? <>Save <b>{money(offer.savingsCents)}</b> · Deposit {money(offer.depositCents)}</>
              : <>Économisez <b>{money(offer.savingsCents)}</b> · Dépôt {money(offer.depositCents)}</>}
          </p>
          {offer.publicNote && <p className="odm-note">{offer.publicNote}</p>}
          <p className="odm-expiry">{expiryLabel(offer)}</p>
          <span className="odm-cta">
            {LANG === 'en' ? 'Book this offer' : 'Réserver cette offre'} <I.arrowR width="14" />
          </span>
        </div>
      </a>
    );
  }

  function OffersGrid({ offers, max }) {
    const shown = max ? offers.slice(0, max) : offers;
    return (
      <div className="odm-grid">
        {shown.map((o) => <OfferCard key={o.id} offer={o} />)}
      </div>
    );
  }

  // Carte "offre en vedette" — grand format, affichée dans la zone d'état de la
  // homepage quand au moins une offre est active. 100 % données API (aucun calcul ici).
  function FeaturedOffer({ offer }) {
    const timesSep = LANG === 'en' ? ' to ' : ' à ';
    const times = offer.startTime && offer.endTime
      ? `${hourLabel(offer.startTime)}${timesSep}${hourLabel(offer.endTime)}`
      : (offer.timeLabel || "");
    return (
      <a className="odm2-feat" href={localize(offer.bookingUrl)}>
        <div className="odm2-feat-media">
          {offer.image
            ? <img src={offer.image} alt={offer.boatName} loading="lazy" />
            : <div className="odm2-feat-fallback" aria-hidden="true"><I.fleet width="34" /></div>}
          <span className="odm2-feat-badge">{offerReasonLabel(offer)}</span>
          {offer.discountPercent > 0 && (
            <span className="odm2-feat-pct" aria-label={LANG === 'en' ? `${offer.discountPercent}% discount` : `Rabais de ${offer.discountPercent} %`}>
              −{offer.discountPercent} %
            </span>
          )}
        </div>
        <div className="odm2-feat-body">
          <span className="odm2-feat-eyebrow">{LANG === 'en' ? 'Featured offer' : 'Offre en vedette'}</span>
          <h3 className="odm2-feat-name">{offer.title || offer.boatName}</h3>
          {offer.title && <p className="odm2-feat-boat">{offer.boatName}</p>}
          <p className="odm2-feat-when">
            <I.cal width="14" /> {formatOfferDate(offer.date)} · {times} ({durationLabel(offer.durationMinutes)})
          </p>
          <div className="odm2-feat-prices">
            <span className="odm2-feat-old">{money(offer.originalPriceCents)}</span>
            <span className="odm2-feat-new">{money(offer.promotionalPriceCents)}</span>
          </div>
          <p className="odm2-feat-save">
            {LANG === 'en'
              ? <>Save <b>{money(offer.savingsCents)}</b> · Deposit {money(offer.depositCents)}</>
              : <>Économisez <b>{money(offer.savingsCents)}</b> · Dépôt {money(offer.depositCents)}</>}
          </p>
          {offer.publicNote && <p className="odm2-feat-note">{offer.publicNote}</p>}
          <p className="odm2-feat-expiry">{expiryLabel(offer)}</p>
          <span className="odm2-feat-cta">
            {LANG === 'en' ? 'Book this offer' : 'Réserver cette offre'} <I.arrowR width="15" />
          </span>
        </div>
      </a>
    );
  }

  window.BFOffers = { fetchOffers, OfferCard, OffersGrid, FeaturedOffer, formatOfferDate, money, hourLabel, durationLabel, expiryLabel };
})();
