// project-settings-modal.jsx — Per-project settings panel.
//
// Triggered by the gear icon in the project header. Edits the same
// fields the New-project modal accepts (name, color, visibility),
// plus a Calendar section that gates the social-media channel
// tagging on tasks (the `is_content_calendar` flag).
//
// All saves go through api.projects.patch so the existing role gate
// (project owner OR workspace admin/owner) holds. Optimistic updates
// mutate the global PROJECTS array in place so the rest of the app
// (drawer, new-task-modal, calendar) re-reads the new values.

const SETTINGS_PROJECT_COLORS = (typeof EPIC_COLORS !== "undefined" && Array.isArray(EPIC_COLORS)) ? EPIC_COLORS : [
  { id: "purple", hex: "#a25ddc", label: "Purple" },
  { id: "blue",   hex: "#0073ea", label: "Blue"   },
  { id: "teal",   hex: "#0086c0", label: "Teal"   },
  { id: "green",  hex: "#00c875", label: "Green"  },
  { id: "yellow", hex: "#fdab3d", label: "Yellow" },
  { id: "red",    hex: "#e2445c", label: "Red"    },
  { id: "pink",   hex: "#ff5ac4", label: "Pink"   },
  { id: "indigo", hex: "#5559df", label: "Indigo" },
  { id: "gray",   hex: "#676879", label: "Gray"   },
];

function ProjectSettingsModal({ open, project, onClose, onSaved }) {
  const [section, setSection]     = React.useState("general"); // general | calendar
  const [name, setName]           = React.useState("");
  const [color, setColor]         = React.useState(SETTINGS_PROJECT_COLORS[1].hex);
  const [visibility, setVis]      = React.useState("workspace");
  const [contentMode, setContent] = React.useState(false);
  // Default reviewer for new stories created under this project.
  // "" = none set (every new story starts with no reviewer; user picks).
  // Anything else = a user id which auto-fills the reviewer field in
  // NewStoryModal. Implements gap 2 from the office-workflow review.
  const [defaultReviewerId, setDefaultReviewerId] = React.useState("");
  const [busy, setBusy]           = React.useState(false);
  const [err, setErr]             = React.useState("");
  const [okMsg, setOk]            = React.useState("");

  // Hydrate state from `project` whenever the modal opens
  React.useEffect(() => {
    if (!open || !project) return;
    setSection("general");
    setName(project.name || "");
    setColor(project.color || SETTINGS_PROJECT_COLORS[1].hex);
    setVis(project.visibility || "workspace");
    setContent(!!project.isContentCalendar);
    setDefaultReviewerId(project.defaultReviewerId || "");
    setErr(""); setOk(""); setBusy(false);
  }, [open, project && project.id]);

  // ESC closes
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape" && !busy) onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, busy, onClose]);

  if (!open || !project) return null;

  // Compute the diff against the current project so we only PATCH what changed
  function diff() {
    const out = {};
    if (name.trim() && name.trim() !== project.name) out.name = name.trim();
    if (color && color !== project.color) out.color = color;
    if (visibility && visibility !== (project.visibility || "workspace")) out.visibility = visibility;
    if (!!contentMode !== !!project.isContentCalendar) out.is_content_calendar = !!contentMode;
    // Default reviewer — empty string serializes as null so the column
    // can be cleared back to "no default".
    const next = defaultReviewerId || null;
    const prev = project.defaultReviewerId || null;
    if (next !== prev) out.default_reviewer_id = next;
    return out;
  }
  const dirty = Object.keys(diff()).length > 0;

  async function save() {
    if (busy) return;
    const d = diff();
    if (!Object.keys(d).length) { onClose(); return; }
    setBusy(true); setErr(""); setOk("");
    try {
      // Optimistic mutation of the in-memory project so the rest of
      // the app sees the new values immediately.
      if (typeof PROJECTS !== "undefined") {
        const p = PROJECTS.find(x => x.id === project.id);
        if (p) {
          if ("name" in d) p.name = d.name;
          if ("color" in d) p.color = d.color;
          if ("visibility" in d) p.visibility = d.visibility;
          if ("is_content_calendar" in d) p.isContentCalendar = !!d.is_content_calendar;
          if ("default_reviewer_id" in d) p.defaultReviewerId = d.default_reviewer_id || null;
        }
      }
      // Persist
      if (typeof api !== "undefined" && api.projects && typeof api.projects.patch === "function") {
        await api.projects.patch(project.id, d);
      }
      // Tell the rest of the app something changed (calendar header,
      // sidebar swatch, etc).
      try {
        window.dispatchEvent(new CustomEvent("flowboard:project:patched", {
          detail: { id: project.id, fields: d }
        }));
      } catch {}
      setOk("Saved.");
      if (typeof onSaved === "function") onSaved(project.id, d);
      // Close after a short beat so the user sees the confirmation
      setTimeout(() => { onClose(); }, 450);
    } catch (e) {
      setErr((e && e.message) || "Couldn't save settings.");
      setBusy(false);
    }
  }

  return ReactDOM.createPortal(
    <div className="modal-backdrop" onMouseDown={() => !busy && onClose()}>
      <div className="modal nt-modal" onMouseDown={e => e.stopPropagation()} style={{ width: 640 }}>
        <div className="modal-header">
          <div style={{ flex: 1 }}>
            <div className="nt-breadcrumb">
              <Icons.Folder size={11}/> {project.name || "Project"} → Settings
            </div>
            <div className="modal-title">Project settings</div>
          </div>
          <button className="modal-close" onClick={() => !busy && onClose()}>
            <Icons.Close size={16}/>
          </button>
        </div>

        {/* Section tabs */}
        <div style={{
          display: "flex",
          gap: 4,
          padding: "6px 16px 0",
          borderBottom: "1px solid var(--bd, #e6e9ef)",
        }}>
          {[
            { id: "general",     label: "General",     icon: <Icons.Folder size={12}/> },
            { id: "calendar",    label: "Calendar",    icon: <Icons.Calendar size={12}/> },
            { id: "automations", label: "Automations", icon: <Icons.Sparkle size={12}/> },
          ].map(s => (
            <button
              key={s.id}
              className={`project-tab ${section === s.id ? "is-active" : ""}`}
              onClick={() => setSection(s.id)}
              style={{ marginBottom: -1 }}
            >
              {s.icon} {s.label}
            </button>
          ))}
        </div>

        <div className="modal-body" style={{ minHeight: 280 }}>
          {section === "general" && (
            <div className="ms-grid">
              <div className="ms-row">
                <label className="ms-label">Project name</label>
                <input className="ms-input nt-name"
                       value={name}
                       onChange={e => setName(e.target.value)}
                       onKeyDown={e => { if (e.key === "Enter" && !e.shiftKey && !busy) { e.preventDefault(); save(); } }}/>
              </div>

              <div className="ms-row">
                <label className="ms-label">Color</label>
                <div className="nt-prio-row" style={{ flexWrap: "wrap" }}>
                  {SETTINGS_PROJECT_COLORS.map(c => (
                    <button key={c.id}
                            className="nt-prio-chip"
                            onClick={() => setColor(c.hex)}
                            title={c.label}
                            style={{
                              background: color === c.hex ? c.hex : "#fff",
                              color: color === c.hex ? "#fff" : c.hex,
                              borderColor: c.hex,
                              fontWeight: color === c.hex ? 700 : 500,
                              minWidth: 88,
                            }}>
                      <span style={{
                        display: "inline-block", width: 10, height: 10, borderRadius: 3,
                        background: c.hex, marginRight: 6, verticalAlign: "middle",
                        border: color === c.hex ? "1px solid rgba(255,255,255,.6)" : "none",
                      }}/>
                      {c.label}
                    </button>
                  ))}
                </div>
              </div>

              <div className="ms-row">
                <label className="ms-label">Visibility</label>
                <div className="nt-prio-row">
                  <button className={`nt-prio-chip ${visibility === "workspace" ? "is-active" : ""}`}
                          onClick={() => setVis("workspace")}
                          style={visibility === "workspace" ? { background: "#0073ea", color: "#fff", borderColor: "#0073ea" } : null}>
                    <Icons.Users size={12}/> Workspace
                  </button>
                  <button className={`nt-prio-chip ${visibility === "private" ? "is-active" : ""}`}
                          onClick={() => setVis("private")}
                          style={visibility === "private" ? { background: "#676879", color: "#fff", borderColor: "#676879" } : null}>
                    <Icons.Eye size={12}/> Private
                  </button>
                </div>
                <div style={{ fontSize: 11, color: "var(--ink-muted)", marginTop: 4 }}>
                  {visibility === "workspace"
                    ? "Anyone in the workspace can see this project."
                    : "Only members you invite can see this project."}
                </div>
              </div>

              {/* Default reviewer for new user stories — implements
                  gap 2 of the office-workflow review. Coordinator-led
                  teams have the same tester on every story; this saves
                  re-picking them every time. Stored as a column on
                  projects (migration 041). NewStoryModal auto-fills
                  this when the user opens the modal. */}
              <div className="ms-row">
                <label className="ms-label">Default story reviewer</label>
                <select className="ms-input"
                        value={defaultReviewerId || ""}
                        onChange={(e) => setDefaultReviewerId(e.target.value)}
                        style={{ maxWidth: 320 }}>
                  <option value="">— No default (pick per story)</option>
                  {(() => {
                    // Dedupe (defensive, matches the pattern in
                    // NewStoryModal) and filter to active users.
                    const src = (typeof PEOPLE !== "undefined" && Array.isArray(PEOPLE) ? PEOPLE : [])
                      .filter(p => p && p.status !== "deactivated" && p.status !== "inactive");
                    const seen = new Set();
                    const out = [];
                    for (const p of src) {
                      if (!p.id || seen.has(p.id)) continue;
                      seen.add(p.id);
                      out.push(p);
                    }
                    return out.map(p => (
                      <option key={p.id} value={p.id}>{p.name || p.email || p.id}</option>
                    ));
                  })()}
                </select>
                <div style={{ fontSize: 11, color: "var(--ink-muted)", marginTop: 4 }}>
                  New user stories created under this project will
                  auto-fill this person as the reviewer. They get
                  notified when the story enters review and can
                  Approve or Request changes. Per-story override
                  available in the New Story modal.
                </div>
              </div>
            </div>
          )}

          {section === "calendar" && (
            <div className="ms-grid">
              {/* Channel tagging toggle */}
              <div className="ms-row">
                <label className="ms-label">Social-media channels</label>
                <div className="nt-prio-row">
                  <button
                    className={`nt-prio-chip ${contentMode ? "is-active" : ""}`}
                    onClick={() => setContent(true)}
                    style={contentMode ? { background: "#0f1729", color: "#fff", borderColor: "#0f1729" } : null}
                  >
                    On
                  </button>
                  <button
                    className={`nt-prio-chip ${!contentMode ? "is-active" : ""}`}
                    onClick={() => setContent(false)}
                    style={!contentMode ? { background: "#676879", color: "#fff", borderColor: "#676879" } : null}
                  >
                    Off
                  </button>
                </div>
                <div style={{ fontSize: 12, color: "var(--ink-muted)", marginTop: 8, lineHeight: 1.55 }}>
                  When <b>On</b>, every task in this project gets a <b>Channel</b> field
                  (Instagram, YouTube, Blog, Newsletter, LinkedIn, X, TikTok, Facebook, Threads,
                  Podcast). The Calendar view colors task chips by channel and lets you filter
                  by one. Turn it off for projects that aren't about content.
                </div>
              </div>

              {/* Channel preview */}
              {contentMode && (
                <div className="ms-row">
                  <label className="ms-label">Available channels</label>
                  <div className="nt-prio-row" style={{ flexWrap: "wrap", gap: 6 }}>
                    {(typeof window !== "undefined" && Array.isArray(window.CHANNELS) ? window.CHANNELS : []).map(c => (
                      <span
                        key={c.id}
                        title={c.label}
                        style={{
                          display: "inline-flex",
                          alignItems: "center",
                          gap: 6,
                          padding: "4px 10px 4px 4px",
                          borderRadius: 999,
                          background: "#fff",
                          border: `1px solid ${c.color}`,
                          color: c.color,
                          fontSize: 12,
                          fontWeight: 500,
                        }}
                      >
                        {typeof ChannelPill === "function"
                          ? <ChannelPill id={c.id} size="lg"/>
                          : <span style={{
                              display: "inline-flex", alignItems: "center", justifyContent: "center",
                              width: 18, height: 18, borderRadius: 999,
                              background: c.color, color: "#fff",
                              fontSize: 9, fontWeight: 800,
                            }}>{c.short}</span>}
                        {c.label}
                      </span>
                    ))}
                  </div>
                  <div style={{ fontSize: 11, color: "var(--ink-muted)", marginTop: 6 }}>
                    Tasks tagged with a channel show this colored pill on the calendar and table views.
                  </div>
                </div>
              )}
            </div>
          )}

          {section === "automations" && (
            <AutomationsTab projectId={project.id}/>
          )}

          {err && (
            <div className="ms-row" style={{ color: "#c0223a", fontSize: 12, marginTop: 8 }}>{err}</div>
          )}
          {okMsg && !err && (
            <div className="ms-row" style={{ color: "#0a8c47", fontSize: 12, marginTop: 8 }}>{okMsg}</div>
          )}
        </div>

        <div className="modal-footer">
          <div style={{ flex: 1, color: "var(--ink-muted)", fontSize: 11 }}>
            {dirty
              ? <>{Object.keys(diff()).length} unsaved change{Object.keys(diff()).length === 1 ? "" : "s"}</>
              : <>No changes</>}
          </div>
          <button className="btn" onClick={() => !busy && onClose()} disabled={busy}>Cancel</button>
          <button className="btn btn-primary" disabled={!dirty || busy || !name.trim()} onClick={save}>
            {busy ? "Saving…" : "Save changes"}
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
}

// ── Automations tab ────────────────────────────────────────
// Two cards inside Project Settings → Automations:
//   1) Auto-close parent — toggle + target status picker.
//      When ON, marking every child of a task as Done bubbles the
//      parent up to the chosen status.
//   2) Status → Assignee — table of rules. When a task transitions
//      INTO the chosen status, auto-assign per the picked strategy.
// Owner / workspace-admin only (backend gate). The component is
// self-fetching so the parent modal doesn't need to thread state.
function AutomationsTab({ projectId }) {
  const [data, setData]       = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr]         = React.useState("");
  const [savingTarget, setSavingTarget] = React.useState(false);
  const [showAddRule, setShowAddRule]   = React.useState(false);

  const STATUSES = (typeof window !== "undefined" && Array.isArray(window.STATUSES))
    ? window.STATUSES
    : [{ id: "todo", label: "To Do" }, { id: "in-progress", label: "In Progress" },
       { id: "review", label: "Review" }, { id: "done", label: "Done" }];
  const PEOPLE   = (typeof window !== "undefined" && Array.isArray(window.PEOPLE)) ? window.PEOPLE : [];

  const reload = React.useCallback(async () => {
    setLoading(true); setErr("");
    try {
      const r = await window.api.projects.automations.get(projectId);
      setData(r);
    } catch (e) {
      setErr((e && e.body && (e.body.message || e.body.error)) || (e && e.message) || "Could not load automations");
    } finally { setLoading(false); }
  }, [projectId]);
  React.useEffect(() => { reload(); }, [reload]);

  async function setAutoCloseTarget(val) {
    setSavingTarget(true);
    try {
      await window.api.projects.automations.patch(projectId, { auto_close_parent_status: val || null });
      setData(d => d ? { ...d, auto_close_parent_status: val || null } : d);
    } catch (e) {
      setErr((e && e.body && (e.body.message || e.body.error)) || "Could not save");
    } finally { setSavingTarget(false); }
  }

  async function removeRule(ruleId) {
    if (!window.confirm("Remove this rule?")) return;
    try { await window.api.projects.automations.removeRule(projectId, ruleId); reload(); }
    catch (e) { setErr((e && e.body && (e.body.message || e.body.error)) || "Could not delete"); }
  }

  function labelForStatus(id) { return (STATUSES.find(s => s.id === id) || {}).label || id; }
  function labelForUser(id)   { const p = PEOPLE.find(p => p.id === id); return p ? p.name : id; }
  function labelForStrategy(r) {
    if (r.strategy === "user")              return labelForUser(r.assignee_user_id);
    if (r.strategy === "project_owner")     return "Project owner";
    if (r.strategy === "reporter")          return "Reporter";
    if (r.strategy === "round_robin_team")  return "Round-robin (team)";
    return r.strategy;
  }

  if (loading) return <div className="ms-grid" style={{ color: "var(--ink-muted)", padding: "20px 0" }}>Loading automations…</div>;
  if (err && !data) return <div className="ms-grid" style={{ color: "#c0223a", padding: "20px 0" }}>{err}</div>;

  const target = data && data.auto_close_parent_status;
  const rules  = (data && data.rules) || [];

  return (
    <div className="ms-grid" style={{ gap: 18 }}>
      {/* Card 1 — auto-close parent */}
      <div style={{ border: "1px solid var(--bd, #e6e9ef)", borderRadius: 10, padding: 14, background: "var(--bg-card, #fff)" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 }}>
          <div>
            <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--ink-strong, #0f1729)" }}>
              Auto-close parent when all subtasks are Done
            </div>
            <div style={{ fontSize: 12, color: "var(--ink-muted)", marginTop: 2 }}>
              Move the parent to the chosen status as soon as every child task is Done. Bubbles all the way up the chain.
            </div>
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 12 }}>
          <span style={{ fontSize: 12.5, color: "var(--ink-muted)" }}>Target status</span>
          <select value={target || ""} disabled={savingTarget}
                  onChange={e => setAutoCloseTarget(e.target.value)}
                  style={{ padding: "5px 10px", borderRadius: 7, border: "1px solid var(--bd, #d8dce4)", fontSize: 13, background: "#fff" }}>
            <option value="">— Off —</option>
            {STATUSES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
          </select>
        </div>
      </div>

      {/* Card 2 — status → assignee rules */}
      <div style={{ border: "1px solid var(--bd, #e6e9ef)", borderRadius: 10, padding: 14, background: "var(--bg-card, #fff)" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, marginBottom: 8 }}>
          <div>
            <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--ink-strong, #0f1729)" }}>
              Auto-assign on status change
            </div>
            <div style={{ fontSize: 12, color: "var(--ink-muted)", marginTop: 2 }}>
              When a task moves INTO a status, reassign it per the rule.
            </div>
          </div>
          <button className="btn btn-primary" style={{ padding: "4px 10px", fontSize: 12 }} onClick={() => setShowAddRule(true)}>+ Add rule</button>
        </div>
        {rules.length === 0 ? (
          <div style={{ fontSize: 12.5, color: "var(--ink-muted)", padding: "10px 0" }}>No rules yet. Click <b>+ Add rule</b> to create one.</div>
        ) : (
          <div>
            {rules.map(r => (
              <div key={r.id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 0", borderBottom: "1px solid var(--border-row, #f1f2f5)" }}>
                <div style={{ fontSize: 12.5, color: "var(--ink-muted)", minWidth: 50 }}>When</div>
                <span style={{ padding: "2px 8px", borderRadius: 99, fontSize: 11.5, fontWeight: 700, background: "#eef1f6", color: "#5f6675" }}>
                  {labelForStatus(r.status)}
                </span>
                <div style={{ fontSize: 12.5, color: "var(--ink-muted)" }}>→ assign to</div>
                <span style={{ fontSize: 13, fontWeight: 600, color: "var(--ink-strong, #0f1729)" }}>{labelForStrategy(r)}</span>
                <div style={{ flex: 1 }}/>
                <button className="btn" style={{ padding: "3px 8px", fontSize: 11.5 }} onClick={() => removeRule(r.id)}>Remove</button>
              </div>
            ))}
          </div>
        )}
      </div>

      {err && <div style={{ color: "#c0223a", fontSize: 12 }}>{err}</div>}

      {showAddRule && (
        <AddRuleModal projectId={projectId}
                      onClose={() => setShowAddRule(false)}
                      onSaved={() => { setShowAddRule(false); reload(); }}
                      statuses={STATUSES} people={PEOPLE}/>
      )}
    </div>
  );
}

function AddRuleModal({ projectId, onClose, onSaved, statuses, people }) {
  const [status, setStatus]   = React.useState(statuses[0] && statuses[0].id || "");
  const [strategy, setStrat]  = React.useState("user");
  const [userId, setUserId]   = React.useState(people[0] && people[0].id || "");
  const [busy, setBusy]       = React.useState(false);
  const [err, setErr]         = React.useState("");

  async function save() {
    if (!status) return;
    if (strategy === "user" && !userId) { setErr("Pick a user"); return; }
    setBusy(true); setErr("");
    try {
      await window.api.projects.automations.addRule(projectId, {
        status,
        strategy,
        assignee_user_id: strategy === "user" ? userId : null,
      });
      onSaved();
    } catch (e) {
      setErr((e && e.body && (e.body.message || e.body.error)) || "Could not save");
      setBusy(false);
    }
  }

  return ReactDOM.createPortal(
    <div className="modal-backdrop" onMouseDown={onClose}>
      <div className="modal" onMouseDown={e => e.stopPropagation()} style={{ width: 440 }}>
        <div className="modal-header"><div style={{ fontWeight: 700 }}>New assignment rule</div>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body" style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <label style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            <span style={{ fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".04em", color: "var(--ink-muted)" }}>When status becomes</span>
            <select value={status} onChange={e => setStatus(e.target.value)}
                    style={{ padding: "7px 10px", borderRadius: 7, border: "1px solid var(--bd, #d8dce4)", fontSize: 13 }}>
              {statuses.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
            </select>
          </label>
          <label style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            <span style={{ fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".04em", color: "var(--ink-muted)" }}>Assign to</span>
            <select value={strategy} onChange={e => setStrat(e.target.value)}
                    style={{ padding: "7px 10px", borderRadius: 7, border: "1px solid var(--bd, #d8dce4)", fontSize: 13 }}>
              <option value="user">A specific user</option>
              <option value="project_owner">The project owner</option>
              <option value="reporter">The reporter (whoever created the task)</option>
            </select>
          </label>
          {strategy === "user" && (
            <label style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              <span style={{ fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".04em", color: "var(--ink-muted)" }}>User</span>
              <select value={userId} onChange={e => setUserId(e.target.value)}
                      style={{ padding: "7px 10px", borderRadius: 7, border: "1px solid var(--bd, #d8dce4)", fontSize: 13 }}>
                {people.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </label>
          )}
          {err && <div style={{ color: "#c0223a", fontSize: 12 }}>{err}</div>}
        </div>
        <div className="modal-footer">
          <button className="btn" onClick={onClose} disabled={busy}>Cancel</button>
          <button className="btn btn-primary" onClick={save} disabled={busy}>{busy ? "Saving…" : "Add rule"}</button>
        </div>
      </div>
    </div>,
    document.body
  );
}

Object.assign(window, { ProjectSettingsModal });
