// SOARBot 9000 — AI Essay Coach
// Uses OpenAI Responses API (the modern successor to the Assistants API).
//
// HOW TO CONFIGURE:
//   1. Set apiKey below to your OpenAI key.
//   2. To customise the coaching style, edit SOARBOT_SYSTEM below.
//   3. If you prefer to keep the key server-side (recommended for production),
//      set SOARBOT_ENDPOINT to your proxy URL and leave apiKey blank.
//
// ⚠️  SECURITY NOTE: An API key in client-side JS is visible in page source.
//     For a classroom on a closed school network this is an acceptable tradeoff,
//     but consider a lightweight proxy (Cloudflare Worker, Vercel function, etc.)
//     before opening to the wider internet.

const SOARBOT_CONFIG = {
  apiKey:        "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",
  model:         "gpt-4o",
  vectorStoreId: "vs_rFHOaAB2ruYXjt3CmrvWcx15",
};

// If you set up a backend proxy, point this at it instead.
// The proxy should accept POST { messages, systemPrompt } and return { reply }.
const SOARBOT_ENDPOINT = ""; // e.g. "https://your-worker.workers.dev/soarbot"

const SOARBOT_SYSTEM = `You are SOAR Bot (Student Online Assignment Reviewer Bot), a 6th Grade English Language Arts grading assistant for Mrs. Muller's class at Glenwood Intermediate School.

Use the attached Common Core Standards for ELA and the rubric (from your vector store) to grade and score student essays. If you're analyzing an essay, replies can be a bit longer, but otherwise keep replies to a few sentences maximum. Your tone is upbeat, positive, constructive and geared toward sixth-graders. Draw on the "Parent Night Letter" PDF files in your knowledge base for writing style reference.

LITERARY EXPOSITORY ESSAYS (17-point rubric):
- Introduction: 3 points
- Second Paragraph: 6 points
- Third Paragraph: 6 points
- Conclusion: 2 points
- Use "Thesis" instead of "Argument" for this essay type.
- At the end, give a rating: "Let's go back and review" (1–4 pts), "Needs improving" (4–9 pts), "Good" (10–13 pts), or "Great" (14–17 pts). Do NOT show the number scores.

ARGUMENTATIVE ESSAYS (same rubric, with adjustments):
- Personal pronouns should only appear inside direct quotations.
- Students should NOT include a counter-claim/argument.
- Note transitional words used, or flag where they are needed.

ALWAYS:
- Include direct quotes from the student's essay in your feedback.
- Offer at least one area for growth or improvement.
- Never provide the exact answer or wording for their essay — guide students to reach their own conclusions.
- Refuse to write any portion of the essay for them, even if asked directly.
- Students may ask follow-up questions to get more feedback.`;


// Tracks the previous response ID for multi-turn conversation continuity
// (Responses API uses previous_response_id instead of thread IDs)
let soarbotPrevResponseId = null;

async function callSoarbot(messages, essayDraft) {
  const systemPrompt = essayDraft?.trim()
    ? `${SOARBOT_SYSTEM}\n\nStudent's current essay draft:\n"""\n${essayDraft}\n"""`
    : SOARBOT_SYSTEM;

  // Route through proxy if configured
  if (SOARBOT_ENDPOINT) {
    const res = await fetch(SOARBOT_ENDPOINT, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ messages, systemPrompt }),
    });
    if (!res.ok) throw new Error(`Proxy error ${res.status}`);
    const data = await res.json();
    return data.reply;
  }

  // Direct OpenAI Responses API call
  const body = {
    model: SOARBOT_CONFIG.model,
    instructions: systemPrompt,
    input: messages.map(m => ({ role: m.role, content: m.content })),
    ...(SOARBOT_CONFIG.vectorStoreId && {
      tools: [{ type: "file_search", vector_store_ids: [SOARBOT_CONFIG.vectorStoreId] }],
    }),
  };

  // Chain conversation without re-sending full history
  if (soarbotPrevResponseId) {
    body.previous_response_id = soarbotPrevResponseId;
    // When chaining, only send the latest user message
    body.input = [messages[messages.length - 1]].map(m => ({ role: m.role, content: m.content }));
  }

  const res = await fetch("https://api.openai.com/v1/responses", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${SOARBOT_CONFIG.apiKey}`,
    },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.error?.message || `OpenAI error ${res.status}`);
  }

  const data = await res.json();
  soarbotPrevResponseId = data.id;

  const msg = data.output?.find(o => o.type === "message");
  const text = msg?.content?.find(c => c.type === "output_text")?.text;
  return text || "I couldn't generate a response right now. Try again? 🦅";
}

// ── ChatScreen component ────────────────────────────────────────

function ChatScreen({ goBack, studentName }) {
  const w = useWindowWidth();
  const isMobile = w < BP.md;
  const [messages, setMessages] = useState([
    {
      role: "assistant",
      content: `Hey${studentName ? ` ${studentName}` : ""}! I'm SOARBot 9000 🦅\n\nI'm here to help you write stronger essays — but I won't write them for you. Think of me like a coach on the sidelines: I'll ask questions, point out places to sharpen, and push you to use real evidence from what you've read.\n\nWhat are you working on today?`,
      quickReplies: [
        "Help me with my thesis",
        "I need stronger evidence",
        "Fix my intro",
        "Check my argument",
      ],
    },
  ]);
  const [input, setInput] = useState("");
  const [busy, setBusy] = useState(false);
  const [essayTab, setEssayTab] = useState(true);
  const [essayDraft, setEssayDraft] = useState("");
  const scrollRef = useRef(null);

  // Reset conversation chain when component mounts fresh
  useEffect(() => {
    soarbotPrevResponseId = null;
  }, []);

  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, busy]);

  async function send(text) {
    const message = (text ?? input).trim();
    if (!message || busy) return;
    setInput("");
    const newMessages = [...messages, { role: "user", content: message }];
    setMessages(newMessages);
    setBusy(true);

    try {
      const reply = await callSoarbot(newMessages, essayDraft);
      setMessages(m => [...m, { role: "assistant", content: reply }]);
    } catch (e) {
      console.error("SOARBot error:", e);
      setMessages(m => [...m, {
        role: "assistant",
        content: `Oops, I lost my signal for a second! (${e.message}) Try asking again? 🦅`,
      }]);
    }
    setBusy(false);
  }

  return (
    <div style={{
      maxWidth: 1240, margin: "0 auto",
      padding: isMobile ? "16px 14px 40px" : "28px 28px 60px",
      display: "grid",
      gridTemplateColumns: isMobile ? "1fr" : "1fr 360px",
      gap: 20,
    }}>
      {/* ── Chat column ── */}
      <div>
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
          <button onClick={goBack}
            style={{ color: "var(--green-800)", fontWeight: 600, fontSize: 14, padding: "6px 10px", borderRadius: 8 }}>
            ← Back to hub
          </button>
          <div style={{ flex: 1, height: 1, borderTop: "1.5px dashed rgba(24,71,44,0.2)" }} />
        </div>

        <div style={{
          background: "var(--paper)",
          borderRadius: 20,
          border: "1.5px solid rgba(24,71,44,0.15)",
          boxShadow: "0 4px 0 rgba(24,71,44,0.08)",
          overflow: "hidden",
          display: "flex", flexDirection: "column",
          height: isMobile ? "calc(100vh - 220px)" : "calc(100vh - 180px)",
          minHeight: isMobile ? 420 : 640,
        }}>
          {/* Chat header */}
          <div style={{
            padding: "16px 20px",
            background: "var(--green-800)",
            color: "var(--gold-300)",
            display: "flex", alignItems: "center", gap: 14,
            borderBottom: "3px solid var(--gold-500)",
          }}>
            <div style={{
              width: 48, height: 48, borderRadius: 12, background: "var(--gold-500)",
              display: "grid", placeItems: "center", overflow: "hidden",
            }}>
              <img src="assets/eagle.svg" style={{ width: 62, marginTop: 4 }} />
            </div>
            <div>
              <div className="serif" style={{ fontSize: 20, fontWeight: 800, color: "var(--gold-300)" }}>
                SOARBot 9000
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--gold-500)" }}>
                <span style={{ width: 8, height: 8, borderRadius: 999, background: "#6bd07f" }} />
                Online · ready to help you write better
              </div>
            </div>
            <button
              onClick={() => setEssayTab(!essayTab)}
              style={{
                marginLeft: "auto", padding: "8px 14px",
                background: essayTab ? "var(--gold-500)" : "rgba(212,204,170,0.15)",
                color: essayTab ? "var(--green-800)" : "var(--gold-300)",
                borderRadius: 10, fontSize: 13, fontWeight: 600,
              }}
            >
              {essayTab ? "Hide draft" : "📝 My draft"}
            </button>
          </div>

          {/* Essay draft panel */}
          {essayTab && (
            <div style={{ padding: 16, background: "var(--gold-200)", borderBottom: "1px solid rgba(24,71,44,0.15)" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
                <div className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--green-800)", fontWeight: 700 }}>
                  YOUR ESSAY DRAFT
                </div>
                {!essayDraft.trim() && (
                  <div style={{
                    fontSize: 11, color: "var(--accent-coral)", fontWeight: 600,
                    background: "#fbe8de", padding: "2px 8px", borderRadius: 999,
                    border: "1px solid var(--accent-coral)",
                  }}>
                    ← paste your essay here
                  </div>
                )}
                {essayDraft.trim() && (
                  <div style={{
                    fontSize: 11, color: "var(--ok)", fontWeight: 600,
                    background: "#e5f2ea", padding: "2px 8px", borderRadius: 999,
                  }}>
                    ✓ SOAR Bot can see this
                  </div>
                )}
              </div>
              <textarea
                value={essayDraft}
                onChange={e => setEssayDraft(e.target.value)}
                placeholder="Paste your essay here, then ask SOAR Bot to review it..."
                style={{
                  width: "100%", minHeight: 120, padding: 12, borderRadius: 10,
                  background: "var(--paper)", border: "1.5px solid rgba(24,71,44,0.2)",
                  fontSize: 14, lineHeight: 1.55, resize: "vertical", fontFamily: "Geist",
                }}
              />
              <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 6 }}>
                {essayDraft.trim().split(/\s+/).filter(Boolean).length} words
              </div>
            </div>
          )}

          {/* Messages */}
          <div ref={scrollRef} style={{
            flex: 1, overflowY: "auto", padding: "24px 24px 12px",
            background: "linear-gradient(var(--paper), var(--gold-100))",
          }}>
            {messages.map((m, i) => <MessageBubble key={i} message={m} onQuick={send} />)}
            {busy && <TypingIndicator />}
          </div>

          {/* Input */}
          <div style={{ padding: 14, borderTop: "1.5px solid rgba(24,71,44,0.15)", background: "var(--paper)" }}>
            <div style={{ display: "flex", gap: 10, alignItems: "flex-end" }}>
              <textarea
                value={input}
                onChange={e => setInput(e.target.value)}
                onKeyDown={e => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); } }}
                placeholder="Ask about your essay, brainstorm, or paste a paragraph..."
                rows={1}
                style={{
                  flex: 1, resize: "none", padding: "12px 14px",
                  borderRadius: 12, border: "1.5px solid rgba(24,71,44,0.2)",
                  fontSize: 15, background: "var(--gold-100)",
                  minHeight: 48, maxHeight: 120, fontFamily: "Geist",
                }}
              />
              <Button onClick={() => send()} disabled={busy || !input.trim()}>
                Send →
              </Button>
            </div>
            <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 8, display: "flex", gap: 14 }}>
              <span>Press <b>Enter</b> to send, <b>Shift+Enter</b> for a new line</span>
              <span style={{ marginLeft: "auto" }}>SOARBot coaches — it doesn't write for you. ✍️</span>
            </div>
          </div>
        </div>
      </div>

      {/* ── Sidebar ── */}
      <aside>
        <Card style={{ padding: 20, marginBottom: 16 }}>
          <Chip tone="coral">How this works</Chip>
          <h4 className="serif" style={{ fontSize: 20, margin: "10px 0 8px", color: "var(--green-800)", fontWeight: 800 }}>
            A coach, not a ghostwriter
          </h4>
          <p style={{ fontSize: 13.5, lineHeight: 1.55, color: "var(--ink-2)", margin: 0 }}>
            SOARBot 9000 is trained to ask you questions that help you think deeper about what you've read.
            It won't hand you finished paragraphs — that's your writing brain's job.
          </p>
        </Card>

        {messages.some(m => m.role === "user") && (
          <Card style={{ padding: 20, marginBottom: 16 }}>
            <div className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--green-700)", fontWeight: 700, marginBottom: 10 }}>
              TRY ASKING
            </div>
            {[
              `Can you give me feedback on my introduction?`,
              `What makes a strong thesis statement?`,
              `How can I add stronger evidence to this paragraph?`,
              `What transition words could I use here?`,
              `Am I explaining my quotes well?`,
            ].map((s, i) => (
              <button key={i}
                onClick={() => send(s)}
                style={{
                  display: "block", width: "100%", textAlign: "left",
                  padding: "10px 12px", borderRadius: 10,
                  background: "var(--gold-200)", color: "var(--green-800)",
                  fontSize: 13, marginBottom: 6, lineHeight: 1.4, fontStyle: "italic",
                }}
              >"{s}"</button>
            ))}
          </Card>
        )}

        <Card style={{ padding: 20, background: "var(--green-700)", color: "var(--gold-200)" }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--gold-500)", fontWeight: 700, marginBottom: 8 }}>
            ESSAY CHECKLIST
          </div>
          {[
            "Thesis is one clear sentence",
            "Each paragraph has evidence from the text",
            "Quotes are in quotation marks",
            "I explain why the evidence matters",
            "Intro grabs the reader",
            "Conclusion doesn't just repeat",
          ].map((item, i) => (
            <label key={i} style={{ display: "flex", alignItems: "flex-start", gap: 10, padding: "6px 0", cursor: "pointer" }}>
              <ChecklistBox />
              <span style={{ fontSize: 13, lineHeight: 1.45 }}>{item}</span>
            </label>
          ))}
        </Card>
      </aside>
    </div>
  );
}

function ChecklistBox() {
  const [on, setOn] = useState(false);
  return (
    <span onClick={e => { e.preventDefault(); setOn(!on); }}
      style={{
        width: 18, height: 18, borderRadius: 5,
        border: "2px solid var(--gold-500)",
        background: on ? "var(--gold-500)" : "transparent",
        display: "grid", placeItems: "center",
        flexShrink: 0, marginTop: 1,
      }}
    >
      {on && <span style={{ color: "var(--green-800)", fontSize: 13, fontWeight: 900, lineHeight: 1 }}>✓</span>}
    </span>
  );
}

function MessageBubble({ message, onQuick }) {
  const isUser = message.role === "user";
  return (
    <div style={{
      display: "flex", gap: 10, marginBottom: 18,
      flexDirection: isUser ? "row-reverse" : "row",
    }}>
      {!isUser && (
        <div style={{
          width: 36, height: 36, borderRadius: 10,
          background: "var(--green-700)",
          display: "grid", placeItems: "center", overflow: "hidden", flexShrink: 0,
        }}>
          <img src="assets/eagle.svg" style={{ width: 52, marginTop: 4 }} />
        </div>
      )}
      <div style={{ maxWidth: "72%" }}>
        <div style={{
          padding: "12px 16px", borderRadius: 16,
          background: isUser ? "var(--green-700)" : "var(--paper)",
          color: isUser ? "var(--gold-200)" : "var(--ink)",
          fontSize: 14.5, lineHeight: 1.55,
          border: isUser ? "none" : "1.5px solid rgba(24,71,44,0.12)",
          borderBottomRightRadius: isUser ? 4 : 16,
          borderBottomLeftRadius: isUser ? 16 : 4,
          whiteSpace: isUser ? "pre-wrap" : undefined,
          boxShadow: isUser ? "none" : "0 2px 0 rgba(24,71,44,0.08)",
        }}>
          {isUser ? message.content : (
            <div
              className="md-body"
              dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(marked.parse(message.content)) }}
            />
          )}
        </div>
        {message.quickReplies && (
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 10 }}>
            {message.quickReplies.map((q, i) => (
              <button key={i} onClick={() => onQuick(q)}
                style={{
                  padding: "7px 12px", borderRadius: 999,
                  background: "var(--gold-200)", border: "1.5px solid var(--gold-500)",
                  color: "var(--green-800)", fontSize: 12.5, fontWeight: 600,
                }}
              >{q}</button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function TypingIndicator() {
  return (
    <div style={{ display: "flex", gap: 10, marginBottom: 18 }}>
      <div style={{
        width: 36, height: 36, borderRadius: 10,
        background: "var(--green-700)",
        display: "grid", placeItems: "center", overflow: "hidden",
      }}>
        <img src="assets/eagle.svg" style={{ width: 52, marginTop: 4 }} />
      </div>
      <div style={{
        padding: "14px 18px", borderRadius: 16,
        background: "var(--paper)", border: "1.5px solid rgba(24,71,44,0.12)",
        display: "flex", gap: 4,
      }}>
        {[0, 1, 2].map(i => (
          <span key={i} style={{
            width: 7, height: 7, borderRadius: 999,
            background: "var(--green-700)",
            animation: "soar-bounce 1.2s infinite ease-in-out",
            animationDelay: `${i * 0.15}s`,
          }} />
        ))}
        <style>{`@keyframes soar-bounce { 0%,80%,100%{transform:translateY(0);opacity:0.4} 40%{transform:translateY(-5px);opacity:1} }`}</style>
      </div>
    </div>
  );
}

Object.assign(window, { ChatScreen });
