/* ===========================================================================
   iRaven App Store Studio — AI wizard.
   Step 1: chat with an AI marketing strategist about the product.
   Step 2: one more prompt extracts concepts (brand, headlines, video copy)
           as strict JSON → user approves or edits → project is created.
   Providers: window.claude.complete (in-preview) or MiniMax via key
   (direct or through the Docker backend proxy /api/ai).
   =========================================================================== */

const AI_CFG_KEY = 'iraven_ai_cfg';

function aiCfg() {
  try { return JSON.parse(localStorage.getItem(AI_CFG_KEY) || '{}'); } catch (e) { return {}; }
}

async function aiComplete(messages) {
  const cfg = aiCfg();
  /* Docker backend present → always proxy through it. The server falls back to
     the MINIMAX_API_KEY in .env when the user hasn't typed a key in settings,
     so the env key "just works" without re-entering it. */
  if (window.__hasBackend) {
    try {
      const r = await fetch('/api/ai', { method: 'POST', headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ model: cfg.model || 'MiniMax-M3', messages, key: cfg.key, baseUrl: cfg.baseUrl }) });
      const j = await r.json();
      if (j.error) throw new Error(typeof j.error === 'string' ? j.error : JSON.stringify(j.error));
      return j.text || '';
    } catch (e) {
      if (window.claude && window.claude.complete) return await window.claude.complete({ messages });
      throw e;
    }
  }
  if (cfg.key) {
    const payload = { model: cfg.model || 'MiniMax-M3', messages };
    const r = await fetch((cfg.baseUrl || 'https://api.minimax.io/v1') + '/chat/completions', {
      method: 'POST',
      headers: { 'content-type': 'application/json', authorization: 'Bearer ' + cfg.key },
      body: JSON.stringify(payload),
    });
    const j = await r.json();
    const c = j.choices && j.choices[0];
    if (!c) throw new Error((j.error && (j.error.message || JSON.stringify(j.error))) || 'AI request failed');
    return (c.message && c.message.content) || '';
  }
  if (window.claude && window.claude.complete) {
    return await window.claude.complete({ messages });
  }
  throw new Error('No AI configured — open settings (⚙) and add your MiniMax API key.');
}

const AI_CHAT_SYSTEM = `You are a senior App Store marketing strategist inside "iRaven App Store Studio".
The user wants to market a mobile app on the App Store. Interview them, 1-2 focused questions at a time:
app name · what it does · target users · top 4-8 features · tone of voice · brand colors (if any).
Keep every reply under 110 words. Be concrete, never generic. When you have enough material,
say: "I'm ready — press Generate concepts."`;

function aiGenPrompt(transcript) {
  return `Based on this product interview, write App Store marketing concepts.

INTERVIEW:
${transcript}

Return ONLY valid JSON, no markdown, exactly this shape:
{"name":"AppName","tagline":"max 6 words","accent1":"#hex","accent2":"#hex",
"screens":[8 items: {"headline":"2-4 punchy words, may contain \\n once","subtitle":"max 9 words"}],
"videos":[2 items: {"headline":"2-3 words, may contain \\n once","subtitle":"max 8 words"}]}
Headlines must each highlight a DIFFERENT feature/benefit from the interview. accent1/accent2 are brand-fitting, vivid, distinct.`;
}

function aiParseConcepts(text) {
  const a = text.indexOf('{');
  if (a === -1) throw new Error('no JSON found');
  let depth = 0, inStr = false, esc = false, slice = null;
  for (let i = a; i < text.length; i++) {
    const ch = text[i];
    if (inStr) { if (esc) esc = false; else if (ch === '\\') esc = true; else if (ch === '"') inStr = false; continue; }
    if (ch === '"') inStr = true;
    else if (ch === '{') depth++;
    else if (ch === '}') { depth--; if (depth === 0) { slice = text.slice(a, i + 1); break; } }
  }
  if (!slice) throw new Error('no complete JSON found');
  const j = JSON.parse(slice);
  if (!j.screens || !j.screens.length) throw new Error('no screens in JSON');
  j.screens = j.screens.slice(0, 10);
  j.videos = (j.videos || []).slice(0, 3);
  return j;
}

/* ---------- UI ---------- */
function AISettings({ onClose }) {
  const [cfg, setCfg] = useState(aiCfg());
  const save = () => { localStorage.setItem(AI_CFG_KEY, JSON.stringify(cfg)); onClose(); };
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 1200, background: 'rgba(3,5,14,0.8)',
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div onClick={e => e.stopPropagation()} style={{ width: 'min(440px, 92vw)', borderRadius: 16,
        background: '#0c1222', border: '1px solid rgba(255,255,255,0.12)', padding: 22 }}>
        <div style={{ fontFamily: DISPLAY, fontWeight: 600, fontSize: 17, color: '#fff', marginBottom: 6 }}>AI provider</div>
        <p style={{ margin: '0 0 14px', fontSize: 12.5, color: 'rgba(255,255,255,0.5)', fontFamily: BODY }}>
          On Docker the <b>MINIMAX_API_KEY</b> from your .env is used automatically — leave this blank.
          In the preview, blank = built-in assistant. Set a key here only to override.
        </p>
        <Field label="MiniMax API key" value={cfg.key || ''} placeholder="sk-…"
          onChange={v => setCfg({ ...cfg, key: v })} />
        <Field label="Model" value={cfg.model || ''} placeholder="MiniMax-M3"
          onChange={v => setCfg({ ...cfg, model: v })} />
        <Field label="Base URL" value={cfg.baseUrl || ''} placeholder="https://api.minimax.io/v1"
          onChange={v => setCfg({ ...cfg, baseUrl: v })} />
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 6 }}>
          <button style={btnStyle()} onClick={onClose}>Cancel</button>
          <button style={btnStyle({ background: 'linear-gradient(180deg,#3b78ff,#1f54d6)', border: '1px solid #3b78ff' })}
            onClick={save}>Save</button>
        </div>
      </div>
    </div>
  );
}

function AIWizard({ onCreate, onCancel }) {
  const [step, setStep] = useState('chat');
  const [msgs, setMsgs] = useState([
    { role: 'assistant', content: 'Hi! I\'ll help you craft App Store marketing for your app. What\'s the app called, and what does it do?' },
  ]);
  const [input, setInput] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const [showCfg, setShowCfg] = useState(false);
  const [concepts, setConcepts] = useState(null);
  const scrollRef = useRef(null);

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

  const send = async () => {
    const text = input.trim();
    if (!text || busy) return;
    setInput('');
    setErr(null);
    const next = [...msgs, { role: 'user', content: text }];
    setMsgs(next);
    setBusy(true);
    try {
      const reply = await aiComplete([
        { role: 'user', content: AI_CHAT_SYSTEM + '\n\n(The conversation starts now.)' },
        ...next,
      ]);
      setMsgs([...next, { role: 'assistant', content: reply }]);
    } catch (e) { setErr(String(e.message || e)); }
    setBusy(false);
  };

  const generate = async () => {
    if (busy) return;
    setErr(null);
    setBusy(true);
    try {
      const transcript = msgs.map(m => (m.role === 'user' ? 'USER: ' : 'STRATEGIST: ') + m.content).join('\n');
      const out = await aiComplete([{ role: 'user', content: aiGenPrompt(transcript) }]);
      setConcepts(aiParseConcepts(out));
      setStep('review');
    } catch (e) { setErr('Generation failed: ' + String(e.message || e)); }
    setBusy(false);
  };

  const userTurns = msgs.filter(m => m.role === 'user').length;

  if (step === 'review' && concepts) {
    return <AIReview concepts={concepts} setConcepts={setConcepts} busy={busy}
      onBack={() => setStep('chat')} onRegenerate={generate}
      onApprove={() => onCreate(concepts)} />;
  }

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 1100, background: '#070a14', display: 'flex',
      flexDirection: 'column', fontFamily: BODY }}>
      <header style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '0 22px', height: 60, borderBottom: '1px solid rgba(255,255,255,0.08)', flex: '0 0 auto' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button style={btnStyle({ padding: '6px 12px' })} onClick={onCancel}>←</button>
          <span style={{ fontFamily: DISPLAY, fontWeight: 600, fontSize: 17, color: '#fff' }}>New app · AI wizard</span>
        </div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <button title="AI settings" style={btnStyle({ padding: '8px 12px' })} onClick={() => setShowCfg(true)}>⚙</button>
          <button disabled={userTurns < 1 || busy}
            style={btnStyle({ background: 'linear-gradient(180deg,#3b78ff,#1f54d6)', border: '1px solid #3b78ff',
              opacity: userTurns < 1 || busy ? 0.5 : 1 })}
            onClick={generate}>Generate concepts →</button>
        </div>
      </header>

      <div ref={scrollRef} style={{ flex: 1, overflowY: 'auto', padding: '26px 0' }}>
        <div style={{ maxWidth: 680, margin: '0 auto', padding: '0 20px', display: 'flex',
          flexDirection: 'column', gap: 14 }}>
          {msgs.map((m, i) => (
            <div key={i} style={{ alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
              maxWidth: '85%', padding: '11px 15px', borderRadius: 14, fontSize: 14, lineHeight: 1.5,
              whiteSpace: 'pre-wrap', color: '#fff',
              background: m.role === 'user' ? 'linear-gradient(180deg,#2f63d8,#1f4ab0)' : 'rgba(255,255,255,0.06)',
              border: m.role === 'user' ? 'none' : '1px solid rgba(255,255,255,0.09)' }}>
              {m.content}
            </div>
          ))}
          {busy ? (
            <div style={{ alignSelf: 'flex-start', padding: '11px 15px', borderRadius: 14,
              background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.09)',
              color: 'rgba(255,255,255,0.5)', fontSize: 14 }}>thinking…</div>
          ) : null}
          {err ? (
            <div style={{ alignSelf: 'stretch', padding: '10px 14px', borderRadius: 12, fontSize: 13,
              background: 'rgba(255,59,70,0.12)', border: '1px solid rgba(255,59,70,0.35)', color: '#ff9ba1' }}>
              {err}
            </div>
          ) : null}
        </div>
      </div>

      <div style={{ flex: '0 0 auto', borderTop: '1px solid rgba(255,255,255,0.08)', padding: 16 }}>
        <div style={{ maxWidth: 680, margin: '0 auto', display: 'flex', gap: 10 }}>
          <textarea rows={2} value={input} placeholder="Tell the strategist about your app…"
            onChange={e => setInput(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
            style={{ flex: 1, resize: 'none', padding: '11px 14px', borderRadius: 12,
              background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.12)',
              color: '#fff', fontFamily: BODY, fontSize: 14, outline: 'none' }} />
          <button style={btnStyle({ background: 'linear-gradient(180deg,#3b78ff,#1f54d6)',
            border: '1px solid #3b78ff', alignSelf: 'stretch', opacity: busy ? 0.5 : 1 })}
            onClick={send} disabled={busy}>Send</button>
        </div>
      </div>

      {showCfg ? <AISettings onClose={() => setShowCfg(false)} /> : null}
    </div>
  );
}

/* ---------- review & approve ---------- */
function AIReview({ concepts, setConcepts, onBack, onRegenerate, onApprove, busy }) {
  const c = concepts;
  const patch = (ch) => setConcepts({ ...c, ...ch });
  const patchScreen = (i, ch) => patch({ screens: c.screens.map((s, k) => k === i ? { ...s, ...ch } : s) });
  const patchVideo = (i, ch) => patch({ videos: c.videos.map((s, k) => k === i ? { ...s, ...ch } : s) });

  const colorField = (key) => (
    <label style={{ display: 'flex', alignItems: 'center', gap: 8, flex: 1 }}>
      <span style={{ width: 26, height: 26, borderRadius: 8, background: c[key] || '#888',
        border: '1px solid rgba(255,255,255,0.25)', flex: '0 0 auto' }} />
      <input value={c[key] || ''} onChange={e => patch({ [key]: e.target.value })}
        style={{ width: '100%', padding: '8px 10px', borderRadius: 9, background: 'rgba(255,255,255,0.04)',
          border: '1px solid rgba(255,255,255,0.10)', color: '#fff', fontFamily: "'JetBrains Mono',monospace",
          fontSize: 12.5, outline: 'none' }} />
    </label>
  );

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 1100, background: '#070a14', display: 'flex',
      flexDirection: 'column', fontFamily: BODY }}>
      <header style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '0 22px', height: 60, borderBottom: '1px solid rgba(255,255,255,0.08)', flex: '0 0 auto' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button style={btnStyle({ padding: '6px 12px' })} onClick={onBack}>← chat</button>
          <span style={{ fontFamily: DISPLAY, fontWeight: 600, fontSize: 17, color: '#fff' }}>Review concepts</span>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button style={btnStyle({ opacity: busy ? 0.5 : 1 })} onClick={onRegenerate} disabled={busy}>
            {busy ? 'Generating…' : '↻ Regenerate'}</button>
          <button style={btnStyle({ background: 'linear-gradient(180deg,#22a45c,#157a41)', border: '1px solid #22a45c' })}
            onClick={onApprove}>✓ Approve & create</button>
        </div>
      </header>

      <div style={{ flex: 1, overflowY: 'auto', padding: '26px 0' }}>
        <div style={{ maxWidth: 880, margin: '0 auto', padding: '0 22px' }}>
          <Section title="Brand">
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <Field label="App name" value={c.name || ''} onChange={v => patch({ name: v })} />
              <Field label="Tagline" value={c.tagline || ''} onChange={v => patch({ tagline: v })} />
            </div>
            <div style={{ display: 'flex', gap: 12 }}>
              {colorField('accent1')}
              {colorField('accent2')}
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 12 }}>
              {c.logo ? (
                <img src={c.logo} style={{ height: 44, maxWidth: 140, objectFit: 'contain', borderRadius: 8,
                  background: 'rgba(255,255,255,0.06)', padding: 5, flex: '0 0 auto' }} />
              ) : null}
              <div style={{ flex: 1 }}>
                <DropZone compact accept="image/*" sub="PNG / SVG · used in the video outro"
                  title={c.logo ? 'App logo · replace' : 'App logo · drop image (optional)'}
                  hasImage={!!c.logo}
                  onFile={f => { if (!f) return; const r = new FileReader();
                    r.onload = () => patch({ logo: r.result }); r.readAsDataURL(f); }} />
              </div>
              {c.logo ? (
                <button style={btnStyle({ padding: '7px 10px', fontSize: 12, color: '#ff8089', flex: '0 0 auto' })}
                  onClick={() => patch({ logo: null })}>Remove</button>
              ) : null}
            </div>
          </Section>

          <Section title={`Screenshots · ${c.screens.length}`} hint="edit freely">
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px,1fr))', gap: 12 }}>
              {c.screens.map((s, i) => (
                <div key={i} style={{ borderRadius: 14, border: '1px solid rgba(255,255,255,0.10)',
                  background: 'rgba(255,255,255,0.03)', padding: 14 }}>
                  <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10.5, color: 'rgba(255,255,255,0.4)',
                    marginBottom: 8 }}>{String(i + 1).padStart(2, '0')}</div>
                  <textarea rows={2} value={s.headline || ''} onChange={e => patchScreen(i, { headline: e.target.value })}
                    style={{ width: '100%', boxSizing: 'border-box', resize: 'none', marginBottom: 6, padding: '8px 10px',
                      borderRadius: 9, background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.10)',
                      color: '#fff', fontFamily: DISPLAY, fontWeight: 600, fontSize: 14, outline: 'none' }} />
                  <input value={s.subtitle || ''} onChange={e => patchScreen(i, { subtitle: e.target.value })}
                    style={{ width: '100%', boxSizing: 'border-box', padding: '7px 10px', borderRadius: 9,
                      background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.10)',
                      color: 'rgba(255,255,255,0.8)', fontFamily: BODY, fontSize: 12.5, outline: 'none' }} />
                </div>
              ))}
            </div>
          </Section>

          <Section title={`App Previews · ${c.videos.length}`}>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px,1fr))', gap: 12 }}>
              {c.videos.map((s, i) => (
                <div key={i} style={{ borderRadius: 14, border: '1px solid rgba(255,255,255,0.10)',
                  background: 'rgba(255,255,255,0.03)', padding: 14 }}>
                  <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10.5, color: 'rgba(255,255,255,0.4)',
                    marginBottom: 8 }}>▶ {String(i + 1).padStart(2, '0')}</div>
                  <textarea rows={2} value={s.headline || ''} onChange={e => patchVideo(i, { headline: e.target.value })}
                    style={{ width: '100%', boxSizing: 'border-box', resize: 'none', marginBottom: 6, padding: '8px 10px',
                      borderRadius: 9, background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.10)',
                      color: '#fff', fontFamily: DISPLAY, fontWeight: 600, fontSize: 14, outline: 'none' }} />
                  <input value={s.subtitle || ''} onChange={e => patchVideo(i, { subtitle: e.target.value })}
                    style={{ width: '100%', boxSizing: 'border-box', padding: '7px 10px', borderRadius: 9,
                      background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.10)',
                      color: 'rgba(255,255,255,0.8)', fontFamily: BODY, fontSize: 12.5, outline: 'none' }} />
                </div>
              ))}
            </div>
          </Section>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AIWizard, AISettings, aiComplete, aiCfg });
