/* Workouts tab — native Co-Pilot.
 *
 * Generator + Result on the home view. Library editing at
 * /#/workouts/library/{exercises|formats|warmups|finishers} — each item
 * opens in a Drawer with proper inputs (not just a name field).
 *
 * Recent-workouts data still flows under the surface so smart selection
 * can avoid same-exercise repeats; the UI peek was removed in favour of
 * library and equipment edits.
 */
(function () {
  const { useState, useEffect } = React;
  const {
    Card,
    Button,
    Pill,
    Drawer,
    Icons,
    Input,
    TextArea,
    SegmentedControl,
    LoadingSpinner,
    EmptyState,
    showToast,
    coach,
    workouts,
    time,
    tokens,
  } = window.CC;

  function Workouts({ route }) {
    if (route && route.startsWith("/workouts/library")) {
      return <Library route={route} />;
    }
    return <Generator />;
  }

  // ────────────────────────────────────────────────────────────
  // Generator
  // ────────────────────────────────────────────────────────────
  function Generator() {
    const [snap, setSnap] = useState(null);
    const [session, setSession] = useState("full");
    const [formatId, setFormatId] = useState(null);
    const [workout, setWorkout] = useState(null);
    const [generating, setGenerating] = useState(false);

    useEffect(() => workouts.subscribe(setSnap), []);

    const cat = snap?.catalogue;

    async function go() {
      if (!cat) return;
      setGenerating(true);
      await new Promise((r) => setTimeout(r, 60));
      const w = workouts.generate({ session, formatId });
      setWorkout(w);
      try { await workouts.logRecent(w); } catch {}
      setGenerating(false);
    }

    return (
      <div className="cc-workouts">
        <header className="cc-workouts__head">
          <h1 className="cc-hub__title">Workouts</h1>
          <a href="#/workouts/library/exercises" className="cc-workouts__lib-link">
            Edit libraries →
          </a>
        </header>

        <Card padding={20} className="cc-workouts__gen">
          <SessionPicker value={session} onChange={setSession} />
          <FormatPicker
            formats={cat?.formats || []}
            value={formatId}
            onChange={setFormatId}
          />
          <Button size="xl" fullWidth onClick={go} loading={generating} disabled={!cat}>
            Generate
          </Button>
        </Card>

        {workout && <ResultCard workout={workout} onRegenerate={go} />}
      </div>
    );
  }

  function SessionPicker({ value, onChange }) {
    return (
      <div className="cc-workouts__session">
        {[
          { v: "upper", l: "Upper" },
          { v: "lower", l: "Lower" },
          { v: "full", l: "Full" },
        ].map((s) => (
          <button
            key={s.v}
            type="button"
            onClick={() => onChange(s.v)}
            className={`cc-workouts__session-btn ${value === s.v ? "is-on" : ""}`}
          >
            {s.l}
          </button>
        ))}
      </div>
    );
  }

  function FormatPicker({ formats, value, onChange }) {
    return (
      <div className="cc-workouts__format">
        <span className="cc-workouts__format-label">Format</span>
        <select
          value={value || "auto"}
          onChange={(e) =>
            onChange(e.target.value === "auto" ? null : e.target.value)
          }
          className="cc-workouts__format-select"
        >
          <option value="auto">Auto-pick</option>
          {formats.map((f) => (
            <option key={f.id} value={f.id}>
              {f.name}
            </option>
          ))}
        </select>
      </div>
    );
  }

  function ResultCard({ workout, onRegenerate }) {
    const [copied, setCopied] = useState(false);
    function copy() {
      const text = workouts.buildText(workout);
      navigator.clipboard.writeText(text).then(() => {
        setCopied(true);
        showToast("Copied to clipboard.");
        setTimeout(() => setCopied(false), 1500);
      }).catch(() => showToast("Couldn’t copy."));
    }
    const sessLabel =
      workout.session === "upper" ? "Upper body"
      : workout.session === "lower" ? "Lower body"
      : "Full body";

    return (
      <div className="cc-result">
        <header className="cc-result__head">
          <div>
            <div className="cc-result__title">{sessLabel}</div>
            <div className="cc-result__sub">
              {workout.format.name} · ~{workout.time} min
              {workout.format.mode === "time" && (<>{" "}· {workout.format.workTime}s/{workout.format.restTime}s · {workout.format.rounds} rounds</>)}
              {workout.format.mode === "reps" && (<>{" "}· {workout.format.reps} reps · {workout.format.rounds} rounds</>)}
              {workout.format.mode === "amrap" && (<> · AMRAP {workout.format.capMinutes}m</>)}
            </div>
          </div>
          <div className="cc-result__head-actions">
            <Button variant="secondary" size="sm" onClick={onRegenerate}>Regenerate</Button>
            <Button variant={copied ? "ghost" : "primary"} size="sm" onClick={copy}>
              {copied ? "Copied" : "Copy"}
            </Button>
          </div>
        </header>

        <div className="cc-result__sections">
          <SectionCard
            accent="onTrack"
            label="Warmup"
            title={workout.warmup.name}
            hint={hintFor(workout.warmup)}
            desc={workout.warmup.desc}
          />
          <ExercisesCard exercises={workout.exercises} format={workout.format} />
          <SectionCard
            accent="overdue"
            label="Finisher"
            title={workout.finisher.name}
            hint={hintFor(workout.finisher)}
            desc={workout.finisher.desc}
          />
        </div>
      </div>
    );
  }

  function hintFor(item) {
    if (!item) return null;
    const groupLabel =
      item.group === "team"
        ? "Team"
        : item.group === "pair"
        ? "Pair"
        : item.group === "solo"
        ? "Solo"
        : null;
    return [item.dur, groupLabel].filter(Boolean).join(" · ");
  }

  function SectionCard({ accent, label, title, hint, desc }) {
    return (
      <Card padding={16} className={`cc-result__section cc-result__section--${accent}`}>
        <div className="cc-result__section-label">{label}</div>
        <div className="cc-result__section-title">{title}</div>
        {hint && <div className="cc-result__section-hint">{hint}</div>}
        {desc && <div className="cc-result__section-desc">{desc}</div>}
      </Card>
    );
  }

  function ExercisesCard({ exercises }) {
    return (
      <Card padding={16} className="cc-result__section cc-result__section--member">
        <div className="cc-result__section-label">Workout</div>
        <ol className="cc-result__exercises">
          {exercises.map((e, i) => (
            <li key={e.id}>
              <span className="cc-result__ex-num">{i + 1}</span>
              <span className="cc-result__ex-name">{e.name}</span>
              {e.equipment?.length > 0 && (
                <span className="cc-result__ex-eq">{e.equipment.join(" · ")}</span>
              )}
            </li>
          ))}
        </ol>
      </Card>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Library
  // ────────────────────────────────────────────────────────────
  function Library({ route }) {
    const [snap, setSnap] = useState(null);
    const [editing, setEditing] = useState(null); // existing item or 'new'
    useEffect(() => workouts.subscribe(setSnap), []);

    const segs = route.split("/").filter(Boolean);
    const kind = segs[2] || "exercises";
    const items = snap?.catalogue?.[kind] || [];

    return (
      <div className="cc-workouts">
        <header className="cc-workouts__head">
          <button
            type="button"
            className="cc-member-detail__back"
            onClick={() => (window.location.hash = "/workouts")}
          >
            ← Workouts
          </button>
          <h1 className="cc-hub__title">Libraries</h1>
        </header>
        <SegmentedControl
          value={kind}
          onChange={(v) => (window.location.hash = `/workouts/library/${v}`)}
          options={[
            { label: "Exercises", value: "exercises" },
            { label: "Formats", value: "formats" },
            { label: "Warmups", value: "warmups" },
            { label: "Finishers", value: "finishers" },
          ]}
        />

        {!snap?.catalogue ? (
          <LoadingSpinner delay={0} />
        ) : (
          <LibraryList
            kind={kind}
            items={items}
            onOpen={setEditing}
            onAdd={() => setEditing("new")}
          />
        )}

        {editing && (
          <LibraryDrawer
            kind={kind}
            item={editing === "new" ? null : editing}
            equipment={snap?.catalogue?.equipment || []}
            onClose={() => setEditing(null)}
          />
        )}
      </div>
    );
  }

  function LibraryList({ kind, items, onOpen, onAdd }) {
    if (items.length === 0) {
      return (
        <EmptyState
          icon={Icons.dumbbell(40)}
          title="Empty"
          subtitle="Add your first below."
          action={{ label: "Add", onClick: onAdd }}
        />
      );
    }
    return (
      <div className="cc-lib">
        <ul className="cc-lib__list">
          {items.map((it) => (
            <LibraryRow key={it.id} kind={kind} item={it} onOpen={() => onOpen(it)} />
          ))}
        </ul>
        <Button onClick={onAdd} variant="secondary" fullWidth>
          {Icons.plus(16)} Add {kind.slice(0, -1)}
        </Button>
      </div>
    );
  }

  function LibraryRow({ kind, item, onOpen }) {
    const stars = item.rating || 3;
    return (
      <li className="cc-lib-row" onClick={onOpen} role="button" tabIndex={0}>
        <div className="cc-lib-row__main">
          <span className="cc-lib-row__name-text">{item.name}</span>
          {item.desc && <span className="cc-lib-row__desc">{item.desc}</span>}
        </div>
        <span className="cc-lib-row__meta">
          {kind === "exercises" && (
            <>
              {(Array.isArray(item.category) ? item.category : [item.category]).join(" + ")}
              {(() => {
                const subs = Array.isArray(item.subcategory) ? item.subcategory : [item.subcategory].filter(Boolean);
                return subs.length ? ` · ${subs.join(" + ")}` : "";
              })()}
              {item.equipment?.length ? ` · ${item.equipment.join(", ")}` : ""}
            </>
          )}
          {(kind === "warmups" || kind === "finishers") && (
            <>
              {item.dur}
              {item.category?.length ? ` · ${item.category.join(", ")}` : ""}
              {item.group ? ` · ${item.group}` : ""}
            </>
          )}
          {kind === "formats" && (
            <>
              {item.mode}
              {item.mode === "reps" && ` · ${item.reps}r × ${item.rounds}`}
              {item.mode === "time" && ` · ${item.workTime}s/${item.restTime}s × ${item.rounds}`}
              {item.mode === "amrap" && ` · ${item.capMinutes}m cap`}
            </>
          )}
        </span>
        <span className="cc-lib-row__stars" aria-label={`Rating ${stars} of 5`}>
          {[1, 2, 3, 4, 5].map((n) => (
            <span key={n} className={n <= stars ? "is-on" : ""}>★</span>
          ))}
        </span>
        <span className="cc-lib-row__chev">{Icons.chevronRight(14)}</span>
      </li>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Edit/add drawer — branches on `kind`
  // ────────────────────────────────────────────────────────────
  function LibraryDrawer({ kind, item, equipment, onClose }) {
    const [draft, setDraft] = useState(() => item ? { ...item } : blank(kind));
    const [saving, setSaving] = useState(false);

    function patch(p) { setDraft((d) => ({ ...d, ...p })); }

    async function save() {
      if (!draft.name?.trim()) {
        showToast("Name is required.");
        return;
      }
      setSaving(true);
      try {
        const cat = workouts.getCatalogue();
        const list = (cat[kind] || []).slice();
        // Strip undefined values — Firebase rejects writes that contain any.
        const clean = JSON.parse(JSON.stringify(draft));
        if (item) {
          const idx = list.findIndex((x) => x.id === item.id);
          if (idx !== -1) list[idx] = clean;
        } else {
          const id = `${kind.slice(0, 3)}-${Date.now().toString(36)}`;
          list.push({ ...clean, id });
        }
        await workouts.saveCatalogue({ [kind]: list });
        showToast("Saved.");
        onClose();
      } catch (e) {
        console.error("save failed", e);
        showToast(`Couldn’t save: ${e.message || "unknown"}`);
      } finally {
        setSaving(false);
      }
    }

    async function remove() {
      if (!item) return;
      if (!confirm(`Remove "${item.name}"?`)) return;
      const cat = workouts.getCatalogue();
      const list = (cat[kind] || []).filter((x) => x.id !== item.id);
      await workouts.saveCatalogue({ [kind]: list });
      showToast("Removed.");
      onClose();
    }

    return (
      <Drawer
        open
        onClose={onClose}
        title={item ? `Edit ${kind.slice(0, -1)}` : `Add ${kind.slice(0, -1)}`}
        footer={
          <div style={{ display: "flex", gap: 8 }}>
            {item && (
              <Button variant="ghost" onClick={remove}>
                {Icons.trash(14)} Remove
              </Button>
            )}
            <span style={{ flex: 1 }} />
            <Button onClick={save} loading={saving}>Save</Button>
          </div>
        }
      >
        <div style={{ display: "grid", gap: 16 }}>
          <Input label="Name" value={draft.name || ""} onChange={(v) => patch({ name: v })} autoFocus />

          {kind === "exercises" && (
            <ExerciseFields draft={draft} patch={patch} equipment={equipment} />
          )}
          {(kind === "warmups" || kind === "finishers") && (
            <WarmupFinisherFields draft={draft} patch={patch} />
          )}
          {kind === "formats" && (
            <FormatFields draft={draft} patch={patch} />
          )}

          <RatingPicker value={draft.rating || 3} onChange={(r) => patch({ rating: r })} />
        </div>
      </Drawer>
    );
  }

  function ExerciseFields({ draft, patch, equipment }) {
    const cats = window.CC.workouts.CATEGORIES;
    const equipmentNames = (equipment || []).map((e) => e.name);
    const selectedCats = draft.category || [];
    const selectedTypes = draft.type || [];
    const selectedSubs = draft.subcategory || [];
    const selectedEq = draft.equipment || [];
    // Movement-pattern options = union of subcategories from the
    // currently-selected body parts.
    const subcats = Array.from(
      new Set(selectedCats.flatMap((c) => cats[c] || []))
    );

    function toggle(field, value) {
      const arr = draft[field] || [];
      const next = arr.includes(value)
        ? arr.filter((v) => v !== value)
        : [...arr, value];
      const patchObj = { [field]: next };
      // If we just removed a body part, drop any subcategories that no
      // longer have a parent.
      if (field === "category") {
        const validSubs = new Set(next.flatMap((c) => cats[c] || []));
        patchObj.subcategory = (draft.subcategory || []).filter((s) =>
          validSubs.has(s)
        );
      }
      patch(patchObj);
    }

    return (
      <>
        <div>
          <div className="cc-toggle-row__label">Type — tap any that apply</div>
          <div className="cc-tag-row">
            {[
              { v: "resistance", l: "Resistance" },
              { v: "cardio", l: "Cardio" },
            ].map((t) => (
              <button
                key={t.v}
                type="button"
                onClick={() => toggle("type", t.v)}
                className={`cc-tag ${selectedTypes.includes(t.v) ? "is-active" : ""}`}
              >
                {t.l}
              </button>
            ))}
          </div>
        </div>
        <div>
          <div className="cc-toggle-row__label">Body part — tap any that apply</div>
          <div className="cc-tag-row">
            {Object.keys(cats).map((c) => (
              <button
                key={c}
                type="button"
                onClick={() => toggle("category", c)}
                className={`cc-tag ${selectedCats.includes(c) ? "is-active" : ""}`}
              >
                {c}
              </button>
            ))}
          </div>
        </div>
        {subcats.length > 0 && (
          <div>
            <div className="cc-toggle-row__label">Movement pattern — tap any that apply</div>
            <div className="cc-tag-row">
              {subcats.map((s) => (
                <button
                  key={s}
                  type="button"
                  onClick={() => toggle("subcategory", s)}
                  className={`cc-tag ${selectedSubs.includes(s) ? "is-active" : ""}`}
                >
                  {s}
                </button>
              ))}
            </div>
          </div>
        )}
        <div>
          <div className="cc-toggle-row__label">Equipment</div>
          <div className="cc-tag-row">
            {equipmentNames.map((eq) => {
              const on = selectedEq.includes(eq);
              return (
                <button
                  key={eq}
                  type="button"
                  onClick={() =>
                    patch({
                      equipment: on
                        ? selectedEq.filter((x) => x !== eq)
                        : [...selectedEq, eq],
                    })
                  }
                  className={`cc-tag ${on ? "is-active" : ""}`}
                >
                  {eq}
                </button>
              );
            })}
          </div>
        </div>
      </>
    );
  }

  function WarmupFinisherFields({ draft, patch }) {
    const selectedCats = draft.category || [];
    function toggleCat(c) {
      const next = selectedCats.includes(c)
        ? selectedCats.filter((x) => x !== c)
        : [...selectedCats, c];
      patch({ category: next });
    }
    return (
      <>
        <Input
          label="Duration"
          value={draft.dur || ""}
          onChange={(v) => patch({ dur: v })}
          placeholder="e.g. 3 min"
        />
        <TextArea
          label="Description"
          value={draft.desc || ""}
          onChange={(v) => patch({ desc: v })}
          rows={3}
          maxRows={6}
        />
        <div>
          <div className="cc-toggle-row__label">Body emphasis — tap any that apply</div>
          <div className="cc-tag-row">
            {["Lower body", "Upper body", "Core", "Full body"].map((c) => (
              <button
                key={c}
                type="button"
                onClick={() => toggleCat(c)}
                className={`cc-tag ${selectedCats.includes(c) ? "is-active" : ""}`}
              >
                {c}
              </button>
            ))}
          </div>
        </div>
        <div>
          <div className="cc-toggle-row__label">Group</div>
          <div className="cc-tag-row">
            {[
              { v: "solo", l: "Solo" },
              { v: "pair", l: "Pair" },
              { v: "team", l: "Team" },
            ].map((g) => (
              <button
                key={g.v}
                type="button"
                onClick={() => patch({ group: g.v })}
                className={`cc-tag ${draft.group === g.v ? "is-active" : ""}`}
              >
                {g.l}
              </button>
            ))}
          </div>
        </div>
      </>
    );
  }

  function FormatFields({ draft, patch }) {
    return (
      <>
        <TextArea
          label="Description"
          value={draft.desc || ""}
          onChange={(v) => patch({ desc: v })}
          rows={2}
          maxRows={4}
        />
        <div>
          <div className="cc-toggle-row__label">Mode</div>
          <div className="cc-tag-row">
            {[
              { v: "reps", l: "Reps" },
              { v: "time", l: "Time" },
              { v: "amrap", l: "AMRAP" },
            ].map((m) => (
              <button
                key={m.v}
                type="button"
                onClick={() => patch({ mode: m.v })}
                className={`cc-tag ${draft.mode === m.v ? "is-active" : ""}`}
              >
                {m.l}
              </button>
            ))}
          </div>
        </div>
        <Input
          label="Exercises per workout"
          type="number"
          value={String(draft.exCount ?? 6)}
          onChange={(v) => patch({ exCount: Number(v) || 6 })}
        />
        {draft.mode === "reps" && (
          <>
            <Input
              label="Reps per exercise"
              type="number"
              value={String(draft.reps ?? 10)}
              onChange={(v) => patch({ reps: Number(v) || 10 })}
            />
            <Input
              label="Rounds"
              type="number"
              value={String(draft.rounds ?? 3)}
              onChange={(v) => patch({ rounds: Number(v) || 3 })}
            />
          </>
        )}
        {draft.mode === "time" && (
          <>
            <Input
              label="Work (seconds)"
              type="number"
              value={String(draft.workTime ?? 40)}
              onChange={(v) => patch({ workTime: Number(v) || 40 })}
            />
            <Input
              label="Rest (seconds)"
              type="number"
              value={String(draft.restTime ?? 20)}
              onChange={(v) => patch({ restTime: Number(v) || 20 })}
            />
            <Input
              label="Rounds"
              type="number"
              value={String(draft.rounds ?? 3)}
              onChange={(v) => patch({ rounds: Number(v) || 3 })}
            />
          </>
        )}
        {draft.mode === "amrap" && (
          <Input
            label="Time cap (minutes)"
            type="number"
            value={String(draft.capMinutes ?? 12)}
            onChange={(v) => patch({ capMinutes: Number(v) || 12 })}
          />
        )}
      </>
    );
  }

  function RatingPicker({ value, onChange }) {
    return (
      <div>
        <div className="cc-toggle-row__label">Rating</div>
        <span className="cc-stars">
          {[1, 2, 3, 4, 5].map((n) => (
            <button
              key={n}
              type="button"
              onClick={() => onChange(n)}
              className={n <= value ? "is-on" : ""}
              aria-label={`${n} stars`}
            >
              ★
            </button>
          ))}
        </span>
      </div>
    );
  }

  function blank(kind) {
    if (kind === "exercises") {
      return {
        name: "",
        category: ["Lower Body"],
        subcategory: ["Push (Squats/Lunges)"],
        equipment: [],
        type: ["resistance"],
        rating: 3,
      };
    }
    if (kind === "formats") {
      return {
        name: "",
        desc: "",
        mode: "reps",
        reps: 10,
        rounds: 3,
        exCount: 6,
        rating: 3,
      };
    }
    if (kind === "warmups") return { name: "", dur: "3 min", category: ["Full body"], group: "solo", desc: "", rating: 3 };
    if (kind === "finishers") return { name: "", dur: "5 min", category: ["Full body"], group: "solo", desc: "", rating: 3 };
    return { name: "" };
  }

  window.CC = window.CC || {};
  window.CC.Workouts = Workouts;
})();
