// ============ APPROVALS TAB ============
// Anything an agent kicked up to you for sign-off. Inline edit, approve, reject.

function ApprovalsTab({ agents, onCountChange }) {
  const byId = Object.fromEntries(agents.map((a) => [a.id, a]));
  const fmtSourceConvo = (c) => {
    if (typeof c === "string") return c;
    if (!c || typeof c !== "object") return "";
    return [c.channel, c.from].filter(Boolean).join(": ") || "conversation";
  };
  const fallbackAgent = (it) => ({
    id: it.agentId || it.agent || "learning",
    name: it.agentName || "Agent",
    role: it.kind === "learning" ? "Learning approval" : "Approval",
    palette: { skin: "#8b8f98" },
  });
  const [pending, setPending] = useState([]);
  const [editingId, setEditingId] = useState(null);
  const [draft, setDraft] = useState(null);
  const [decided, setDecided] = useState(null); // { id, kind: "approved" | "rejected" }

  const reloadPending = () => {
    return fetch(`/approvals?status=pending`)
      .then((r) => r.ok ? r.json() : [])
      .then((list) => {
        const filtered = list.filter((item) => item.kind === "learning");
        setPending(filtered);
        onCountChange && onCountChange(filtered.length);
        return filtered;
      })
      .catch(() => []);
  };

  // Load pending approvals from server on mount.
  useEffect(() => {
    reloadPending();
  }, []);

  const startEdit = (it) => {
    if (it.kind === "learning") return;
    setEditingId(it.id);
    setDraft({ title: it.title, body: it.body, amount: it.amount || "" });
  };
  const cancelEdit = () => { setEditingId(null); setDraft(null); };
  const saveEdit = (id) => {
    const body = { title: draft.title, body: draft.body, amount: draft.amount || null };
    fetch(`/approvals/${id}`, {
      method: "PUT",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(body),
    })
      .then((r) => r.ok ? r.json() : null)
      .then((updated) => {
        if (updated) setPending((p) => p.map((x) => x.id === id ? updated : x));
      })
      .catch(() => {
        // Optimistic local update if server unreachable
        setPending((p) => p.map((x) => x.id === id
          ? { ...x, ...body, edited: true } : x));
      });
    cancelEdit();
  };
  const decide = (id, kind) => {
    setDecided({ id, kind });
    fetch(`/approvals/${id}/${kind === "approved" ? "approve" : "reject"}`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({}),
    })
      .then((r) => r.json().then((j) => ({ ok: r.ok, status: r.status, j })).catch(() => ({ ok: r.ok, status: r.status, j: {} })))
      .then(({ ok, status, j }) => {
        if (!ok) {
          const msg = String(j?.error || "").toLowerCase();
          if (status === 404 || status === 409 || msg === "not found" || msg === "already decided") {
            return reloadPending().then(() => {
              throw new Error("This item was already processed. Refreshed the approvals list.");
            });
          }
          throw new Error(j?.error || "Approval action failed");
        }
        setTimeout(() => {
          reloadPending();
          setDecided(null);
        }, 700);
      })
      .catch((e) => {
        setDecided(null);
        window.toast && window.toast(String(e?.message || "Approval action failed"), "warn");
      });
  };

  if (pending.length === 0) {
    return (
      <div className="ap-empty">
        <div className="ap-empty-mark">✓</div>
        <div className="ap-empty-t">All caught up</div>
        <div className="ap-empty-s">No approvals waiting on you. Your agents are running clean.</div>
      </div>
    );
  }

  return (
    <div className="ap-page">
      <div className="ap-head">
        <div className="ap-head-c">{pending.length}</div>
        <div className="ap-head-l">items waiting on your call</div>
      </div>
      <div className="ap-list">
        {pending.map((it) => {
          const a = byId[it.agentId] || byId[it.agent] || fallbackAgent(it);
          const agentColor = a.palette && a.palette.skin ? a.palette.skin : "#8b8f98";
          const agentInitial = a.name ? a.name[0] : "?";
          const isLearning = it.kind === "learning";
          const lesson = it.proposedLesson || {};
          const isEditing = editingId === it.id;
          const isDecided = decided && decided.id === it.id;
          const riskLabel = it.riskLevel || "low";
          const needsCitrus = it.status === "pending";
          const needsMaster = it.masterStatus === "pending";
          const timeLabel = it.createdAt
            ? new Date(it.createdAt).toLocaleString(undefined, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" })
            : it.raised || "";
          return (
            <div key={it.id} className={`ap-card ${isEditing ? "is-editing" : ""} ${isDecided ? `is-${decided.kind}` : ""}`}>
              <div className="ap-card-side" style={{ background: agentColor }} />
              <div className="ap-card-body">
                <div className="ap-card-meta">
                  <div className="ap-card-agent">
                    <span className="ap-card-mark" style={{ background: agentColor }}>{agentInitial}</span>
                    {a.name} · {a.role}
                    {it.edited ? <span className="ap-edited">edited</span> : null}
                  </div>
                  <div className="ap-card-time">{timeLabel}</div>
                </div>

                {isEditing ? (
                  <>
                    <input
                      className="ap-input ap-input-title"
                      value={draft.title}
                      onChange={(e) => setDraft({ ...draft, title: e.target.value })}
                      placeholder="Title"
                    />
                    <textarea
                      className="ap-input ap-input-body"
                      value={draft.body}
                      onChange={(e) => setDraft({ ...draft, body: e.target.value })}
                      placeholder="Details"
                      rows={4}
                    />
                    <div className="ap-input-row">
                      <label className="ap-input-l">Amount</label>
                      <input
                        className="ap-input ap-input-amount"
                        value={draft.amount}
                        onChange={(e) => setDraft({ ...draft, amount: e.target.value })}
                        placeholder="$0.00 (optional)"
                      />
                    </div>
                    <div className="ap-card-cta">
                      <button className="btn btn-primary btn-sm" onClick={() => saveEdit(it.id)}>Save & approve</button>
                      <button className="btn btn-ghost btn-sm" onClick={() => { saveEdit(it.id); }}>Save changes</button>
                      <button className="btn btn-ghost btn-sm" onClick={cancelEdit}>Cancel</button>
                    </div>
                  </>
                ) : (
                  <>
                    {isLearning ? (
                      <>
                        <div className="ap-card-title">Learning approval: {lesson.what || it.title || "Proposed lesson"}</div>
                        {lesson.why ? (
                          <div className="ap-card-text">
                            <strong>Why:</strong> {lesson.why}
                          </div>
                        ) : null}
                        {lesson.sourceQuote ? (
                          <div className="ap-card-text">
                            <strong>Source quote:</strong> "{lesson.sourceQuote}"
                          </div>
                        ) : null}
                        {Array.isArray(lesson.sourceConvos) && lesson.sourceConvos.length ? (
                          <div className="ap-card-text">
                            <strong>Source conversations:</strong> {lesson.sourceConvos.map(fmtSourceConvo).filter(Boolean).join(", ")}
                          </div>
                        ) : null}
                        <div className="ap-card-text">
                          <strong>Risk:</strong> {riskLabel}
                          {Array.isArray(it.riskReasons) && it.riskReasons.length
                            ? ` - ${it.riskReasons.join("; ")}`
                            : ""}
                        </div>
                        <div className="ap-card-text">
                          <strong>Citrus approval:</strong> {needsCitrus ? "required" : it.status || "unknown"}
                          {" · "}
                          <strong>Master approval:</strong> {needsMaster ? "required" : (it.masterStatus || "unknown").replace("_", " ")}
                        </div>
                      </>
                    ) : (
                      <>
                        <div className="ap-card-title">{it.title}</div>
                        <div className="ap-card-text">{it.body}</div>
                        {it.amount ? <div className="ap-card-amount">{it.amount}</div> : null}
                      </>
                    )}
                    <div className="ap-card-cta">
                      <button className="btn btn-primary btn-sm" onClick={() => decide(it.id, "approved")}>Approve</button>
                      {!isLearning ? <button className="btn btn-ghost btn-sm" onClick={() => startEdit(it)}>Edit</button> : null}
                      <button className="btn btn-ghost btn-sm ap-reject" onClick={() => decide(it.id, "rejected")}>Reject</button>
                    </div>
                  </>
                )}

                {isDecided ? (
                  <div className={`ap-decided ap-decided-${decided.kind}`}>
                    {decided.kind === "approved" ? "✓ Approved — sending back to " + a.name : "✕ Rejected — letting " + a.name + " know"}
                  </div>
                ) : null}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.ApprovalsTab = ApprovalsTab;
