// Prompt Configuration — edit systemPromptTemplate + ageGuidelines in config/story_generation

const AGE_GROUPS = ["1-2", "2-3", "3-4", "4-5", "5-6", "6+"];

const DEFAULT_CONFIG = {
  systemPromptTemplate: "",
  ageGuidelines: Object.fromEntries(AGE_GROUPS.map(k => [k, { words: "", vocab: "" }])),
};

function deepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

function isDirty(original, draft) {
  return JSON.stringify(original) !== JSON.stringify(draft);
}

function TokenBadge({ token }) {
  return (
    <code style={{
      display: "inline-block", padding: "1px 7px", borderRadius: 5,
      background: "var(--bg-soft)", border: "1px solid var(--border)",
      fontFamily: "var(--mono)", fontSize: 11, color: "var(--accent)",
    }}>{token}</code>
  );
}

function PagePrompts() {
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [savedAt, setSavedAt] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [config, setConfig] = React.useState(null);   // last-saved from server
  const [draft, setDraft] = React.useState(null);     // local edits

  React.useEffect(() => { load(); }, []);

  async function load() {
    setLoading(true);
    setError(null);
    try {
      const res = await window.__adminGetPromptConfig({});
      const data = res.data || DEFAULT_CONFIG;
      setConfig(deepClone(data));
      setDraft(deepClone(data));
    } catch (e) {
      setError(e.message || "Failed to load config");
    } finally {
      setLoading(false);
    }
  }

  async function save() {
    setSaving(true);
    setError(null);
    try {
      await window.__adminSetPromptConfig(draft);
      setConfig(deepClone(draft));
      setSavedAt(new Date());
    } catch (e) {
      setError(e.message || "Failed to save config");
    } finally {
      setSaving(false);
    }
  }

  function setPrompt(value) {
    setDraft(d => ({ ...d, systemPromptTemplate: value }));
  }

  function setAgeField(age, field, value) {
    setDraft(d => ({
      ...d,
      ageGuidelines: {
        ...d.ageGuidelines,
        [age]: { ...d.ageGuidelines[age], [field]: value },
      },
    }));
  }

  const dirty = draft && config && isDirty(config, draft);

  return (
    <>
      <div className="page-header">
        <div>
          <h1>Prompt Configuration</h1>
          <div className="sub">
            Edit the GPT-4o system prompt and per-age vocabulary rules.
            Changes propagate to live story generation within <b>5 minutes</b>.
          </div>
        </div>
        <div className="actions" style={{ gap: 8 }}>
          {savedAt && !dirty && (
            <span className="badge green" style={{ marginRight: 4 }}>
              <Icon.check size={10}/> Saved {savedAt.toLocaleTimeString()}
            </span>
          )}
          {dirty && <span className="badge amber">Unsaved changes</span>}
          <button className="btn sm" onClick={load} disabled={loading || saving}>
            <Icon.rotate size={12}/> Reload
          </button>
          <button
            className="btn primary sm"
            onClick={save}
            disabled={saving || loading || !dirty}
          >
            {saving ? "Saving…" : <><Icon.check size={12}/> Save changes</>}
          </button>
        </div>
      </div>

      {error && (
        <div style={{
          background: "oklch(0.97 0.02 25)", border: "1px solid oklch(0.85 0.08 25)",
          borderRadius: 10, padding: "12px 16px", marginBottom: 20,
          color: "oklch(0.45 0.15 25)", fontSize: 13, display: "flex", gap: 8, alignItems: "center",
        }}>
          <Icon.x size={14}/> {error}
        </div>
      )}

      {loading && (
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "60px 0", justifyContent: "center", color: "var(--ink-4)" }}>
          <Icon.rotate size={18} style={{ animation: "spin 1s linear infinite" }}/>
          <span style={{ fontSize: 13 }}>Loading config from Firestore…</span>
        </div>
      )}

      {!loading && draft && (
        <>
          {/* System prompt */}
          <div className="card" style={{ marginBottom: 20 }}>
            <div className="card-header">
              <h3>System Prompt Template</h3>
              <div className="spacer"/>
              <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                <span style={{ fontSize: 11, color: "var(--ink-4)" }}>Substitution tokens:</span>
                <TokenBadge token="{{WORDS_PER_PAGE}}"/>
                <TokenBadge token="{{VOCAB_GUIDELINES}}"/>
              </div>
            </div>
            <div className="card-body">
              <div style={{ fontSize: 12, color: "var(--ink-3)", marginBottom: 10 }}>
                These tokens are replaced at runtime using the active age group's values below.
              </div>
              <textarea
                value={draft.systemPromptTemplate}
                onChange={e => setPrompt(e.target.value)}
                spellCheck={false}
                style={{
                  width: "100%", minHeight: 340,
                  padding: "12px 14px", borderRadius: 8,
                  border: "1px solid var(--border)", background: "var(--bg-elev)",
                  color: "var(--ink)", fontFamily: "var(--mono)", fontSize: 12.5,
                  lineHeight: 1.65, resize: "vertical", boxSizing: "border-box",
                  outline: "none",
                }}
              />
              <div style={{ marginTop: 8, display: "flex", justifyContent: "flex-end", gap: 12 }}>
                <span className="muted" style={{ fontSize: 11 }}>
                  {draft.systemPromptTemplate.length.toLocaleString()} chars ·{" "}
                  {draft.systemPromptTemplate.trim().split(/\s+/).filter(Boolean).length.toLocaleString()} words
                </span>
                <span className="muted" style={{ fontSize: 11 }}>
                  {(draft.systemPromptTemplate.match(/\{\{WORDS_PER_PAGE\}\}/g) || []).length} × <code style={{ fontFamily: "var(--mono)" }}>WORDS_PER_PAGE</code> ·{" "}
                  {(draft.systemPromptTemplate.match(/\{\{VOCAB_GUIDELINES\}\}/g) || []).length} × <code style={{ fontFamily: "var(--mono)" }}>VOCAB_GUIDELINES</code>
                </span>
              </div>
            </div>
          </div>

          {/* Age guidelines */}
          <div className="card">
            <div className="card-header">
              <h3>Age Guidelines</h3>
              <div className="spacer"/>
              <span style={{ fontSize: 11, color: "var(--ink-4)" }}>
                Injected into <TokenBadge token="{{WORDS_PER_PAGE}}"/> and <TokenBadge token="{{VOCAB_GUIDELINES}}"/>
              </span>
            </div>
            <div className="card-body" style={{ padding: 0 }}>
              <table className="tbl" style={{ tableLayout: "fixed" }}>
                <colgroup>
                  <col style={{ width: 80 }}/>
                  <col style={{ width: "30%" }}/>
                  <col/>
                </colgroup>
                <thead>
                  <tr>
                    <th>Age</th>
                    <th>Words per page <span className="muted" style={{ fontWeight: 400, fontSize: 11 }}>(→ WORDS_PER_PAGE)</span></th>
                    <th>Vocabulary style <span className="muted" style={{ fontWeight: 400, fontSize: 11 }}>(→ VOCAB_GUIDELINES)</span></th>
                  </tr>
                </thead>
                <tbody>
                  {AGE_GROUPS.map(age => {
                    const g = draft.ageGuidelines[age] || { words: "", vocab: "" };
                    return (
                      <tr key={age}>
                        <td>
                          <span style={{
                            display: "inline-flex", alignItems: "center", justifyContent: "center",
                            width: 44, height: 22, borderRadius: 6,
                            background: "var(--accent)", color: "white",
                            fontFamily: "var(--display)", fontWeight: 600, fontSize: 11,
                          }}>{age}</span>
                        </td>
                        <td style={{ padding: "8px 12px" }}>
                          <input
                            value={g.words}
                            onChange={e => setAgeField(age, "words", e.target.value)}
                            style={{
                              width: "100%", padding: "5px 9px", borderRadius: 6,
                              border: "1px solid var(--border)", background: "var(--bg-elev)",
                              color: "var(--ink)", fontFamily: "var(--mono)", fontSize: 12,
                              boxSizing: "border-box",
                            }}
                          />
                        </td>
                        <td style={{ padding: "8px 12px" }}>
                          <input
                            value={g.vocab}
                            onChange={e => setAgeField(age, "vocab", e.target.value)}
                            style={{
                              width: "100%", padding: "5px 9px", borderRadius: 6,
                              border: "1px solid var(--border)", background: "var(--bg-elev)",
                              color: "var(--ink)", fontSize: 12,
                              boxSizing: "border-box",
                            }}
                          />
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>

          {/* Bottom save bar (sticky when dirty) */}
          {dirty && (
            <div style={{
              position: "sticky", bottom: 20, marginTop: 20,
              background: "var(--bg-elev)", border: "1px solid var(--border)",
              borderRadius: 12, padding: "12px 16px", boxShadow: "0 4px 24px rgba(0,0,0,.12)",
              display: "flex", alignItems: "center", gap: 10,
            }}>
              <Icon.bell size={14} style={{ color: "var(--amber, oklch(0.72 0.18 80))" }}/>
              <span style={{ fontSize: 13, flex: 1 }}>You have unsaved changes.</span>
              <button className="btn sm" onClick={() => setDraft(deepClone(config))} disabled={saving}>
                Discard
              </button>
              <button className="btn primary sm" onClick={save} disabled={saving}>
                {saving ? "Saving…" : "Save changes"}
              </button>
            </div>
          )}
        </>
      )}
    </>
  );
}

window.PagePrompts = PagePrompts;
