import { useState } from 'react'
import { api, runJob } from '../api'
import { useJob, ProgressBox, ErrorBox } from '../hooks'
import PromptPanel from '../components/PromptPanel'

export default function TopicsStep({ data, refreshProject, projectId, selectReel }) {
  const [count, setCount] = useState(8)
  const [picked, setPicked] = useState(null)
  const [editing, setEditing] = useState(null)
  const [editTopic, setEditTopic] = useState(null) // {title, reason, popularity_signal}
  const [prompt, setPrompt] = useState(null)
  const [creating, setCreating] = useState(false)
  const job = useJob()

  const topics = data.topics?.topics || []

  const generate = async () => {
    try {
      await job.start(`/api/projects/${projectId}/topics/generate`, { n: Number(count), prompt })
      await refreshProject()
      setPicked(null)
    } catch { /* shown */ }
  }

  // A legacy single-string signal looks like:
  //   "Source ('quote'), Other ('q1', 'q2'), r/sub ('quote')"
  // Split only on ")," boundaries between sources, so commas *inside* the
  // parenthetical quotes don't split. Falls back to the whole string.
  const splitLegacy = (str) => {
    const parts = str.split(/\)\s*,\s*/)
    return parts
      .map((p, i) => (i < parts.length - 1 ? p + ')' : p).trim())
      .filter(Boolean)
  }

  // Signals may arrive as the new list, a one-item list still holding a
  // combined string, or the legacy single string. Split EVERY entry on the
  // "), " source boundaries (idempotent: already-clean items pass through).
  const signalsOf = (t) => {
    const raw = (t.signals && t.signals.length) ? t.signals
      : (t.popularity_signal ? [t.popularity_signal] : [])
    return raw.flatMap((s) => splitLegacy(String(s)))
  }

  const startEdit = (i) => { setEditing(i); setEditTopic({ ...topics[i], signals: signalsOf(topics[i]) }) }

  const saveEdit = async (i) => {
    // Clean up signal lines (drop blanks/whitespace) only at save time.
    const clean = { ...editTopic, signals: (editTopic.signals || []).map((s) => s.trim()).filter(Boolean) }
    const updated = topics.map((t, j) => (j === i ? { ...t, ...clean } : t))
    await api.put(`/api/projects/${projectId}/topics`, { topics: updated })
    await refreshProject()
    setEditing(null)
  }

  const addCustom = async () => {
    const fresh = { title: "New topic", reason: "added manually", signals: [] }
    await api.put(`/api/projects/${projectId}/topics`, { topics: [fresh, ...topics] })
    await refreshProject()
    setEditing(0)
    setEditTopic({ ...fresh })
  }

  const removeTopic = async (i) => {
    const updated = topics.filter((_, j) => j !== i)
    await api.put(`/api/projects/${projectId}/topics`, { topics: updated })
    await refreshProject()
    setPicked(null)
  }

  // Create a reel for the chosen topic and open it on the Script step,
  // where the user can QC/edit the script prompt before generating.
  const useTopic = async () => {
    setCreating(true)
    try {
      const reel = await api.post(`/api/projects/${projectId}/reels`, { topic: topics[picked].title })
      await refreshProject()
      selectReel(reel.id)
    } catch (e) {
      job.setError(e.message)
    } finally {
      setCreating(false)
    }
  }

  return (
    <div>
      <h2>Topics</h2>
      <p className="subtitle">
        Ranked from your reference channels&apos; top Shorts plus news and Reddit signals. Edit any topic inline, then turn one into a reel.
      </p>

      <div className="card">
        <div className="row">
          <label className="row" style={{ gap: 8 }}>
            <span className="muted">How many:</span>
            <input type="number" min="1" max="20" style={{ width: 70 }} value={count}
              onChange={(e) => setCount(e.target.value)} />
          </label>
          <button className="btn" onClick={generate} disabled={job.running}>
            {job.running ? 'Generating…' : topics.length ? 'Regenerate topics' : 'Generate topics'}
          </button>
        </div>
        <div style={{ marginTop: 10 }}>
          <PromptPanel
            label="topic-ranking"
            value={prompt}
            setValue={setPrompt}
            disabled={job.running}
            fetchPrompt={async () => (await runJob(`/api/projects/${projectId}/topics/prompt`, { n: Number(count) })).prompt}
          />
        </div>
      </div>

      <ErrorBox error={job.error} onRetry={generate} />
      {job.running && <ProgressBox progress={job.progress.length ? job.progress : ['Collecting signals…']} />}

      {(topics.length > 0 || data.topics) && (
        <div className="card">
          <div className="row" style={{ marginBottom: topics.length ? 8 : 0 }}>
            <strong className="grow">Topic pool ({topics.length})</strong>
            <button className="btn small secondary" onClick={addCustom}>+ Add your own topic</button>
          </div>
          {topics.map((t, i) => (
            <div key={i} className={`topic-row ${picked === i ? 'selected' : ''}`}>
              <input type="radio" name="topic" checked={picked === i} onChange={() => setPicked(i)}
                style={{ marginTop: 5 }} />
              <div className="grow">
                {editing === i ? (
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                    <label className="field" style={{ margin: 0 }}>
                      <span className="lbl">Title</span>
                      <input type="text" value={editTopic.title} autoFocus
                        onChange={(e) => setEditTopic({ ...editTopic, title: e.target.value })}
                        onKeyDown={(e) => e.key === 'Enter' && saveEdit(i)} />
                    </label>
                    <label className="field" style={{ margin: 0 }}>
                      <span className="lbl">Description (why this topic)</span>
                      <textarea value={editTopic.reason} style={{ minHeight: 56 }}
                        onChange={(e) => setEditTopic({ ...editTopic, reason: e.target.value })} />
                    </label>
                    <label className="field" style={{ margin: 0 }}>
                      <span className="lbl">Supporting signals (one per line)</span>
                      <textarea style={{ minHeight: 70 }}
                        value={(editTopic.signals || []).join('\n')}
                        placeholder="FutbolEssence — 'Arsenal Reaction…'&#10;r/soccer — 'High schoolers react…'"
                        onChange={(e) => setEditTopic({ ...editTopic, signals: e.target.value.split('\n') })} />
                    </label>
                    <div className="row">
                      <button className="btn small" onClick={() => saveEdit(i)}>Save</button>
                      <button className="btn small secondary" onClick={() => setEditing(null)}>Cancel</button>
                    </div>
                  </div>
                ) : (
                  <>
                    <strong style={{ cursor: 'pointer' }} onClick={() => setPicked(i)}>{t.title}</strong>
                    {t.reason && <div className="topic-meta">{t.reason}</div>}
                    {signalsOf(t).length > 0 && (
                      <ul className="signal-list">
                        {signalsOf(t).map((s, k) => <li key={k}>{s}</li>)}
                      </ul>
                    )}
                  </>
                )}
              </div>
              {editing !== i && (
                <>
                  <button className="btn small secondary" onClick={() => startEdit(i)}>Edit</button>
                  <button className="btn small danger" onClick={() => removeTopic(i)}>Remove</button>
                </>
              )}
            </div>
          ))}
        </div>
      )}

      {topics.length > 0 && (
        <button className="btn" disabled={picked === null || creating} onClick={useTopic}>
          {creating ? 'Creating reel…' : 'Create a reel for this topic →'}
        </button>
      )}
    </div>
  )
}
