/* Krytz · Live AI extraction widget
 *
 * Paste any text, call window.assistant.complete() with a strict JSON
 * extraction prompt, render the structured result. Falls back to a
 * deterministic local extractor if the API is unavailable.
 */

(function () {
  const { useState, useRef } = React;

  const PRESETS = [
    "Just got off the call with Asha. Need to send the revised proposal by Friday — they want pricing for 25 seats. Sam is blocked on the staging deploy bug, can't ship v2.3 until that's fixed. Q3 metrics review is moved to Thursday.",
    "Stand-up: Maya is shipping the onboarding redesign today. Ben needs API docs updated before Tuesday — he's flying out and won't be back until the 23rd. Pricing review still open — owner unclear.",
    "Voice memo from Lyft: Remember to follow up with the design contractor about the icon set. Also we need to interview at least two more senior eng candidates next week. The board update is due Monday morning.",
  ];

  function localFallback(text) {
    // dumb but deterministic — finds words, dates, "by X", etc.
    const items = [];
    const lower = text.toLowerCase();
    const dayMatch = lower.match(/\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|tomorrow|next week|tonight|today)\b/g) || [];
    const nameMatch = text.match(/\b[A-Z][a-z]{2,}\b/g) || [];
    const verbs = ['send', 'fix', 'ship', 'review', 'update', 'follow up', 'prep', 'interview', 'hire', 'deploy', 'call', 'email'];

    text.split(/[.!?\n]/).forEach((sentence) => {
      const s = sentence.trim();
      if (!s) return;
      const sl = s.toLowerCase();
      const verb = verbs.find((v) => sl.includes(v));
      const day = (sl.match(/\b(monday|tuesday|wednesday|thursday|friday|today|tomorrow)\b/) || [])[0];
      if (sl.includes('block') || sl.includes("can't") || sl.includes('cant')) {
        items.push({ type: 'blocker', title: s.slice(0, 80), meta: 'blocks downstream work' });
      } else if (day && verb) {
        items.push({ type: 'deadline', title: s.slice(0, 80), meta: `due ${day}` });
      } else if (verb) {
        items.push({ type: 'task', title: s.slice(0, 80), meta: 'add to queue' });
      }
    });

    // entities
    [...new Set(nameMatch)].slice(0, 4).forEach((name) => {
      items.push({ type: 'entity', title: name, meta: 'person mentioned' });
    });

    return {
      summary: items.length ? `Extracted ${items.length} structured items locally.` : 'No structured items found.',
      items,
    };
  }

  function ExtractionDemo() {
    const [input, setInput] = useState('');
    const [status, setStatus] = useState('idle'); // idle | loading | done | error
    const [result, setResult] = useState(null);
    const [error, setError] = useState(null);
    const abortRef = useRef(null);

    const run = async () => {
      if (!input.trim()) return;
      setStatus('loading');
      setError(null);
      setResult(null);

      const prompt = `You are Krytz, a personal clarity system. Extract structured items from the following text. Return ONLY a JSON object (no prose, no markdown fences) with this shape:

{
  "summary": "one short sentence describing what was captured",
  "items": [
    { "type": "task" | "deadline" | "blocker" | "event" | "entity", "title": "short clear title", "meta": "short meta (e.g. due Friday, blocks X, person, project name)" }
  ]
}

Rules:
- type "task": something the user must do
- type "deadline": a task with a specific time
- type "blocker": something preventing other work
- type "event": something that already happened or is scheduled (meeting, call)
- type "entity": a person, project, or organization mentioned
- 3-6 items max
- Titles under 70 chars, meta under 40 chars
- No markdown, no commentary, JSON only.

TEXT:
"""
${input}
"""`;

      try {
        if (!window.assistant || !window.assistant.complete) {
          throw new Error('local-fallback');
        }
        const raw = await window.assistant.complete(prompt);
        // strip code fences if any
        const cleaned = String(raw).trim()
          .replace(/^```(?:json)?\s*/i, '')
          .replace(/```$/, '')
          .trim();
        const parsed = JSON.parse(cleaned);
        if (!Array.isArray(parsed.items)) throw new Error('bad-shape');
        setResult(parsed);
        setStatus('done');
      } catch (err) {
        // graceful degrade
        const fb = localFallback(input);
        setResult(fb);
        setStatus('done');
        if (err.message !== 'local-fallback') {
          setError('API unavailable — fell back to local heuristic extractor.');
        }
      }
    };

    const reset = () => {
      setInput('');
      setResult(null);
      setStatus('idle');
      setError(null);
    };

    return (
      <div className="cx-grid">
        {/* INPUT */}
        <div className="cx-pane">
          <div className="cx-pane-head">
            <span><span className="dot"></span>Raw capture</span>
            <span>{input.length} chars</span>
          </div>
          <div className="cx-input-area">
            <textarea
              className="cx-input"
              placeholder="Paste a meeting note, voice memo, slack thread, or anything you'd write down. Krytz will extract tasks, deadlines, blockers, and entities."
              value={input}
              onChange={(e) => setInput(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) run();
              }}
            />
            <div className="cx-input-footer">
              <div className="cx-input-hint">
                <kbd>⌘</kbd> + <kbd>↵</kbd> to extract
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                {input && <button className="btn btn-secondary btn-sm" onClick={reset}>Clear</button>}
                <button
                  className="btn btn-primary btn-sm"
                  onClick={run}
                  disabled={!input.trim() || status === 'loading'}
                >
                  {status === 'loading' ? 'Extracting…' : 'Extract →'}
                </button>
              </div>
            </div>
          </div>
          <div className="cx-presets">
            <div className="cx-presets-label">Or try a sample</div>
            {PRESETS.map((p, i) => (
              <button key={i} className="cx-preset" onClick={() => { setInput(p); setResult(null); setStatus('idle'); }}>
                {p.slice(0, 90)}{p.length > 90 ? '…' : ''}
              </button>
            ))}
          </div>
        </div>

        {/* OUTPUT */}
        <div className="cx-pane">
          <div className={`cx-pane-head ${status === 'done' ? 'is-live' : ''}`}>
            <span><span className="dot"></span>Structured output</span>
            {result && <span><span className="v">{result.items.length}</span> items</span>}
          </div>
          <div className="cx-output">
            {status === 'idle' && (
              <div className="cx-empty">
                <div>◇ Awaiting capture</div>
                <div style={{ fontSize: 11, opacity: 0.7 }}>Paste text on the left, or pick a sample.</div>
              </div>
            )}

            {status === 'loading' && (
              <div className="cx-loading">
                <div style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--ink-3)', letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 8 }}>
                  ◇ Calling assistant · parsing JSON · validating shape
                </div>
                <div className="cx-loading-row"><div className="cx-loading-bar" /></div>
                <div className="cx-loading-row"><div className="cx-loading-bar" style={{ width: '70%' }} /></div>
                <div className="cx-loading-row"><div className="cx-loading-bar" style={{ width: '85%' }} /></div>
                <div className="cx-loading-row"><div className="cx-loading-bar" style={{ width: '60%' }} /></div>
              </div>
            )}

            {status === 'done' && result && (
              <>
                {result.summary && (
                  <div className="cx-summary">
                    <div className="lbl">Summary</div>
                    {result.summary}
                  </div>
                )}
                {error && <div className="cx-error">{error}</div>}
                {result.items.map((item, i) => (
                  <div key={i} className={`cx-item ${item.type}`} style={{ animationDelay: `${i * 60}ms` }}>
                    <div className="cx-item-head">
                      <span className="cx-item-badge">{item.type}</span>
                      <span className="cx-item-title">{item.title}</span>
                    </div>
                    {item.meta && <div className="cx-item-meta">↳ {item.meta}</div>}
                  </div>
                ))}
              </>
            )}
          </div>
        </div>
      </div>
    );
  }

  window.ExtractionDemo = ExtractionDemo;
})();
