import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { api, ApiError } from '../api/client'
import { ResearchMapPanel } from '../components/ResearchMapPanel'
import { ViralScanJobPanel } from '../components/ViralScanJobPanel'
import { Badge, Button, Card, ErrorText, Field, Notice, PageTitle, Select, Textarea } from '../components/ui'
import { useActiveCopyPersona } from '../hooks/useActiveCopyPersona'
import { useIslanderPage } from '../lib/islander'
import { registerCopyIslanderActions, setCopyActionDeps } from '../lib/islander/copyActions'
import { isTerminalJobStatus } from '../lib/jobStatus'
import { hasCopyResearchMap, type CopyDraftData, type JobData, type ViralScanPostData } from '../types/api'

export function CopyMatrixPage() {
  const { personaId, persona, personas, setPersonaId, loading: personaLoading } = useActiveCopyPersona()
  const [keywordsText, setKeywordsText] = useState('')
  const [posts, setPosts] = useState<ViralScanPostData[]>([])
  const [drafts, setDrafts] = useState<CopyDraftData[]>([])
  const [viralJob, setViralJob] = useState<JobData | null>(null)
  const [loading, setLoading] = useState(false)
  const [scanning, setScanning] = useState(false)
  const [generatingId, setGeneratingId] = useState('')
  const [error, setError] = useState('')

  const keywords = useMemo(
    () =>
      keywordsText
        .split(/[\n,，]/)
        .map((k) => k.trim())
        .filter(Boolean),
    [keywordsText],
  )

  useIslanderPage({
    title: '拷貝忍者',
    purpose: '流程 A：對標研究地圖 → 爆款掃描 → 依 8D 風格產仿寫草稿',
    hints: [
      '先選人設並完成 8D 對標分析',
      '啟動爆款掃描會自動產生對標研究地圖',
      '從掃描結果產出仿寫草稿',
      '不要使用 expandKnowledgeGraph 等流程 B 動作',
    ],
    suggestions: ['幫我開始爆款掃描', '幫我仿寫這篇', '帶我去設定 8D'],
  })

  const load = useCallback(async () => {
    if (!personaId) return
    setLoading(true)
    setError('')
    try {
      const [postsData, draftsData, jobsData] = await Promise.all([
        api.get<{ list: ViralScanPostData[] }>(
          `/api/v1/personas/${encodeURIComponent(personaId)}/viral-scan-posts`,
          { auth: true },
        ),
        api.get<{ list: CopyDraftData[] }>(
          `/api/v1/personas/${encodeURIComponent(personaId)}/copy-drafts`,
          { auth: true },
        ),
        api.get<{ list: JobData[] }>(`/api/v1/jobs?scope=persona&scope_id=${encodeURIComponent(personaId)}`, {
          auth: true,
        }),
      ])
      setPosts(postsData.list ?? [])
      setDrafts(draftsData.list ?? [])
      const active =
        (jobsData.list ?? []).find(
          (job) => job.template_type === 'scan-viral' && !isTerminalJobStatus(job.status),
        ) ?? null
      setViralJob(active)
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '載入失敗')
    } finally {
      setLoading(false)
    }
  }, [personaId])

  useEffect(() => {
    load().catch(() => undefined)
  }, [load])

  useEffect(() => {
    registerCopyIslanderActions()
  }, [])

  useEffect(() => {
    setCopyActionDeps({
      personaId,
      keywords,
      onStartScan: () => setScanning(true),
      reload: () => {
        load().catch(() => undefined)
      },
    })
    return () => setCopyActionDeps(null)
  }, [personaId, keywords, load])

  useEffect(() => {
    if (!viralJob || isTerminalJobStatus(viralJob.status)) return
    const timer = window.setInterval(() => {
      load().catch(() => undefined)
    }, 3000)
    return () => window.clearInterval(timer)
  }, [viralJob, load])

  const startScan = async () => {
    if (!personaId) return
    setScanning(true)
    setError('')
    try {
      await api.post(
        `/api/v1/personas/${encodeURIComponent(personaId)}/viral-scan-jobs`,
        { keywords },
        { auth: true },
      )
      await load()
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '啟動掃描失敗')
    } finally {
      setScanning(false)
    }
  }

  const generateDraft = async (scanPostId: string) => {
    if (!personaId) return
    setGeneratingId(scanPostId)
    setError('')
    try {
      await api.post(
        `/api/v1/personas/${encodeURIComponent(personaId)}/copy-drafts/generate`,
        { scan_post_id: scanPostId },
        { auth: true },
      )
      await load()
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '產出仿寫失敗')
    } finally {
      setGeneratingId('')
    }
  }

  const displayName = persona?.display_name?.trim() || '未命名人設'
  const has8D = !!persona?.style_profile?.trim()

  return (
    <div className="space-y-8">
      <header className="space-y-2">
        <p className="display-en text-[10px] font-bold tracking-[0.16em] text-brand uppercase">流程 A · Copy Ninja</p>
        <PageTitle
          title="拷貝忍者"
          subtitle="掃描 Threads 高互動爆款，依你的 8D 風格產出可直接發布的仿寫草稿。"
        />
      </header>

      <Card className="grid gap-4">
        <Field label="人設（語氣 + 8D）">
          <Select
            value={personaId}
            onChange={(e) => setPersonaId(e.target.value)}
            disabled={personaLoading || personas.length === 0}
            data-islander-label="拷貝人設"
          >
            {personas.length === 0 ? <option value="">尚無人設</option> : null}
            {personas.map((item) => (
              <option key={item.id} value={item.id}>
                {item.display_name || item.id}
                {item.style_benchmark ? ` · @${item.style_benchmark.replace(/^@/, '')}` : ''}
              </option>
            ))}
          </Select>
        </Field>
        <div className="flex flex-wrap items-center gap-2 text-sm">
          <span className="text-ink-secondary">目前：{displayName}</span>
          {has8D ? <Badge tone="success">8D 已就緒</Badge> : <Badge tone="warning">尚未 8D</Badge>}
          {personaId ? (
            <Link to={`/personas/${personaId}#style-8d`} className="font-semibold text-brand hover:underline">
              設定對標帳號
            </Link>
          ) : null}
        </div>
        <Field label="掃描關鍵字（每行一個，可留空用研究地圖 tag 推導）">
          <Textarea
            rows={3}
            value={keywordsText}
            onChange={(e) => setKeywordsText(e.target.value)}
            placeholder="例如：轉職焦慮&#10;面試技巧"
            data-islander-label="爆款關鍵字"
          />
        </Field>
        <div className="flex flex-wrap gap-2">
          <Button onClick={startScan} disabled={!personaId || scanning || !!viralJob}>
            {scanning || viralJob ? '掃描進行中…' : '開始爆款掃描'}
          </Button>
          <Link to="/placement/topics">
            <Button variant="soft">改走置入（流程 B）</Button>
          </Link>
        </div>
      </Card>

      <Card className="space-y-3">
        <div className="flex items-center gap-2">
          <h2 className="text-sm font-bold text-ink">① 對標研究地圖</h2>
          {hasCopyResearchMap(persona) ? (
            <Badge tone="success">已就緒</Badge>
          ) : (
            <Badge tone="neutral">掃描時自動產生</Badge>
          )}
        </div>
        <ResearchMapPanel map={persona?.copy_research_map} variant="copy" loading={scanning || !!viralJob} />
      </Card>

      {viralJob ? (
        <Card>
          <ViralScanJobPanel job={viralJob} />
        </Card>
      ) : null}

      {!has8D ? (
        <Notice
          tone="warning"
          title="建議先完成 8D 分析"
          message="仿寫會套用 style_profile；未完成時仍可掃描，但語氣可能不夠貼近你的帳號。"
        />
      ) : null}

      <ErrorText message={error} />

      <section>
        <h2 className="text-lg font-bold text-ink">爆款候選（{posts.length}）</h2>
        <p className="mt-1 text-sm text-ink-secondary">依互動分數排序。選一篇產出仿寫草稿。</p>
        {loading ? (
          <Card className="mt-4 p-6 text-sm text-muted">載入中…</Card>
        ) : posts.length ? (
          <div className="mt-4 grid gap-3">
            {posts.map((post) => (
              <Card key={post.id} className="space-y-3 p-4">
                <div className="flex flex-wrap items-center gap-2 text-xs text-ink-secondary">
                  <Badge tone="sky">{post.search_tag || '爆款'}</Badge>
                  <span>互動 {post.engagement_score}</span>
                  {post.author ? <span>@{post.author}</span> : null}
                </div>
                <p className="text-sm leading-relaxed text-ink">{post.text}</p>
                <div className="flex flex-wrap gap-2">
                  {post.permalink ? (
                    <a
                      href={post.permalink}
                      target="_blank"
                      rel="noreferrer"
                      className="text-xs font-semibold text-brand hover:underline"
                    >
                      原文
                    </a>
                  ) : null}
                  <Button
                    variant="soft"
                    onClick={() => generateDraft(post.id)}
                    disabled={generatingId === post.id}
                  >
                    {generatingId === post.id ? '仿寫中…' : '產出仿寫'}
                  </Button>
                </div>
              </Card>
            ))}
          </div>
        ) : (
          <Card className="mt-4 p-8 text-center text-sm text-muted">尚無掃描結果，按「開始爆款掃描」</Card>
        )}
      </section>

      <section>
        <h2 className="text-lg font-bold text-ink">仿寫草稿（{drafts.length}）</h2>
        {drafts.length ? (
          <div className="mt-4 grid gap-3">
            {drafts.map((draft) => (
              <Card key={draft.id} className="space-y-2 p-4">
                {draft.hook ? <p className="text-xs font-bold text-brand">Hook：{draft.hook}</p> : null}
                <p className="whitespace-pre-wrap text-sm leading-relaxed text-ink">{draft.text}</p>
                {draft.rationale ? (
                  <p className="text-xs text-ink-secondary">{draft.rationale}</p>
                ) : null}
              </Card>
            ))}
          </div>
        ) : (
          <Card className="mt-4 p-8 text-center text-sm text-muted">完成掃描後，從爆款候選產出仿寫</Card>
        )}
      </section>
    </div>
  )
}