// IndieVertical — developer flow: dashboard, project editor, publish review modal.

function IvDevDashboard() {
  const { state, api } = useStore();
  const projects = Object.values(state.projects);
  const published = projects.filter((p) => p.status !== "draft");
  const featured = published.find((p) => p.slug === "hollow-root") || published[0];
  const msgCount = (slug) => ivThreadsFor(state, "dev").filter((t) => t.game === slug).reduce((n, t) => n + t.messages.length, 0);
  const threadCount = (slug) => ivThreadsFor(state, "dev").filter((t) => t.game === slug).length;
  const statusChip = (p) =>
    p.status === "published" ? <span className="pstatus">Published</span>
    : p.status === "pending" ? <span className="pstatus" style={{ borderColor: "var(--cool)", color: "var(--cool)", background: "var(--cool-bg)" }}>Pending review</span>
    : <span className="pstatus draft">Draft</span>;

  return (
    <div className="pp dir-marquee">
      <IvHeader />
      <div className="app" style={{ flex: 1 }}>
        <IvSidebar items={[
          { label: "My Projects", on: true, href: "#/dashboard" },
          { label: "Inbox", href: "#/inbox", dot: ivUnreadCount(state, "dev") > 0 },
        ]} />
        <div className="main">
          <div className="main-h">
            <h1>My projects</h1>
            <button type="button" className="btn btn-primary" style={{ height: 42, padding: "0 20px", fontSize: 14 }}
              onClick={() => { const slug = api.createProject(); ivGo("#/dashboard/projects/" + slug); }}>
              New project
            </button>
          </div>

          {projects.length === 0 && (
            <IvEmptyState heading="You do not have a game page yet" button="Make your game page"
              onClick={() => { const slug = api.createProject(); ivGo("#/dashboard/projects/" + slug); }}>
              <div className="esteps">
                <span className="st"><b>1</b> Tell us about your game. Add your description, screenshots, and deal details.</span>
                <span className="st"><b>2</b> Choose what is public and what stays private. Then publish when you are ready.</span>
              </div>
            </IvEmptyState>
          )}

          {projects.map((p) => {
            const f = p.fields;
            const canPublish = !!(f.trailerUrl || f.demoUrl);
            return (
              <div className="prow" key={p.slug}>
                <div className={"p-thumb " + p.art} style={p.fields.keyArtUrl ? { backgroundImage: "url(" + p.fields.keyArtUrl + ")", backgroundSize: "cover", backgroundPosition: "center" } : undefined}></div>
                <div>
                  <div className="p-t">{f.title || "Untitled project"} {statusChip(p)}</div>
                  <div className="p-meta">
                    {f.devStatus} · {f.dealType} · {p.status === "draft" ? "Last edited " + p.updated : "Updated " + p.updated}
                  </div>
                  <div className="p-meta">
                    {p.status === "draft"
                      ? (canPublish ? "Ready to publish from the editor" : "Needs a trailer or a playable demo before it can publish")
                      : p.stats.views.toLocaleString() + " views · " + p.stats.saves + " shortlist saves · " + msgCount(p.slug) + " messages"}
                  </div>
                </div>
                <div className="p-actions">
                  <a className="btn btn-secondary" href={"#/dashboard/projects/" + p.slug}>Edit</a>
                  <a className="btn btn-secondary" href={"#/game/" + p.slug}>{p.status === "draft" ? "Preview" : "Visit"}</a>
                </div>
              </div>
            );
          })}

          {featured && (
            <React.Fragment>
              <h2 className="h2-small">{featured.fields.title} — last 30 days</h2>
              <div className="statcards">
                <div className="sc"><div className="v">{featured.stats.views.toLocaleString()}</div><div className="l">Page Views</div></div>
                <div className="sc"><div className="v">{featured.stats.saves}</div><div className="l">Shortlist Saves</div></div>
                <div className="sc"><div className="v">{threadCount(featured.slug)}</div><div className="l">Conversations</div></div>
              </div>
            </React.Fragment>
          )}
        </div>
      </div>
    </div>
  );
}

// ---------- editor ----------
function IvField({ label, req, help, htmlFor, children }) {
  return (
    <div className="f-row">
      {htmlFor
        ? <label className="f-label" htmlFor={htmlFor}>{label} {req && <span className="req">Required</span>}</label>
        : <div className="f-label">{label} {req && <span className="req">Required</span>}</div>}
      {children}
      {help && <p className="f-help">{help}</p>}
    </div>
  );
}

function IvEditor({ slug }) {
  const { state, api } = useStore();
  const proj = state.projects[slug];
  const [showModal, setShowModal] = React.useState(false);

  if (!proj) {
    return (
      <div className="pp dir-marquee">
        <IvHeader />
        <div style={{ padding: "60px 32px" }}>
          <IvEmptyState heading="Project not found" button="Back to dashboard" href="#/dashboard" />
        </div>
        <IvFooter />
      </div>
    );
  }

  const f = proj.fields;
  const set = (key) => (e) => api.updateProject(slug, { [key]: e.target.value });
  const setSocial = (key) => (e) => api.updateProject(slug, { socials: { ...f.socials, [key]: e.target.value } });
  const canPublish = !!(f.trailerUrl || f.demoUrl);
  const isDraft = proj.status === "draft";
  const fileRef = React.useRef(null);
  const onArtFile = (e) => {
    const file = e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (ev) => api.setProjectKeyArt(slug, ev.target.result, file.name);
    reader.readAsDataURL(file);
    e.target.value = "";
  };

  const onPublish = () => {
    if (!f.title || !f.hook) { api.showToast("Add a title and a one-line hook before publishing."); return; }
    if (!canPublish) { api.showToast("Add a trailer or a playable demo link before publishing."); return; }
    setShowModal(true);
  };

  return (
    <div className="pp dir-marquee">
      <IvHeader />
      <div className="edwrap" style={{ flex: 1 }}>
        <div>
          <div className="main-h" style={{ marginBottom: 8 }}>
            <h1>{isDraft ? "Create" : "Edit"}: {f.title || "Untitled project"}</h1>
            <div className="ed-actions">
              <span className="ed-autosave">Saved automatically</span>
              <a className="btn btn-secondary" style={{ height: 42, padding: "0 18px", fontSize: 13.5 }} href={"#/game/" + slug}>Preview</a>
              {isDraft ? (
                <button type="button" className={"btn btn-primary" + (canPublish ? "" : " dis")} style={{ height: 42, padding: "0 22px", fontSize: 13.5 }} onClick={onPublish}>Publish</button>
              ) : (
                <a className="btn btn-primary" style={{ height: 42, padding: "0 22px", fontSize: 13.5 }} href={"#/game/" + slug}>View live page</a>
              )}
            </div>
          </div>
          <p className="ed-welcome">
            {isDraft
              ? "Let's build your game page. Fill in what you have. You can come back and edit anything before you publish."
              : "Your page is live. Changes here save automatically and show on your page right away."}
          </p>

          <div className="callout">
            <div className="co-t">Visibility — read this once</div>
            Each field has a visibility setting. You choose who can see what. Public means anyone, even people who are not logged in. Publisher accounts only means just the accounts that signed up as a publisher or scout. To keep a field fully private, leave it blank. Funding targets and contact details start at publisher accounts only.
          </div>

          <div className="fsec">
            <h3>Basics</h3>
            <IvField label="Key art" req help={'Recommended: 1200×420 px, PNG or JPG. Describe the image for people who cannot see it — "A character standing in a dark forest" is better than "key art."'}>
              <input ref={fileRef} type="file" accept="image/*" style={{ display: "none" }} onChange={onArtFile} />
              <div
                className={"upload" + (f.keyArtUrl ? "" : " " + proj.art)}
                style={f.keyArtUrl
                  ? { backgroundImage: "url(" + f.keyArtUrl + ")", backgroundSize: "cover", backgroundPosition: "center", borderStyle: "solid", cursor: "default" }
                  : { cursor: "pointer" }}
                onClick={f.keyArtUrl ? undefined : () => fileRef.current && fileRef.current.click()}
              >
                {f.keyArtUrl ? (
                  <span className="up-note" style={{ display: "flex", gap: 8, alignItems: "center" }}>
                    <span style={{ maxWidth: 200, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{f.keyArtName}</span>
                    <button type="button" className="up-act" onClick={(e) => { e.stopPropagation(); fileRef.current && fileRef.current.click(); }}>Change</button>
                    <button type="button" className="up-act" onClick={(e) => { e.stopPropagation(); api.setProjectKeyArt(slug, "", ""); }}>Remove</button>
                  </span>
                ) : (
                  <React.Fragment>
                    <span className="up-note">Click to upload key art</span>
                    <span className="up-swatches">
                      {[proj.art.startsWith("art-new") ? null : proj.art, "art-newa", "art-newb", "art-newc"].filter(Boolean).map((a) => (
                        <button type="button" key={a} className={a + (proj.art === a ? " on" : "")} title={a.replace("art-", "")}
                          onClick={(e) => { e.stopPropagation(); api.setProjectArt(slug, a); }}></button>
                      ))}
                    </span>
                  </React.Fragment>
                )}
              </div>
            </IvField>
            <IvField label="Game title" req htmlFor="ed-title">
              <input id="ed-title" className="f-input" type="text" value={f.title} placeholder="What is your game called?" onChange={set("title")} />
            </IvField>
            <IvField label="One-line hook" req help="This is the one sentence someone reads before deciding to look further. Write it like you would say it out loud to a stranger." htmlFor="ed-hook">
              <input id="ed-hook" className="f-input" type="text" value={f.hook} placeholder="One sentence that makes someone look twice." onChange={set("hook")} />
            </IvField>
            <IvField label="About this game" help="Two or three short paragraphs. What is it, what state is it in, what happens next." htmlFor="ed-description">
              <textarea id="ed-description" className="f-input area" value={f.description} placeholder="What is the game, and where is it at?" onChange={set("description")}></textarea>
            </IvField>
            <IvField label="About the team" help="Who is making this game? Names, roles, and what you have shipped before. Scouts bet on teams as much as games." htmlFor="ed-aboutteam">
              <textarea id="ed-aboutteam" className="f-input area" value={f.aboutTeam} placeholder="Who are you, and what have you shipped?" onChange={set("aboutTeam")}></textarea>
            </IvField>
          </div>

          <div className="fsec">
            <h3>Status and timing</h3>
            <div className="f-grid2">
              <IvField label="Trailer URL" htmlFor="ed-trailerurl">
                <input id="ed-trailerurl" className="f-input" type="text" value={f.trailerUrl} placeholder="youtube.com/watch?v=…" onChange={set("trailerUrl")} />
              </IvField>
              <IvField label="Dev status" req htmlFor="ed-devstatus">
                <select id="ed-devstatus" className="f-input" value={f.devStatus} onChange={set("devStatus")}>
                  {IV_DEV_STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}
                </select>
              </IvField>
            </div>
            <IvField label="Target release" req help={"Give your best guess. A quarter (\"Q3 2027\"), a month, a year, or \"not sure\" all work. Scouts use it to see if your timing fits their plans. You can change it anytime."} htmlFor="ed-targetrelease">
              <input id="ed-targetrelease" className="f-input" type="text" value={f.targetRelease} placeholder="Q3 2027" onChange={set("targetRelease")} />
            </IvField>
            <div className="f-grid2">
              <IvField label="Deal type" req htmlFor="ed-dealtype">
                <select id="ed-dealtype" className="f-input" value={f.dealType} onChange={set("dealType")}>
                  {IV_DEAL_TYPES.map((s) => <option key={s} value={s}>{s}</option>)}
                </select>
              </IvField>
              <IvField label="Playable demo link" help={"A working demo link turns on your \"Demo available\" badge."} htmlFor="ed-demo">
                <input id="ed-demo" className="f-input" type="text" value={f.demoUrl} placeholder="yourgame.itch.io/demo" onChange={set("demoUrl")} />
              </IvField>
            </div>
            {!canPublish && isDraft && <p className="req-note">A trailer or a playable demo is required before this page can publish.</p>}
          </div>

          <div className="fsec">
            <h3>Deal details</h3>
            <div className="f-row">
              <label className="f-label" htmlFor="ed-funding">Funding range</label>
              <input id="ed-funding" className="f-input" type="text" value={f.fundingValue} placeholder="$100k – $250k" onChange={set("fundingValue")} />
              <IvVisToggle gated={f.fundingGated} onChange={(v) => api.updateProject(slug, { fundingGated: v })} />
              <p className="f-help">Keep this at "publisher accounts only" by default. A public number can attract noise. Scouts use it to check fit before reaching out.</p>
            </div>
            <div className="f-row">
              <fieldset style={{ border: "none", padding: 0, margin: 0, width: "100%" }}>
                <legend className="f-label">Traction</legend>
                <div className="f-grid2" style={{ gridTemplateColumns: "1fr 1fr 1fr" }}>
                  <div>
                    <p className="f-help" style={{ margin: "0 0 5px" }}>Wishlists</p>
                    <select id="ed-traction-w" className="f-input" value={f.tractionW} onChange={set("tractionW")}>
                      <option value="">Not set</option>
                      {IV_RANGES.map((r) => <option key={r} value={r}>{r}</option>)}
                    </select>
                  </div>
                  <div>
                    <p className="f-help" style={{ margin: "0 0 5px" }}>Discord members</p>
                    <select id="ed-traction-d" className="f-input" value={f.tractionD} onChange={set("tractionD")}>
                      <option value="">Not set</option>
                      {IV_RANGES.map((r) => <option key={r} value={r}>{r}</option>)}
                    </select>
                  </div>
                  <div>
                    <p className="f-help" style={{ margin: "0 0 5px" }}>Social followers</p>
                    <select id="ed-traction-s" className="f-input" value={f.tractionS} onChange={set("tractionS")}>
                      <option value="">Not set</option>
                      {IV_RANGES.map((r) => <option key={r} value={r}>{r}</option>)}
                    </select>
                  </div>
                </div>
              </fieldset>
              <IvVisToggle gated={f.tractionGated} onChange={(v) => api.updateProject(slug, { tractionGated: v })} />
              <p className="f-help">Pick the range that matches today. Ranges keep exact numbers private while still telling scouts the scale. They check against their own data anyway.</p>
            </div>
            <IvField label="Comp titles" help="Name 2 or 3 games that feel similar to yours in tone, mechanics, or audience. These help scouts figure out the market fast." htmlFor="ed-comps">
              <input id="ed-comps" className="f-input" type="text" value={f.comps} placeholder="Game one, game two, game three" onChange={set("comps")} />
            </IvField>
            <div className="f-row">
              <label className="f-label" htmlFor="ed-contact">Contact</label>
              <input id="ed-contact" className="f-input" type="text" value={f.contactValue} placeholder="you@studio.com" onChange={set("contactValue")} />
              <IvVisToggle gated={f.contactGated} onChange={(v) => api.updateProject(slug, { contactGated: v })} />
              <p className="f-help">To keep something fully private, leave the field blank. It will not show on your page at all.</p>
            </div>
          </div>

          <div className="fsec">
            <h3>Social links</h3>
            <p className="f-help" style={{ marginTop: -8, marginBottom: 14 }}>Add what you actually keep updated. One main link is enough. Leave the rest blank and they will not show on your page.</p>
            <div className="f-grid2">
              {[["x", "X", "x.com/…"], ["bluesky", "Bluesky", "bsky.app/profile/…"], ["instagram", "Instagram", "instagram.com/…"], ["tiktok", "TikTok", "tiktok.com/@…"], ["facebook", "Facebook", "facebook.com/…"], ["linkedin", "LinkedIn", "linkedin.com/company/…"], ["linktree", "Linktree", "linktr.ee/…"], ["other", "Other", "Any other link…"]].map(([key, label, ph]) => (
                <div className="f-row" style={{ marginBottom: 0 }} key={key}>
                  <label className="f-label" htmlFor={"ed-social-" + key}>{label}</label>
                  <input id={"ed-social-" + key} className="f-input" type="text" value={f.socials[key]} placeholder={ph} onChange={setSocial(key)} />
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="prevcol">
          <div className="prev-tag">Live preview · indievertical.com/game/{slug}</div>
          <div className="prevcard">
            <div className={"pv-art " + proj.art} style={f.keyArtUrl ? { backgroundImage: "url(" + f.keyArtUrl + ")", backgroundSize: "cover", backgroundPosition: "center" } : undefined}>
              <div className="scrim"></div>
              <div className="pv-t">
                <h4>{f.title || "Untitled project"}</h4>
                <p>{f.hook || "Your one-line hook shows here."}</p>
              </div>
            </div>
            <div className="pv-body">
              <div className="badge-row">
                <span className="badge">{f.devStatus}</span>
                <span className="badge">{f.dealType}</span>
                {f.demoUrl && <span className="badge demo">Demo available</span>}
              </div>
              <div className="gc-tags">{[f.targetRelease, f.comps ? "Like: " + f.comps : null].filter(Boolean).join(" · ") || "Target release and comps show here."}</div>
              {f.fundingValue && f.fundingGated && (
                <div className="gate" style={{ maxWidth: "none" }}>
                  <span className="lock"><IvLock /></span>
                  <div>
                    <div className="g-t">Funding range</div>
                    <div className="g-d">Shown to publisher accounts only.</div>
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {showModal && <IvPublishModal slug={slug} onClose={() => setShowModal(false)} />}
      <IvFooter />
    </div>
  );
}

// ---------- publish review modal ----------
function IvPublishModal({ slug, onClose }) {
  const { state, api } = useStore();
  const proj = state.projects[slug];
  const dialogRef = React.useRef(null);
  React.useEffect(() => {
    if (dialogRef.current) dialogRef.current.focus();
  }, []);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onClose]);
  const f = proj.fields;
  const socials = Object.entries(f.socials).filter(([, v]) => v).map(([k]) => k === "x" ? "X" : k[0].toUpperCase() + k.slice(1));
  const rows = [
    ["Game title", f.title, "pub"],
    ["One-line hook", f.hook, "pub"],
    ["Key art", f.keyArtUrl ? (f.keyArtName || "Uploaded image") : "Placeholder palette", "pub"],
    f.trailerUrl ? ["Trailer", f.trailerUrl, "pub"] : null,
    f.demoUrl ? ["Playable demo link", f.demoUrl, "pub"] : null,
    (f.tractionW || f.tractionD || f.tractionS) ? ["Traction ranges", ["Wishlists " + (f.tractionW || "—"), "Discord " + (f.tractionD || "—"), "Followers " + (f.tractionS || "—")].join(" · "), f.tractionGated ? "gated" : "pub"] : null,
    f.comps ? ["Comp titles", f.comps, "pub"] : null,
    f.aboutTeam ? ["About the team", f.aboutTeam.slice(0, 60) + (f.aboutTeam.length > 60 ? "…" : ""), "pub"] : null,
    socials.length ? ["Social links", socials.join(" · "), "pub"] : null,
    f.fundingValue ? ["Funding range", f.fundingValue, f.fundingGated ? "gated" : "pub"] : null,
    f.contactValue ? ["Contact", f.contactValue, f.contactGated ? "gated" : "pub"] : null,
  ].filter(Boolean);

  return (
    <div className="modal-scrim" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal" role="dialog" aria-modal="true" aria-labelledby="pubmodal-title" tabIndex={-1} ref={dialogRef}>
        <h2 id="pubmodal-title">One last look before you go live</h2>
        <p className="m-sub">Check that your visibility settings are right for each field. Once published, scouts can find your page.</p>
        <table className="vtable">
          <thead>
            <tr><th>Field</th><th>Value</th><th>Who can see it</th></tr>
          </thead>
          <tbody>
            {rows.map(([field, value, vis]) => (
              <tr key={field}>
                <td className="fname">{field}</td>
                <td className="fval">{value}</td>
                <td>
                  {vis === "pub"
                    ? <span className="vis-chip pub">Public</span>
                    : <span className="vis-chip gated"><IvLock /> Publisher accounts only</span>}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        <div className="modal-actions">
          <button type="button" className="btn-ghost" onClick={onClose}>Go back and edit</button>
          <button type="button" className="btn btn-primary" style={{ padding: "0 24px" }}
            onClick={() => { api.publishProject(slug); onClose(); ivGo("#/game/" + slug); }}>
            Publish my page
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { IvDevDashboard, IvEditor, IvPublishModal });
