/* global React, PageHeader, PhotoPH, toRoman, FadeUp */

const PER_PAGE = 8;

// Map photo filename to full-size path (drops "_small" suffix)
const fullPath = (photo) =>
  photo
    ? "assets/images/annonces/full/" +
      photo.replace(/_small\.(jpg|png)$/i, ".$1")
    : null;

function PageBoutique() {
  const [data, setData] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [filter, setFilter] = React.useState("Toutes");
  const [mode, setMode] = React.useState("Vente");
  const [search, setSearch] = React.useState("");
  const [sort, setSort] = React.useState("recent");
  const [page, setPage] = React.useState(1);
  const [selected, setSelected] = React.useState(null);

  React.useEffect(() => {
    fetch("data/annonces.json")
      .then((r) => r.json())
      .then(setData)
      .catch((e) => setError(e.message));
  }, []);

  // Reset page when filter/search/mode change
  React.useEffect(() => {
    setPage(1);
  }, [filter, mode, search, sort]);

  if (error)
    return (
      <div className="container-wide" style={{ padding: 64 }}>
        Erreur : {error}
      </div>
    );
  if (!data)
    return (
      <div className="container-wide" style={{ padding: 64 }}>
        <div className="tag-mono">— Chargement —</div>
      </div>
    );

  const annonces = data.annonces;
  const allCategories = [
    "Toutes",
    ...new Set(annonces.map((a) => a.categorie)),
  ].sort((a, b) => (a === "Toutes" ? -1 : 0));

  // Apply filters
  let filtered = annonces.filter((a) => {
    if (mode === "Vente" && a.type !== "vente") return false;
    if (mode === "Recherche / Achat" && a.type !== "achat") return false;
    if (filter !== "Toutes" && a.categorie !== filter) return false;
    if (search) {
      const q = search.toLowerCase();
      if (
        !a.titre.toLowerCase().includes(q) &&
        !a.description.toLowerCase().includes(q) &&
        !a.categorie.toLowerCase().includes(q)
      )
        return false;
    }
    return true;
  });

  // Sort
  const parseDate = (s) => {
    const [d, m, y] = s.split("/").map(Number);
    return new Date(y < 100 ? 2000 + y : y, m - 1, d).getTime();
  };
  filtered = [...filtered].sort((a, b) => {
    if (sort === "recent") return parseDate(b.date) - parseDate(a.date);
    if (sort === "asc") return (a.prix_chf || 99999) - (b.prix_chf || 99999);
    if (sort === "desc") return (b.prix_chf || 0) - (a.prix_chf || 0);
    return 0;
  });

  const totalPages = Math.max(1, Math.ceil(filtered.length / PER_PAGE));
  const pagedAnnonces = filtered.slice((page - 1) * PER_PAGE, page * PER_PAGE);

  const countByMode = {
    Vente: annonces.filter((a) => a.type === "vente").length,
    "Recherche / Achat": annonces.filter((a) => a.type === "achat").length,
  };

  return (
    <div className="container-wide">
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "flex-end",
          flexWrap: "wrap",
          gap: 24,
          padding: "64px 0 32px",
        }}
      >
        <div style={{ minWidth: 0, flex: "1 1 320px" }}>
          <div className="tag-gold" style={{ marginBottom: 18 }}>
            — Entre membres —
          </div>
          <h1
            style={{
              fontFamily: "var(--display)",
              fontWeight: 500,
              fontSize: "clamp(36px, 5vw, 64px)",
              lineHeight: 1.05,
              margin: 0,
              letterSpacing: "-0.015em",
            }}
          >
            Bourse <em style={{ color: "var(--accent-deep)" }}>EAN 2026</em>
          </h1>
          <div className="tag-mono" style={{ marginTop: 16 }}>
            {annonces.length} annonces actives · {countByMode["Vente"]} ventes /{" "}
            {countByMode["Recherche / Achat"]} achat · réservé aux membres
          </div>
        </div>
        <button className="btn btn-red" style={{ flexShrink: 0 }}>
          + Publier une annonce
        </button>
      </div>

      <hr className="hr-fine" />

      {/* category filters */}
      <div
        style={{
          display: "flex",
          gap: 8,
          flexWrap: "wrap",
          alignItems: "center",
          padding: "24px 0",
        }}
      >
        {allCategories.map((c) => {
          const cnt =
            c === "Toutes"
              ? annonces.length
              : annonces.filter((a) => a.categorie === c).length;
          return (
            <button
              key={c}
              className={"chip" + (filter === c ? " active" : "")}
              onClick={() => setFilter(c)}
            >
              {c} <span style={{ opacity: 0.5, marginLeft: 4 }}>· {cnt}</span>
            </button>
          );
        })}
      </div>

      {/* mode + search + sort */}
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          flexWrap: "wrap",
          gap: 16,
          marginBottom: 32,
          padding: "16px 0",
          borderTop: "1px solid var(--hairline)",
          borderBottom: "1px solid var(--hairline)",
        }}
      >
        <div
          style={{
            display: "flex",
            gap: 0,
            border: "1px solid var(--hairline-strong)",
          }}
        >
          {["Vente", "Recherche / Achat"].map((m) => (
            <button
              key={m}
              onClick={() => setMode(m)}
              style={{
                padding: "10px 20px",
                border: 0,
                background: mode === m ? "var(--ink)" : "transparent",
                color: mode === m ? "var(--paper)" : "var(--ink)",
                fontFamily: "var(--mono)",
                fontSize: 11,
                letterSpacing: "0.12em",
                textTransform: "uppercase",
                cursor: "pointer",
              }}
            >
              {m} <span style={{ opacity: 0.5 }}>· {countByMode[m]}</span>
            </button>
          ))}
        </div>
        <div
          style={{
            display: "flex",
            gap: 16,
            alignItems: "center",
            flexWrap: "wrap",
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 10,
              border: "1px solid var(--hairline-strong)",
              padding: "10px 14px",
              minWidth: 280,
            }}
          >
            <svg
              width="14"
              height="14"
              viewBox="0 0 24 24"
              fill="none"
              stroke="var(--gray)"
              strokeWidth="1.6"
            >
              <circle cx="11" cy="11" r="7" />
              <line x1="16.5" y1="16.5" x2="21" y2="21" />
            </svg>
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Rechercher (titre, description…)"
              style={{
                border: 0,
                background: "transparent",
                flex: 1,
                fontFamily: "var(--sans)",
                fontSize: 13,
                outline: "none",
              }}
            />
            {search && (
              <button
                onClick={() => setSearch("")}
                style={{
                  border: 0,
                  background: "transparent",
                  cursor: "pointer",
                  color: "var(--gray)",
                  padding: 0,
                }}
              >
                ✕
              </button>
            )}
          </div>
          <select
            value={sort}
            onChange={(e) => setSort(e.target.value)}
            style={{
              padding: "10px 14px",
              border: "1px solid var(--hairline-strong)",
              background: "transparent",
              fontFamily: "var(--mono)",
              fontSize: 11,
              letterSpacing: "0.08em",
            }}
          >
            <option value="recent">Plus récentes</option>
            <option value="asc">Prix croissant</option>
            <option value="desc">Prix décroissant</option>
          </select>
        </div>
      </div>

      {/* result count */}
      <div
        className="tag-mono"
        style={{ marginBottom: 16, color: "var(--gray)" }}
      >
        — {filtered.length} résultat{filtered.length !== 1 ? "s" : ""}{" "}
        {(filter !== "Toutes" || search) && (
          <span style={{ marginLeft: 12 }}>
            <a
              onClick={() => {
                setFilter("Toutes");
                setSearch("");
              }}
              style={{ color: "var(--accent-deep)", cursor: "pointer" }}
            >
              réinitialiser ✕
            </a>
          </span>
        )}
      </div>

      {/* grille */}
      {filtered.length === 0 ? (
        <div
          style={{
            padding: 80,
            textAlign: "center",
            background: "var(--paper-2)",
            border: "1px solid var(--hairline)",
          }}
        >
          <div className="tag-mono" style={{ marginBottom: 12 }}>
            — Aucun résultat
          </div>
          <p style={{ color: "var(--gray)", margin: 0 }}>
            Essayez d'élargir vos filtres ou de modifier votre recherche.
          </p>
        </div>
      ) : (
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "repeat(2, 1fr)",
            gap: 20,
          }}
          className="annonce-grid"
        >
          {pagedAnnonces.map((a, i) => (
            <FadeUp key={a.num} delay={Math.min(i * 30, 200)}>
              <article
                onClick={() => setSelected(a)}
                style={{
                  display: "grid",
                  gridTemplateColumns: "160px 1fr",
                  gap: 20,
                  background: "var(--white)",
                  border: "1px solid var(--hairline)",
                  padding: 16,
                  position: "relative",
                  transition: "box-shadow .25s, transform .25s",
                  cursor: "pointer",
                }}
                onMouseEnter={(e) => {
                  e.currentTarget.style.boxShadow =
                    "0 12px 30px -12px rgba(0,0,0,0.15)";
                  e.currentTarget.style.transform = "translateY(-2px)";
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.boxShadow = "none";
                  e.currentTarget.style.transform = "translateY(0)";
                }}
              >
                {a.type === "achat" && (
                  <div
                    style={{
                      position: "absolute",
                      top: 12,
                      right: 12,
                      fontFamily: "var(--mono)",
                      fontSize: 9,
                      letterSpacing: "0.16em",
                      textTransform: "uppercase",
                      color: "var(--paper)",
                      background: "var(--red)",
                      padding: "4px 8px",
                      zIndex: 2,
                    }}
                  >
                    Recherche
                  </div>
                )}
                <PhotoPH
                  ratio="1/1"
                  src={fullPath(a.photo)}
                  alt={a.titre}
                  label={a.categorie.toUpperCase()}
                />
                <div style={{ display: "flex", flexDirection: "column" }}>
                  <div
                    className="tag-gold"
                    style={{ fontSize: 9, marginBottom: 8 }}
                  >
                    — {a.categorie} —
                  </div>
                  <h3
                    style={{
                      fontFamily: "var(--display)",
                      fontWeight: 500,
                      fontSize: 19,
                      margin: "0 0 6px",
                      lineHeight: 1.2,
                    }}
                  >
                    {a.titre}
                  </h3>
                  <p
                    style={{
                      fontSize: 12.5,
                      color: "var(--gray)",
                      margin: "0 0 auto",
                      lineHeight: 1.5,
                      display: "-webkit-box",
                      WebkitLineClamp: 3,
                      WebkitBoxOrient: "vertical",
                      overflow: "hidden",
                    }}
                  >
                    {a.description}
                  </p>
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "baseline",
                      marginTop: 12,
                      gap: 8,
                    }}
                  >
                    <span
                      className="mono"
                      style={{ fontSize: 10, color: "var(--gray)" }}
                    >
                      {a.date}
                    </span>
                    <div
                      style={{
                        fontFamily: "var(--display)",
                        fontSize: 20,
                        fontWeight: 600,
                        color: "var(--red)",
                        whiteSpace: "nowrap",
                      }}
                    >
                      {a.prix_chf
                        ? `CHF ${a.prix_chf.toLocaleString("fr-CH")}.—`
                        : a.prix_label}
                    </div>
                  </div>
                </div>
              </article>
            </FadeUp>
          ))}
        </div>
      )}

      {/* pagination */}
      {totalPages > 1 && (
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            gap: 4,
            marginTop: 56,
          }}
        >
          <button
            className="btn btn-ghost"
            style={{ padding: "8px 14px" }}
            onClick={() => setPage((p) => Math.max(1, p - 1))}
            disabled={page <= 1}
          >
            ←
          </button>
          {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => (
            <button
              key={p}
              onClick={() => setPage(p)}
              style={{
                width: 40,
                height: 40,
                border: "1px solid var(--hairline)",
                background: p === page ? "var(--ink)" : "var(--white)",
                color: p === page ? "var(--paper)" : "var(--ink)",
                fontFamily: "var(--display)",
                fontSize: 16,
                fontStyle: "italic",
                cursor: "pointer",
              }}
            >
              {toRoman(p)}
            </button>
          ))}
          <button
            className="btn btn-ghost"
            style={{ padding: "8px 14px" }}
            onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
            disabled={page >= totalPages}
          >
            →
          </button>
        </div>
      )}

      {/* boutique officielle teaser */}
      <div
        style={{
          marginTop: 80,
          padding: 32,
          background: "var(--paper-2)",
          border: "1px solid var(--hairline)",
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          gap: 24,
          flexWrap: "wrap",
        }}
      >
        <div>
          <div className="tag-mono" style={{ marginBottom: 8 }}>
            — Aussi —
          </div>
          <div
            style={{
              fontFamily: "var(--display)",
              fontStyle: "italic",
              fontSize: 22,
            }}
          >
            La Boutique officielle de l'EAN
          </div>
          <div style={{ fontSize: 13, color: "var(--gray)", marginTop: 4 }}>
            Articles aux couleurs de l'Arquebuse — pin's, plaquettes, vêtements,
            souvenirs. Vente au secrétariat du stand.
          </div>
        </div>
        <button className="btn btn-ghost-gold">Visiter la boutique →</button>
      </div>

      {selected && (
        <AnnonceModal annonce={selected} onClose={() => setSelected(null)} />
      )}

      <style>{`
        @media (max-width: 900px) {
          .annonce-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </div>
  );
}

function AnnonceModal({ annonce, onClose }) {
  return (
    <div
      onClick={onClose}
      style={{
        position: "fixed",
        inset: 0,
        background: "rgba(26,26,26,0.7)",
        zIndex: 100,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        padding: 20,
        backdropFilter: "blur(2px)",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          background: "var(--paper)",
          maxWidth: 760,
          width: "100%",
          maxHeight: "90vh",
          overflowY: "auto",
          border: "1px solid var(--ink)",
          position: "relative",
        }}
      >
        <button
          onClick={onClose}
          style={{
            position: "absolute",
            top: 16,
            right: 16,
            background: "var(--paper)",
            border: "1px solid var(--hairline)",
            fontSize: 18,
            cursor: "pointer",
            color: "var(--ink)",
            zIndex: 2,
            width: 36,
            height: 36,
          }}
        >
          ✕
        </button>
        <div
          style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 0 }}
          className="modal-grid"
        >
          <div
            style={{
              background: "var(--paper-3)",
              minHeight: 360,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            {annonce.photo ? (
              <img
                src={fullPath(annonce.photo)}
                alt={annonce.titre}
                style={{
                  maxWidth: "100%",
                  maxHeight: 480,
                  objectFit: "contain",
                  display: "block",
                }}
              />
            ) : (
              <div className="tag-mono" style={{ color: "var(--gray)" }}>
                — Sans photo —
              </div>
            )}
          </div>
          <div style={{ padding: "36px 32px" }}>
            <div className="tag-gold" style={{ marginBottom: 14 }}>
              — {annonce.categorie} {annonce.type === "achat" && "· RECHERCHE"}{" "}
              —
            </div>
            <h2
              style={{
                fontFamily: "var(--display)",
                fontSize: 26,
                fontWeight: 500,
                margin: "0 0 18px",
                lineHeight: 1.2,
              }}
            >
              {annonce.titre}
            </h2>
            <div
              style={{
                fontFamily: "var(--display)",
                fontSize: 32,
                fontWeight: 600,
                color: "var(--red)",
                marginBottom: 20,
              }}
            >
              {annonce.prix_chf
                ? `CHF ${annonce.prix_chf.toLocaleString("fr-CH")}.—`
                : annonce.prix_label}
            </div>
            <hr className="hr-fine" />
            <p
              style={{
                fontSize: 14,
                color: "var(--ink-soft)",
                lineHeight: 1.7,
                margin: "20px 0",
              }}
            >
              {annonce.description}
            </p>
            <hr className="hr-fine" />
            <div
              style={{
                marginTop: 20,
                display: "grid",
                gridTemplateColumns: "90px 1fr",
                gap: 8,
                fontSize: 13,
              }}
            >
              <span className="tag-mono">N°</span>
              <span className="mono">#{annonce.num}</span>
              <span className="tag-mono">DATE</span>
              <span className="mono">{annonce.date}</span>
              <span className="tag-mono">TYPE</span>
              <span style={{ textTransform: "capitalize" }}>
                {annonce.type}
              </span>
              <span className="tag-mono">CAT.</span>
              <span>{annonce.categorie}</span>
            </div>
            <div style={{ marginTop: 28 }}>
              <button
                className="btn btn-primary"
                style={{ width: "100%", justifyContent: "center" }}
              >
                Contacter le vendeur →
              </button>
            </div>
          </div>
        </div>
        <style>{`
          @media (max-width: 700px) {
            .modal-grid { grid-template-columns: 1fr !important; }
          }
        `}</style>
      </div>
    </div>
  );
}

window.PageBoutique = PageBoutique;
