/* recipes.jsx — RecipesIndex (section) + RecipeDetail + CookMode */
(function () {
  const { useState, useMemo, useEffect, useRef } = React;
  const { cx, fmtTime, fmtDate, scaleAmount, Difficulty, Stat, SmartImg, useReveal } = window;

  // ==================================================================
  //  Recipes index (filterable grid)
  // ==================================================================
  function RecipesIndex({ go }) {
    const { RecipeCard } = window;
    const ref = useReveal();
    const all = window.RECIPES;
    const categories = ["All", ...Array.from(new Set(all.map((r) => r.category)))];
    const [cat, setCat] = useState("All");
    const [sort, setSort] = useState("new");

    const filtered = useMemo(() => {
      let list = all.filter((r) => cat === "All" || r.category === cat);
      list = [...list].sort((a, b) =>
        sort === "new" ? new Date(b.date) - new Date(a.date)
        : sort === "quick" ? a.total - b.total
        : a.title.localeCompare(b.title));
      return list;
    }, [cat, sort]);

    return (
      <div className="page container" ref={ref} style={{ paddingTop: "2.4rem", paddingBottom: "4rem" }}>
        <div className="col" style={{ gap: ".5rem", marginBottom: "1.8rem" }}>
          <span className="eyebrow">{filtered.length} of {all.length} recipes</span>
          <h1 className="h1">Recipes</h1>
          <p className="lead" style={{ maxWidth: 560 }}>{window.SECTIONS.recipes.blurb}</p>
        </div>

        {/* filter bar */}
        <div className="col" style={{ gap: ".85rem", marginBottom: "1.8rem" }}>
          <div className="row wrap" style={{ gap: ".5rem" }}>
            {categories.map((c) => (
              <button key={c} className="chip" aria-pressed={cat === c} onClick={() => setCat(c)}>{c}</button>
            ))}
            <div className="grow" />
            <div className="row hide-mobile" style={{ gap: ".4rem" }}>
              <span className="muted" style={{ fontSize: ".84rem" }}>Sort</span>
              {[["new", "Newest"], ["quick", "Quickest"], ["az", "A–Z"]].map(([k, l]) => (
                <button key={k} className="chip btn-sm" aria-pressed={sort === k} onClick={() => setSort(k)} style={{ height: "2rem" }}>{l}</button>
              ))}
            </div>
          </div>
        </div>

        {filtered.length === 0
          ? <div className="muted" style={{ textAlign: "center", padding: "4rem 0" }}>No recipes match these filters.</div>
          : <div className="grid-recipes stagger">{filtered.map((r, idx) => <RecipeCard key={r.slug} recipe={r} go={go} idx={idx} />)}</div>}
      </div>
    );
  }

  // ==================================================================
  //  Ingredient list (checkable + scaled)
  // ==================================================================
  function IngredientList({ recipe, factor, checked, toggle }) {
    return (
      <div>
        {recipe.ingredients.map((ing, i) => (
          <label key={i} className="ing" data-checked={checked.has(i)} data-opt={ing.opt}>
            <input type="checkbox" className="check" checked={checked.has(i)} onChange={() => toggle(i)} />
            <span className="ing-label">{ing.name}</span>
            <span className="ing-amt tnum">{scaleAmount(ing, factor)}</span>
          </label>
        ))}
      </div>
    );
  }

  function ServingStepper({ value, unit, onChange, base }) {
    const { Minus, Plus, RotateCcw, Users } = window.Icons;
    return (
      <div className="col" style={{ gap: ".55rem" }}>
        <div className="spread">
          <span className="row muted" style={{ gap: ".4rem", fontSize: ".85rem", fontWeight: 500 }}><Users size={15} /> {unit === "loaf" ? "Batch" : "Servings"}</span>
          {value !== base && (
            <button className="btn btn-ghost btn-sm" style={{ height: "1.7rem", padding: "0 .4rem", fontSize: ".78rem" }} onClick={() => onChange(base)}>
              <RotateCcw size={12} /> Reset
            </button>
          )}
        </div>
        <div className="row" style={{ gap: ".5rem" }}>
          <button className="btn btn-outline btn-icon" onClick={() => onChange(Math.max(1, value - 1))} aria-label="Fewer" disabled={value <= 1}><Minus size={16} /></button>
          <div className="card" style={{ flex: 1, textAlign: "center", padding: ".5rem", fontWeight: 600, fontSize: "1.05rem" }}>
            {value} <span className="muted" style={{ fontWeight: 400, fontSize: ".85rem" }}>{unit === "loaf" ? (value === 1 ? "loaf" : "loaves") : "portions"}</span>
          </div>
          <button className="btn btn-outline btn-icon" onClick={() => onChange(value + 1)} aria-label="More"><Plus size={16} /></button>
        </div>
      </div>
    );
  }

  // ==================================================================
  //  Cook mode (fullscreen, step by step)
  // ==================================================================
  function CookMode({ recipe, onExit, factor = 1, checked, toggle }) {
    const { X, ChevronLeft, ChevronRight, Check } = window.Icons;
    const [step, setStep] = useState(0);
    const [localChecked, setLocalChecked] = useState(checked || new Set());
    const [onlyStep, setOnlyStep] = useState(true);
    const [stepChecked, setStepChecked] = useState(new Set());
    const chk = checked || localChecked;
    const toggleChk = toggle || ((i) => setLocalChecked((s) => { const n = new Set(s); n.has(i) ? n.delete(i) : n.add(i); return n; }));
    const toggleStepChk = (k) => setStepChecked((s) => { const n = new Set(s); n.has(k) ? n.delete(k) : n.add(k); return n; });
    const total = recipe.steps.length;
    const wakeRef = useRef(null);

    // Ingredients shown in the left panel: just this step's, or the whole list.
    const shown = onlyStep
      ? recipe.steps[step].ingredients.map((ing, i) => ({ ing, key: step + ":" + i, on: stepChecked.has(step + ":" + i), toggle: () => toggleStepChk(step + ":" + i) }))
      : recipe.ingredients.map((ing, i) => ({ ing, key: i, on: chk.has(i), toggle: () => toggleChk(i) }));

    useEffect(() => {
      let released = false;
      (async () => {
        try { if (navigator.wakeLock) { wakeRef.current = await navigator.wakeLock.request("screen"); } } catch (e) {}
      })();
      const onKey = (e) => {
        if (e.key === "Escape") onExit();
        else if (e.key === "ArrowRight") setStep((s) => Math.min(s + 1, total - 1));
        else if (e.key === "ArrowLeft") setStep((s) => Math.max(s - 1, 0));
      };
      window.addEventListener("keydown", onKey);
      return () => { window.removeEventListener("keydown", onKey); try { wakeRef.current && wakeRef.current.release(); } catch (e) {} };
    }, [total, onExit]);

    const last = step === total - 1;
    return (
      <div className="cook">
        <div className="cook-top">
          <div className="row" style={{ gap: ".7rem" }}>
            <span className="badge badge-brand">Cook mode</span>
            <strong className="hide-mobile" style={{ letterSpacing: "-.01em" }}>{recipe.title}</strong>
          </div>
          <div className="row" style={{ gap: "1rem" }}>
            <span className="muted tnum" style={{ fontSize: ".9rem" }}>Step {step + 1} / {total}</span>
            <button className="btn btn-outline" onClick={onExit}><X size={16} /> Exit</button>
          </div>
        </div>

        <div style={{ padding: "0 clamp(1rem,4vw,2rem)" }}>
          <div className="cook-progress" style={{ marginTop: "1rem" }}><div style={{ width: ((step + 1) / total) * 100 + "%" }} /></div>
        </div>

        <div className="cook-split">
          {/* left half — ingredients */}
          <aside className="cook-ings">
            <div className="spread" style={{ marginBottom: ".2rem" }}>
              <h2 className="h3">Ingredients</h2>
              <label className="row" style={{ gap: ".5rem", cursor: "pointer", fontSize: ".82rem", userSelect: "none" }}>
                <span className="muted">Only this step</span>
                <button type="button" role="switch" aria-checked={onlyStep} className="switch" onClick={() => setOnlyStep((v) => !v)}><i /></button>
              </label>
            </div>
            <span className="muted" style={{ fontSize: ".8rem" }}>
              {onlyStep ? "Just what step " + (step + 1) + " needs" : shown.length + " items total"}
            </span>
            <div style={{ marginTop: ".5rem" }}>
              {shown.length === 0
                ? <p className="muted" style={{ fontSize: ".92rem", padding: ".6rem 0" }}>No new ingredients for this step.</p>
                : shown.map((row) => (
                  <label key={row.key} className="ing" data-checked={row.on} data-opt={row.ing.opt} style={{ padding: ".55rem 0" }}>
                    <input type="checkbox" className="check" checked={row.on} onChange={row.toggle} />
                    <span className="ing-label">{row.ing.name}</span>
                    <span className="ing-amt tnum">{window.scaleAmount(row.ing, factor)}</span>
                  </label>
                ))}
            </div>
          </aside>

          {/* right half — current instruction */}
          <div className="cook-instr">
            <div className="cook-step">
              <div className="row" style={{ gap: "1rem", marginBottom: "1.5rem" }}>
                <span style={{ width: "3.2rem", height: "3.2rem", borderRadius: 99, background: "var(--brand)", color: "var(--brand-fg)", display: "grid", placeContent: "center", fontWeight: 700, fontSize: "1.3rem", flex: "none" }}>{step + 1}</span>
                <span className="eyebrow">Step {step + 1} of {total}</span>
              </div>
              <p style={{ fontSize: "clamp(1.35rem, 2.4vw, 1.95rem)", lineHeight: 1.45, letterSpacing: "-.01em", fontWeight: 450, textWrap: "pretty" }}>{recipe.steps[step].text}</p>
            </div>
          </div>
        </div>

        <div className="cook-top" style={{ borderTop: "1px solid hsl(var(--border))", borderBottom: "none" }}>
          <button className="btn btn-outline btn-lg" onClick={() => setStep((s) => Math.max(0, s - 1))} disabled={step === 0}><ChevronLeft size={18} /> Back</button>
          {last
            ? <button className="btn btn-primary btn-lg" onClick={onExit}><Check size={18} /> Done</button>
            : <button className="btn btn-primary btn-lg" onClick={() => setStep((s) => Math.min(total - 1, s + 1))}>Next <ChevronRight size={18} /></button>}
        </div>
      </div>
    );
  }

  // ==================================================================
  //  Recipe detail
  // ==================================================================
  function RecipeDetail({ slug, go, recipeLayout }) {
    const recipe = window.RECIPES.find((r) => r.slug === slug);
    const ref = useReveal();
    const { ChevronLeft, Clock, Timer, Printer, ChefHat, Check, Utensils } = window.Icons;
    const { MD } = window;
    const baseServings = recipe.servings || 1;
    const [servings, setServings] = useState(baseServings);
    const [checked, setChecked] = useState(new Set());
    const [doneSteps, setDoneSteps] = useState(new Set());
    const [cook, setCook] = useState(false);
    const factor = servings / baseServings;

    useEffect(() => { window.scrollTo(0, 0); }, [slug]);

    const toggleCheck = (i) => setChecked((s) => { const n = new Set(s); n.has(i) ? n.delete(i) : n.add(i); return n; });
    const toggleStep = (i) => setDoneSteps((s) => { const n = new Set(s); n.has(i) ? n.delete(i) : n.add(i); return n; });

    const related = window.RECIPES.filter((r) => r.slug !== slug && r.category === recipe.category).slice(0, 3);
    const relatedFinal = (related.length ? related : window.RECIPES.filter((r) => r.slug !== slug)).slice(0, 3);

    const isLinear = recipeLayout === "linear";
    const isSplit = recipeLayout === "split";

    // ---- ingredients panel (reused in layouts) ----
    const IngredientsPanel = (
      <div className={cx("card", isSplit ? "" : "")} style={{ padding: "1.3rem", background: isSplit ? "var(--brand-soft)" : "hsl(var(--card))", borderColor: isSplit ? "var(--brand-line)" : "hsl(var(--border))" }}>
        <div className="spread" style={{ marginBottom: "1rem" }}>
          <h2 className="h3">Ingredients</h2>
          <span className="badge badge-outline">{recipe.ingredients.length}</span>
        </div>
        <ServingStepper value={servings} unit={recipe.servingsUnit} base={baseServings} onChange={setServings} />
        <hr className="sep" style={{ margin: "1rem 0 .3rem" }} />
        <IngredientList recipe={recipe} factor={factor} checked={checked} toggle={toggleCheck} />
        {checked.size > 0 && (
          <button className="btn btn-ghost btn-sm" style={{ marginTop: ".8rem" }} onClick={() => setChecked(new Set())}>Clear checked ({checked.size})</button>
        )}
      </div>
    );

    const StepsPanel = (
      <div>
        <div className="spread" style={{ marginBottom: ".4rem" }}>
          <h2 className="h2" style={{ fontSize: "1.5rem" }}>Method</h2>
          <span className="muted tnum" style={{ fontSize: ".88rem" }}>{doneSteps.size}/{recipe.steps.length} done</span>
        </div>
        <div className="cook-progress" style={{ marginBottom: ".4rem" }}><div style={{ width: (doneSteps.size / recipe.steps.length) * 100 + "%" }} /></div>
        <div>
          {recipe.steps.map((s, i) => (
            <div key={i} className="step" data-done={doneSteps.has(i)}>
              <button className="step-num" onClick={() => toggleStep(i)} aria-label={"Toggle step " + (i + 1)}>
                {doneSteps.has(i) ? <Check size={16} /> : i + 1}
              </button>
              <p className="step-body" style={{ fontSize: "1.02rem", lineHeight: 1.6 }}>{s.text}</p>
            </div>
          ))}
        </div>

        {recipe.notes && recipe.notes.length > 0 && (
          <div className="card card-pad" style={{ marginTop: "2rem", background: "hsl(var(--muted) / .4)" }}>
            <h3 className="h3" style={{ marginBottom: ".7rem" }}>Notes</h3>
            <ol className="prose" style={{ paddingLeft: "1.2rem", fontSize: ".96rem" }}>
              {recipe.notes.map((n, i) => <li key={i} style={{ marginTop: i ? ".5rem" : 0 }}>{n}</li>)}
            </ol>
          </div>
        )}
      </div>
    );

    return (
      <div className="page" ref={ref}>
        {cook && <CookMode recipe={recipe} onExit={() => setCook(false)} factor={factor} checked={checked} toggle={toggleCheck} />}

        {/* breadcrumb */}
        <div className="container" style={{ paddingTop: "1.5rem" }}>
          <button className="btn btn-ghost btn-sm" style={{ paddingLeft: ".4rem" }} onClick={() => go({ name: "section", section: "recipes" })}>
            <ChevronLeft size={16} /> All recipes
          </button>
        </div>

        {/* hero */}
        <header className="container" style={{ paddingTop: "1rem" }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(1.2rem,3vw,2.4rem)", alignItems: "center" }} className="recipe-hero">
            <div className="col" style={{ gap: "1rem" }}>
              <div className="row wrap" style={{ gap: ".5rem" }}>
                <span className="badge badge-brand">{recipe.category}</span>
              </div>
              <h1 className="h1">{recipe.title}</h1>
              <p className="lead" style={{ textWrap: "pretty" }}>{recipe.summary}</p>

              <div className="row wrap" style={{ gap: "1.3rem", padding: ".4rem 0" }}>
                <Stat icon={Timer} title="Active time">{fmtTime(recipe.active)} active</Stat>
                <Stat icon={Clock} title="Total time">{fmtTime(recipe.total)} total</Stat>
                <Difficulty level={recipe.difficulty} />
              </div>

              <div className="row wrap" style={{ gap: ".6rem", marginTop: ".2rem" }}>
                <button className="btn btn-primary" onClick={() => setCook(true)}><ChefHat size={17} /> Cook mode</button>
                <button className="btn btn-outline" onClick={() => window.print()}><Printer size={16} /> Print</button>
              </div>
            </div>

            <div className="rcard-media" style={{ borderRadius: "var(--radius)", aspectRatio: "4/3", boxShadow: "var(--shadow-md)" }}>
              <SmartImg src={recipe.image} alt={recipe.title} label={recipe.category} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
            </div>
          </div>
        </header>

        {/* equipment */}
        {recipe.equipment && recipe.equipment.length > 0 && (
          <div className="container" style={{ paddingTop: "2rem" }}>
            <div className="card card-pad reveal" style={{ display: "flex", gap: "1rem", alignItems: "flex-start", flexWrap: "wrap" }}>
              <span className="row" style={{ gap: ".5rem", fontWeight: 600, fontSize: ".92rem" }}><Utensils size={17} /> You'll need</span>
              <div className="row wrap" style={{ gap: ".5rem" }}>
                {recipe.equipment.map((e, i) => <span key={i} className="badge">{e}</span>)}
              </div>
            </div>
          </div>
        )}

        {/* body */}
        <div className="container" style={{ paddingTop: "2.5rem", paddingBottom: "1rem" }}>
          {isLinear ? (
            <div className="container-tight" style={{ margin: "0 auto", padding: 0 }}>
              <div className="reveal" style={{ marginBottom: "2.5rem" }}>{IngredientsPanel}</div>
              <div className="reveal">{StepsPanel}</div>
            </div>
          ) : (
            <div style={{ display: "grid", gridTemplateColumns: isSplit ? "0.85fr 1.15fr" : "330px 1fr", gap: "clamp(1.5rem,3.5vw,3rem)", alignItems: "start" }} className="recipe-body">
              <aside className="reveal" style={{ position: "sticky", top: "5rem" }}>{IngredientsPanel}</aside>
              <div className="reveal">{StepsPanel}</div>
            </div>
          )}
        </div>

        {/* gallery */}
        {recipe.gallery && recipe.gallery.length > 1 && (
          <div className="container" style={{ paddingTop: "2rem" }}>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(240px,1fr))", gap: "1rem" }}>
              {recipe.gallery.map((g, i) => (
                <div key={i} className="rcard-media reveal" style={{ borderRadius: "var(--radius)", aspectRatio: "4/3", boxShadow: "var(--shadow-sm)" }}>
                  <SmartImg src={g} alt={recipe.title} label="photo" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                </div>
              ))}
            </div>
          </div>
        )}

        {/* related */}
        <div className="container" style={{ paddingTop: "3.5rem", paddingBottom: "1rem" }}>
          <h2 className="h2" style={{ marginBottom: "1.3rem" }}>More to cook</h2>
          <div className="grid-recipes stagger">
            {relatedFinal.map((r, idx) => <window.RecipeCard key={r.slug} recipe={r} go={go} idx={idx} />)}
          </div>
        </div>
      </div>
    );
  }

  Object.assign(window, { RecipesIndex, RecipeDetail });
})();
