/* MY GENIE — Agent workspace (#/agent) (v1)
 *
 * A full-page agentic chat — bigger than the floating Geni panel, and wired
 * for ACTION, not just answers. The loop:
 *   1. The user says something happened ("I advanced the UI work").
 *   2. The model (same Gemini chain as the panel) plans against the live
 *      WORKSPACE CONTEXT and answers with a strict JSON plan:
 *      {"message": "...", "actions": [ ... ]}.
 *   3. window.MYGENI_AGENT.execute() applies each action to the mock data —
 *      ticking mission checklist items, moving status/approval, recomputing
 *      progress, filing progress reports — and returns receipts.
 *   4. The receipts render right under the agent's reply, and a toast
 *      mirrors each mutation. Stage/mission pages reflect the change on
 *      their next render.
 *
 * The model is instructed to: tick matching items when the user reports
 * progress, then ASK for a short report; when the report text arrives,
 * file it with file_report into the right mission.
 */
function AgentWorkspace({ data }) {
  const LS_THREAD = 'mygeni:agent:thread';

  const WELCOME = {
    role: 'ai',
    text: 'I am your Agent. Tell me what you did — "I moved the UI work forward in Stage 3" — and I will tick the checklist, then ask you for a short report and file it in the right mission.',
    receipts: [],
  };

  const [messages, setMessages] = React.useState(() => {
    try {
      const saved = JSON.parse(localStorage.getItem(LS_THREAD) || 'null');
      if (Array.isArray(saved) && saved.length) return saved;
    } catch (e) {}
    return [WELCOME];
  });
  const [input, setInput] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const scrollRef = React.useRef(null);

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

  function persist(next) {
    try { localStorage.setItem(LS_THREAD, JSON.stringify(next.slice(-40))); } catch (e) {}
  }

  function systemPrompt() {
    const ctx = (window.MYGENI_AGENT && window.MYGENI_AGENT.context) ? window.MYGENI_AGENT.context() : '{}';
    return [
      'You are Geni Agent, the hands-on operator inside "My genie" — a Product Operating System.',
      'You do not just answer: you CHANGE the workspace. Every reply must be a single JSON object, no markdown fences, no text outside it:',
      '{"message": "<what you did or what you need next>", "actions": [ ... ]}',
      '',
      'ACTIONS:',
      '{"type":"tick_mission_item","stage":<stage n>,"mission":"<mission key|id|title>","item":"<checklist id or exact text fragment>","done":true|false}',
      '{"type":"set_mission_status","stage":<n>,"mission":"...","status":"todo|in-progress|review|done"}',
      '{"type":"set_mission_approval","stage":<n>,"mission":"...","approval":"approved|pending|rejected"}',
      '{"type":"update_progress","stage":<n>,"mission":"...","progress":<0-100>}',
      '{"type":"file_report","stage":<n>,"mission":"...","title":"<short title>","text":"<the report text>"}',
      '{"type":"append_note","stage":<n>,"mission":"...","text":"..."}',
      '',
      'BEHAVIOUR:',
      '- When the user reports progress ("I advanced the UI", "the scope sign-off happened"), resolve it against WORKSPACE CONTEXT and tick the matching checklist item(s). Then ask the user for a short progress report (what was done, what is next, any blockers).',
      '- When the user then supplies that report, file it with file_report into the right mission and confirm where it landed. Add the user\'s exact wording, lightly cleaned.',
      '- Resolve stage/mission/item references ONLY from WORKSPACE CONTEXT below. If a reference does not exist, say so and list the closest matches — never invent items.',
      '- Keep "message" short (1–3 sentences), plain text, in the SAME LANGUAGE the user writes in.',
      '- Do not emit an action unless the user actually asked for that change or confirmed it.',
      '',
      'WORKSPACE CONTEXT (JSON): ' + ctx,
    ].join('\n');
  }

  // The model may wrap the JSON in prose or fences; be forgiving.
  function parsePlan(text) {
    const raw = String(text || '');
    let body = raw.replace(/```json|```/gi, '').trim();
    const a = body.indexOf('{');
    const b = body.lastIndexOf('}');
    if (a === -1 || b === -1 || b <= a) return { message: raw.trim(), actions: [] };
    try {
      const plan = JSON.parse(body.slice(a, b + 1));
      return {
        message: String(plan.message || '').trim() || raw.trim(),
        actions: Array.isArray(plan.actions) ? plan.actions : [],
      };
    } catch (e) {
      return { message: raw.trim(), actions: [] };
    }
  }

  function send(promptText) {
    const p = String(promptText != null ? promptText : input).trim();
    if (!p || busy) return;
    setInput('');

    const userMsg = { role: 'user', text: p, receipts: [] };
    const history = messages.filter(m => !m.error).map(m => ({ role: m.role, text: m.text }));
    setMessages(m => [...m, userMsg]);
    setBusy(true);

    window.MYGENI_LLM.chat({
      prompt: p,
      history: history,
      system: systemPrompt(),
      temperature: 0.2,
      // Agent turns carry the workspace context and plan JSON — allow a
      // longer budget than the panel's 30s on slow links.
      timeoutMs: 60000,
    }).then(r => {
      const plan = parsePlan(r.text);
      const receipts = (plan.actions.length && window.MYGENI_AGENT)
        ? window.MYGENI_AGENT.run(plan.actions)
        : [];
      const aiMsg = { role: 'ai', text: plan.message, receipts: receipts };
      setMessages(m => { const next = [...m, aiMsg]; persist(next); return next; });
    }).catch(e => {
      const aiMsg = { role: 'ai', error: true, text: 'The model call failed: ' + String(e && e.message || e) + ' — your message is kept, try again.', receipts: [] };
      setMessages(m => { const next = [...m, aiMsg]; persist(next); return next; });
    }).then(() => setBusy(false));
  }

  function reset() {
    setMessages([WELCOME]);
    persist([WELCOME]);
  }

  function receiptTone(ok) { return ok ? 'agw-receipt ok' : 'agw-receipt bad'; }

  const suggestions = [
    'UI رو از Stage 3 پیش بردم — تیکش بزن',
    'Scope sign-off from Alireza is done',
    'گزارش پیشرفت: طراحی صفحات decisions تمام شد، جستجو ۷۰٪ است',
  ];

  const lastReceipts = [];
  messages.forEach(m => { (m.receipts || []).forEach(r => lastReceipts.push(r)); });

  return (
    <main className="main agw-main" data-screen-label="Agent">
      <div className="agw-header">
        <div>
          <h1 className="greeting">Agent</h1>
          <div className="date-line">
            Delegate real work: the agent ticks checklists, files reports, and updates missions · <span className="mono">operates on MH Portal</span>
          </div>
        </div>
        <button className="agw-reset" onClick={reset} title="Clear the agent thread">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path d="M4 4v6h6M20 20v-6h-6" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
            <path d="M20 9a8 8 0 00-14.9-3M4 15a8 8 0 0014.9 3" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
          </svg>
          <span>Reset</span>
        </button>
      </div>

      <div className="agw-grid">
        <div className="agw-chat">
          <div className="agw-thread" ref={scrollRef}>
            {messages.map((m, i) => (
              <div key={i} className={'agw-msg ' + (m.role === 'user' ? 'me' : 'ai') + (m.error ? ' err' : '')}>
                <div className="agw-msg-text">{m.text}</div>
                {(m.receipts || []).length > 0 && (
                  <div className="agw-msg-receipts">
                    {m.receipts.map((r, j) => (
                      <div key={j} className={receiptTone(r.ok)}>
                        <span className="agw-receipt-label">{r.ok ? '✓' : '✕'} {r.label}</span>
                        <span className="agw-receipt-detail">{r.detail}</span>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            ))}
            {busy && (
              <div className="agw-msg ai">
                <div className="agw-msg-text agw-busy">Working — reading the workspace and planning actions…</div>
              </div>
            )}
          </div>

          <div className="agw-suggestions">
            {suggestions.map((s, i) => (
              <button key={i} className="agw-suggestion" onClick={() => send(s)}>{s}</button>
            ))}
          </div>

          <div className="agw-composer">
            <input
              className="agw-input"
              placeholder="Tell the agent what you did, or paste your report…"
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter') send(); }}
              autoFocus
            />
            <button className="agw-send" onClick={() => send()} disabled={busy || !input.trim()} aria-label="Send">
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                <path d="M4 12h15M13 5.5L19.5 12 13 18.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
          </div>
        </div>

        <aside className="agw-side">
          <div className="agw-side-title">Session log</div>
          {lastReceipts.length === 0 && (
            <div className="agw-side-empty">Actions the agent takes appear here — ticks, status moves, filed reports.</div>
          )}
          {lastReceipts.slice().reverse().slice(0, 14).map((r, i) => (
            <div key={i} className={receiptTone(r.ok)}>
              <span className="agw-receipt-label">{r.ok ? '✓' : '✕'} {r.label}</span>
              <span className="agw-receipt-detail">{r.detail}</span>
            </div>
          ))}

          <div className="agw-side-title" style={{ marginTop: 18 }}>Where reports land</div>
          <div className="agw-side-empty">
            Filed reports are stored on their mission and appear in the mission drawer's <b>Notes</b> tab
            (Projects → MH Portal → Stage → mission) — plus here in the session log.
          </div>
        </aside>
      </div>
    </main>
  );
}

Object.assign(window, { AgentWorkspace });
