// project-modal.jsx — "New project" modal (name + color + visibility)

const 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 NewProjectModal({ open, onClose, onCreate, defaultWorkspaceId = null }) {
  const [name, setName]       = React.useState("");
  const [color, setColor]     = React.useState(PROJECT_COLORS[1]?.hex || "#0073ea");
  const [visibility, setVis]  = React.useState("workspace"); // workspace | private
  // Workspace selection — defaults to whichever workspace the user
  // is currently looking at (or first visible). If only one
  // workspace exists, the picker is hidden so the form stays simple.
  const [workspaceId, setWorkspaceId] = React.useState(null);
  const [busy, setBusy]       = React.useState(false);
  const [err, setErr]         = React.useState("");

  const nameRef = React.useRef(null);

  // Visible workspaces — read from the global hydrated by data.jsx.
  // Owner sees all; everyone else sees the ones populated by their
  // project memberships. Falls back to a single shell so the picker
  // never crashes a single-workspace install.
  const visibleWs = (() => {
    const all = (typeof WORKSPACES !== "undefined" && Array.isArray(WORKSPACES))
      ? WORKSPACES : [];
    return all.length ? all : [{ id: 1, name: (typeof WORKSPACE !== "undefined" && WORKSPACE.name) || "Workspace" }];
  })();

  React.useEffect(() => {
    if (!open) return;
    setName("");
    setColor(PROJECT_COLORS[1]?.hex || "#0073ea");
    setVis("workspace");
    // Pick the most natural default: explicit prop > first visible.
    setWorkspaceId(defaultWorkspaceId || (visibleWs[0] && visibleWs[0].id) || 1);
    setBusy(false);
    setErr("");
    setTimeout(() => nameRef.current?.focus(), 50);
  }, [open, defaultWorkspaceId]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape" && !busy) onClose();
      if ((e.metaKey || e.ctrlKey) && e.key === "Enter") submit();
    };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, name, color, visibility, workspaceId, busy]);

  async function submit() {
    const n = name.trim();
    if (!n || busy) return;
    setBusy(true);
    setErr("");
    try {
      await onCreate({ name: n, color, visibility, workspace_id: workspaceId });
      onClose();
    } catch (e) {
      setErr(e?.message || "Could not create project");
      setBusy(false);
    }
  }

  if (!open) return null;

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

        <div className="modal-body">
          <div className="ms-grid">
            {/* Workspace picker — shown only when more than one is
                visible. Single-workspace deploys get the original UX
                without a redundant dropdown. */}
            {visibleWs.length > 1 && (
              <div className="ms-row">
                <label className="ms-label">Workspace</label>
                <select className="ms-input"
                        value={workspaceId || ""}
                        onChange={e => setWorkspaceId(Number(e.target.value))}>
                  {visibleWs.map(ws => (
                    <option key={ws.id} value={ws.id}>{ws.name}</option>
                  ))}
                </select>
              </div>
            )}
            <div className="ms-row">
              <label className="ms-label">Name</label>
              <input className="ms-input nt-name"
                     ref={nameRef}
                     placeholder="e.g. Mobile redesign"
                     value={name} onChange={e => setName(e.target.value)}
                     onKeyDown={e => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); submit(); } }}/>
            </div>

            <div className="ms-row">
              <label className="ms-label">Color</label>
              <div className="nt-prio-row" style={{ flexWrap: "wrap" }}>
                {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>

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

        <div className="modal-footer">
          <div style={{ flex: 1, color: "var(--ink-muted)", fontSize: 11 }}>
            <kbd className="nt-kbd">⌘</kbd><kbd className="nt-kbd">↵</kbd> to create
          </div>
          <button className="btn" onClick={() => !busy && onClose()} disabled={busy}>Cancel</button>
          <button className="btn btn-primary" disabled={!name.trim() || busy} onClick={submit}>
            {busy ? <>Creating…</> : <><Icons.Plus size={13}/> Create project</>}
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
}

// ─────────────────────────────────────────────────────────────────
// Delete project — high-friction confirmation. The user must type
// the exact project name to enable the destructive button. Cascades
// through the FK chain server-side: tasks, epics, project_members,
// task_assignees / reviewers / labels / comments / attachments / qa
// items all go away. Sprints fall back to "no project" (SET NULL).
// Admin/owner-only — gated server-side too.
// ─────────────────────────────────────────────────────────────────
function DeleteProjectModal({ project, taskCount = 0, onClose, onConfirm }) {
  const [typed, setTyped]   = React.useState("");
  const [busy, setBusy]     = React.useState(false);
  const [error, setError]   = React.useState("");
  const expectedName = (project && project.name) || "";
  const matches = typed.trim() === expectedName.trim() && expectedName.length > 0;

  async function go() {
    if (!matches || busy) return;
    setBusy(true); setError("");
    try { await onConfirm(); }
    catch (e) { setError((e && e.message) || "Failed to delete."); setBusy(false); }
  }

  return ReactDOM.createPortal(
    <div className="dlt-backdrop" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="dlt-modal" role="dialog" aria-modal="true" aria-labelledby="dlt-title"
           onMouseDown={(e) => e.stopPropagation()}>
        {/* Hero — danger icon + title + close. Kept compact so the
            consequential bits below stay above the fold. */}
        <div className="dlt-hero">
          <div className="dlt-hero-icon" aria-hidden="true">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                 strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M3 6h18"/>
              <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
              <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
              <path d="M10 11v6M14 11v6"/>
            </svg>
          </div>
          <div className="dlt-hero-text">
            <div id="dlt-title" className="dlt-title">Delete project</div>
            <div className="dlt-sub">
              <b>{expectedName}</b> and everything inside it will be permanently deleted.
            </div>
          </div>
          <button className="dlt-close" onClick={onClose} aria-label="Close" type="button">×</button>
        </div>

        {/* Impact card — what specifically goes away. Stat numbers
            are big and visible so the reviewer doesn't gloss over the
            count. Bullet list spells out the cascade. */}
        <div className="dlt-impact">
          <div className="dlt-impact-stat">
            <div className="dlt-impact-num">{taskCount}</div>
            <div className="dlt-impact-label">{taskCount === 1 ? "task" : "tasks"} deleted</div>
          </div>
          <ul className="dlt-impact-list">
            <li>All epics, sprint links, and project members</li>
            <li>Every comment, attachment, and QA item</li>
            <li>Tasks already in the Bin are hard-deleted too</li>
          </ul>
        </div>

        <div className="dlt-warn">
          This cannot be undone.
        </div>

        {/* Type-to-confirm gate — same friction, cleaner presentation.
            Input mirrors the danger color the moment the typed value
            matches, giving instant positive feedback on the gate. */}
        <label className="dlt-confirm">
          <span className="dlt-confirm-label">
            Type <code>{expectedName}</code> to confirm
          </span>
          <input type="text" autoFocus
                 className={"dlt-confirm-input" + (matches ? " is-armed" : "")}
                 value={typed}
                 onChange={(e) => setTyped(e.target.value)}
                 onKeyDown={(e) => { if (e.key === "Enter" && matches) go(); }}
                 placeholder={expectedName}
                 spellCheck={false}
                 autoComplete="off"/>
        </label>

        {error && <div className="dlt-error">{error}</div>}

        <div className="dlt-footer">
          <button type="button" className="dlt-btn dlt-btn-cancel" onClick={onClose} disabled={busy}>
            Cancel
          </button>
          <button type="button"
                  className={"dlt-btn dlt-btn-danger" + (matches && !busy ? " is-ready" : "")}
                  onClick={go}
                  disabled={!matches || busy}>
            {busy ? "Deleting…" : `Delete ${expectedName}`}
          </button>
        </div>
      </div>
      {/* Scoped stylesheet — keeps the redesigned modal self-contained
          without polluting global modal styles that other modals share. */}
      <style>{`
        .dlt-backdrop {
          position: fixed; inset: 0; z-index: 10080;
          background: rgba(15, 23, 41, .55);
          backdrop-filter: blur(2px);
          display: flex; align-items: center; justify-content: center;
          animation: dltFadeIn .14s ease-out;
        }
        @keyframes dltFadeIn { from { opacity: 0 } to { opacity: 1 } }
        .dlt-modal {
          width: 460px; max-width: 92vw;
          background: white;
          border-radius: 14px;
          box-shadow: 0 32px 80px rgba(15, 23, 41, .35),
                      0 0 0 1px rgba(228, 68, 92, .15);
          overflow: hidden;
          animation: dltPop .18s cubic-bezier(.22, 1, .36, 1);
        }
        @keyframes dltPop {
          from { transform: scale(.94) translateY(8px); opacity: 0 }
          to   { transform: scale(1)    translateY(0);   opacity: 1 }
        }

        .dlt-hero {
          display: flex; align-items: flex-start; gap: 14px;
          padding: 22px 22px 16px;
          border-bottom: 1px solid #f5f6f8;
          position: relative;
        }
        .dlt-hero-icon {
          width: 46px; height: 46px; flex-shrink: 0;
          border-radius: 12px;
          background: linear-gradient(135deg, rgba(228,68,92,.18), rgba(228,68,92,.08));
          color: #c0223a;
          display: flex; align-items: center; justify-content: center;
        }
        .dlt-hero-text { flex: 1; min-width: 0; padding-right: 30px; }
        .dlt-title {
          font-size: 18px; font-weight: 800; color: #0f1729;
          letter-spacing: -0.01em; line-height: 1.2;
        }
        .dlt-sub {
          font-size: 13px; color: #676879; margin-top: 4px; line-height: 1.45;
          word-break: break-word;
        }
        .dlt-sub b { color: #0f1729; font-weight: 700; }
        .dlt-close {
          position: absolute; top: 14px; right: 14px;
          width: 28px; height: 28px; border-radius: 6px;
          background: transparent; border: 0;
          font-size: 22px; line-height: 1; color: #676879; cursor: pointer;
        }
        .dlt-close:hover { background: #f5f6f8; color: #0f1729; }

        .dlt-impact {
          margin: 16px 22px 0;
          padding: 12px 14px;
          border: 1px solid rgba(228, 68, 92, .22);
          background: rgba(228, 68, 92, .04);
          border-radius: 10px;
          display: flex; gap: 14px; align-items: flex-start;
        }
        .dlt-impact-stat {
          flex-shrink: 0;
          min-width: 64px;
          padding: 6px 10px 4px;
          background: rgba(228, 68, 92, .12);
          border-radius: 8px;
          text-align: center;
        }
        .dlt-impact-num {
          font-size: 22px; font-weight: 800; color: #c0223a;
          line-height: 1;
        }
        .dlt-impact-label {
          font-size: 10.5px; font-weight: 700; color: #a01b30;
          text-transform: uppercase; letter-spacing: .04em;
          margin-top: 3px;
        }
        .dlt-impact-list {
          flex: 1; min-width: 0;
          margin: 0; padding-left: 18px;
          font-size: 12.5px; line-height: 1.65; color: #a01b30;
        }
        .dlt-impact-list li { margin: 0; }

        .dlt-warn {
          margin: 12px 22px 0;
          padding: 8px 12px;
          font-size: 12px; font-weight: 700;
          color: #c0223a;
          letter-spacing: .02em;
          text-align: center;
          background: #fff7f8;
          border-radius: 6px;
        }

        .dlt-confirm {
          display: flex; flex-direction: column; gap: 6px;
          margin: 16px 22px 0;
        }
        .dlt-confirm-label {
          font-size: 11px; font-weight: 700; color: #676879;
          text-transform: uppercase; letter-spacing: .04em;
        }
        .dlt-confirm-label code {
          font-family: ui-monospace, "SF Mono", Menlo, monospace;
          background: #f5f6f8; padding: 1px 6px;
          border-radius: 4px; color: #0f1729;
          font-size: 12px;
          word-break: break-all;
        }
        .dlt-confirm-input {
          padding: 10px 12px; font-size: 14px;
          border: 1.5px solid #e6e9ef; border-radius: 8px;
          font-family: inherit;
          transition: border-color .12s, box-shadow .12s, background .12s;
          outline: none;
        }
        .dlt-confirm-input:focus {
          border-color: #b6bccb;
          box-shadow: 0 0 0 3px rgba(15, 23, 41, .06);
        }
        .dlt-confirm-input.is-armed {
          border-color: #e2445c;
          background: #fff8f9;
          box-shadow: 0 0 0 3px rgba(228, 68, 92, .14);
        }

        .dlt-error {
          margin: 10px 22px 0;
          font-size: 12.5px; color: #b41f37;
          background: rgba(228, 68, 92, .08);
          border: 1px solid rgba(228, 68, 92, .25);
          padding: 8px 10px; border-radius: 6px;
        }

        .dlt-footer {
          display: flex; justify-content: flex-end; gap: 8px;
          padding: 18px 22px 20px;
          margin-top: 18px;
          border-top: 1px solid #f5f6f8;
        }
        .dlt-btn {
          padding: 9px 16px; border-radius: 8px;
          font-size: 13px; font-weight: 600;
          cursor: pointer; border: 1px solid transparent;
          transition: background .1s, border-color .1s, transform .1s, box-shadow .1s;
        }
        .dlt-btn-cancel {
          background: white; color: #323338;
          border-color: #e6e9ef;
        }
        .dlt-btn-cancel:hover:not(:disabled) { background: #f5f6f8; }
        .dlt-btn-danger {
          background: #ffd5dc; color: #8a1224;
          border-color: rgba(228, 68, 92, .35);
          cursor: not-allowed;
          max-width: 220px;
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        .dlt-btn-danger.is-ready {
          background: #e2445c; color: white;
          border-color: #e2445c;
          cursor: pointer;
          box-shadow: 0 4px 14px rgba(228, 68, 92, .35);
        }
        .dlt-btn-danger.is-ready:hover { background: #cf2c45; border-color: #cf2c45; }
        .dlt-btn-danger.is-ready:active { transform: translateY(1px); }
        .dlt-btn:disabled { opacity: .55; cursor: not-allowed; }
      `}</style>
    </div>,
    document.body
  );
}

// ── NewWorkspaceModal ──────────────────────────────────────────────
// Tiny modal for owner-only workspace creation. Single Name input.
// Backend: POST /api/workspaces (owner-gated). Caller is auto-added
// as the new workspace's owner so they see it in the sidebar
// immediately.
function NewWorkspaceModal({ open, onClose, onCreated }) {
  const [name, setName] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [err, setErr]   = React.useState("");

  React.useEffect(() => {
    if (!open) return;
    setName(""); setBusy(false); setErr("");
  }, [open]);

  if (!open) return null;

  async function submit() {
    const n = name.trim();
    if (!n || busy) return;
    setBusy(true); setErr("");
    try {
      const r = await api.workspaces.create({ name: n });
      onCreated && onCreated(r);
      onClose && onClose();
    } catch (e) {
      const fromBody = e && e.body && (e.body.message || e.body.error);
      setErr(fromBody || (e && e.message) || "Could not create workspace");
      setBusy(false);
    }
  }

  return ReactDOM.createPortal(
    <div className="modal-backdrop" onMouseDown={() => !busy && onClose()}>
      <div className="modal" style={{ width: 420 }} onMouseDown={(e) => e.stopPropagation()}>
        <div className="modal-header">
          <div>
            <div className="modal-title">Create a new workspace</div>
            <div className="modal-subtitle">A workspace is a top-level container for projects.</div>
          </div>
          <button className="modal-close" onClick={() => !busy && onClose()}><Icons.Close size={16}/></button>
        </div>
        <div className="modal-body">
          <div className="ms-row">
            <label className="ms-label">Workspace name</label>
            <input className="ms-input"
                   value={name}
                   autoFocus
                   placeholder="e.g. Tabsyst Mobile"
                   onChange={e => { setName(e.target.value); setErr(""); }}
                   onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); submit(); } }}/>
          </div>
          {err && <div style={{ color: "var(--prio-critical, #c93636)", fontSize: 12, marginTop: 8 }}>{err}</div>}
        </div>
        <div className="modal-footer">
          <button className="btn-ghost" onClick={onClose} disabled={busy}>Cancel</button>
          <button className="btn-primary" onClick={submit} disabled={busy || !name.trim()}>
            {busy ? "Creating…" : "Create workspace"}
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
}

Object.assign(window, { NewProjectModal, DeleteProjectModal, NewWorkspaceModal, PROJECT_COLORS });
