import { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { api, ApiError } from '../api/client'
import { CopyMissionDiceButton } from '../components/CopyMissionDiceButton'
import { Badge, Button, Card, ErrorText, Field, Input, PageTitle, Select, SuccessText, Textarea } from '../components/ui'
import {
  getActiveCopyPersonaId,
  isPersonaNotFoundError,
  rememberCopyPersonaId,
  resolveCopyPersonaId,
} from '../lib/copyFlow'
import type { ListPersonasData, PersonaData } from '../types/api'
import type { CopyMissionData } from '../types/copyMission'
import { hasPersona8D } from '../lib/styleProfile'
import { copyMissionStatusLabel, copyMissionStatusTone, hasMissionResearchMap } from '../types/copyMission'

export function CopyMatrixPage() {
  const [personas, setPersonas] = useState<PersonaData[]>([])
  const [personaId, setPersonaId] = useState(getActiveCopyPersonaId())
  const [personaDetail, setPersonaDetail] = useState<PersonaData | null>(null)
  const [missions, setMissions] = useState<CopyMissionData[]>([])
  const [label, setLabel] = useState('')
  const [seedQuery, setSeedQuery] = useState('')
  const [brief, setBrief] = useState('')
  const [loading, setLoading] = useState(true)
  const [creating, setCreating] = useState(false)
  const [inspiring, setInspiring] = useState(false)
  const [inspireNote, setInspireNote] = useState('')
  const [inspireMessage, setInspireMessage] = useState('')
  const [message, setMessage] = useState('')
  const [error, setError] = useState('')

  const loadPersonas = useCallback(async () => {
    const data = await api.get<ListPersonasData>('/api/v1/personas', { auth: true })
    const list = data.list ?? []
    setPersonas(list)
    setPersonaId((current) => {
      const resolved = resolveCopyPersonaId(list, current)
      if (resolved) rememberCopyPersonaId(resolved)
      return resolved
    })
    return list
  }, [])

  const loadMissions = useCallback(async (targetPersonaId?: string) => {
    const id = (targetPersonaId ?? personaId).trim()
    if (!id) {
      setMissions([])
      return
    }
    setLoading(true)
    setError('')
    try {
      const data = await api.get<{ list: CopyMissionData[] }>(
        `/api/v1/personas/${encodeURIComponent(id)}/copy-missions`,
        { auth: true },
      )
      setMissions(data.list ?? [])
    } catch (e) {
      const message = e instanceof ApiError ? e.message : '載入任務失敗'
      if (e instanceof ApiError && isPersonaNotFoundError(message)) {
        try {
          const list = await loadPersonas()
          const resolved = resolveCopyPersonaId(list, '')
          if (resolved && resolved !== id) {
            setPersonaId(resolved)
            rememberCopyPersonaId(resolved)
            const data = await api.get<{ list: CopyMissionData[] }>(
              `/api/v1/personas/${encodeURIComponent(resolved)}/copy-missions`,
              { auth: true },
            )
            setMissions(data.list ?? [])
            setError('先前選擇的人設已失效，已自動切換到目前帳號下的人設。')
            return
          }
        } catch {
          // fall through
        }
      }
      setError(message)
    } finally {
      setLoading(false)
    }
  }, [loadPersonas, personaId])

  useEffect(() => {
    void loadPersonas().catch((e) => {
      setError(e instanceof ApiError ? e.message : '載入人設失敗')
    })
  }, [loadPersonas])

  useEffect(() => {
    void loadMissions()
  }, [loadMissions])

  useEffect(() => {
    if (!personaId) {
      setPersonaDetail(null)
      return
    }
    let cancelled = false
    void api
      .get<PersonaData>(`/api/v1/personas/${encodeURIComponent(personaId)}`, { auth: true })
      .then((data) => {
        if (!cancelled) setPersonaDetail(data)
      })
      .catch(() => {
        if (!cancelled) setPersonaDetail(null)
      })
    return () => {
      cancelled = true
    }
  }, [personaId])

  const onPersonaChange = (id: string) => {
    setPersonaId(id)
    rememberCopyPersonaId(id)
  }

  const rollInspiration = async () => {
    if (!personaId) return
    setInspiring(true)
    setError('')
    setInspireMessage('')
    try {
      const data = await api.post<{
        label: string
        seed_query: string
        brief: string
        trend_reason?: string
        trend_keywords?: string[]
        message?: string
        web_search_used?: boolean
      }>(`/api/v1/personas/${encodeURIComponent(personaId)}/copy-mission-inspiration`, {}, { auth: true })
      setLabel(data.label ?? '')
      setSeedQuery(data.seed_query ?? '')
      setBrief(data.brief ?? '')
      const keywords = (data.trend_keywords ?? []).filter(Boolean)
      const reason = data.trend_reason?.trim()
      if (reason) {
        setInspireNote(
          keywords.length
            ? `${reason}（相關熱詞：${keywords.join('、')}）`
            : reason,
        )
      } else {
        setInspireNote('')
      }
      setInspireMessage(data.message || '已填入靈感草稿，確認後按「建立任務」')
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '骰靈感失敗')
      setInspireNote('')
    } finally {
      setInspiring(false)
    }
  }

  const createMission = async () => {
    if (!personaId) return
    setCreating(true)
    setError('')
    setMessage('')
    try {
      const mission = await api.post<CopyMissionData>(
        `/api/v1/personas/${encodeURIComponent(personaId)}/copy-missions`,
        { label, seed_query: seedQuery, brief },
        { auth: true },
      )
      const started = await api.post<{ job_id: string; status: string; message?: string }>(
        `/api/v1/personas/${encodeURIComponent(personaId)}/copy-missions/${encodeURIComponent(mission.id)}/analyze-jobs`,
        {},
        { auth: true },
      )
      setLabel('')
      setSeedQuery('')
      setBrief('')
      setInspireNote('')
      setInspireMessage('')
      await loadMissions(personaId)
      setMessage(
        started.message?.trim() ||
          `已建立「${mission.label}」，研究地圖在背景產生中；請在下方列表按「繼續任務」。`,
      )
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '建立任務失敗')
    } finally {
      setCreating(false)
    }
  }

  const persona = personaDetail ?? personas.find((item) => item.id === personaId)
  const has8D = hasPersona8D(persona)
  const personaLabel = persona?.display_name?.trim() || persona?.id || ''
  const activeMissions = missions.filter((m) => m.status !== 'archived')
  const archivedMissions = missions.filter((m) => m.status === 'archived')

  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">Copy Ninja</p>
        <PageTitle
          title="拷貝忍者"
          subtitle="找近期熱門話題 → 研究地圖 → 勾選標籤 → 海巡爆款 → 產出你的人設版本。"
        />
      </header>

      <Card className="grid gap-4">
        <Field label="人設（8D 語氣來源）">
          <Select
            value={personaId}
            onChange={(e) => onPersonaChange(e.target.value)}
            disabled={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}
              </option>
            ))}
          </Select>
        </Field>
        <div className="flex flex-wrap items-center gap-2 text-sm">
          {personaLabel ? <span className="text-ink-secondary">目前：{personaLabel}</span> : null}
          {has8D ? (
            <Badge tone="success">
              8D 已就緒{persona?.style_benchmark ? ` · @${persona.style_benchmark}` : ''}
            </Badge>
          ) : (
            <Badge tone="warning">建議先完成 8D</Badge>
          )}
          {personaId ? (
            <Link to={`/personas/${personaId}#style-8d`} className="font-semibold text-brand hover:underline">
              {has8D ? '查看 8D 策略' : '設定對標帳號'}
            </Link>
          ) : null}
        </div>
      </Card>

      <Card className="space-y-4">
        <div className="hx-copy-create-head">
          <h2 className="text-sm font-bold text-ink">新增拷貝任務</h2>
          <CopyMissionDiceButton
            rolling={inspiring}
            disabled={!personaId}
            onClick={() => void rollInspiration()}
          />
        </div>
        <p className="text-sm text-ink-secondary">
          每次任務只針對一個熱門方向；不確定題材時可按「骰靈感」自動填表（有 Brave／Exa key 會參考網路趨勢，否則改由 LLM 依人設推測）。建立後會自動分析受眾與研究地圖。
        </p>
        <SuccessText message={inspireMessage} />
        {inspireNote ? (
          <p className="hx-copy-inspire-note">
            <strong>這次靈感：</strong>
            {inspireNote}
          </p>
        ) : null}
        <Field label="任務名稱">
          <Input value={label} onChange={(e) => setLabel(e.target.value)} placeholder="例：轉職焦慮語錄" />
        </Field>
        <Field label="種子關鍵字／近期熱詞">
          <Input value={seedQuery} onChange={(e) => setSeedQuery(e.target.value)} placeholder="例：轉職、被裁" />
        </Field>
        <Field label="這次想找什麼（Brief）">
          <Textarea
            rows={3}
            value={brief}
            onChange={(e) => setBrief(e.target.value)}
            placeholder="例：想找最近 Threads 上互動高的轉職心情貼文，語錄或故事型都可以。"
          />
        </Field>
        <Button onClick={createMission} disabled={!personaId || creating || !label.trim() || !seedQuery.trim() || !brief.trim()}>
          {creating ? '建立中…' : '建立任務'}
        </Button>
      </Card>

      <SuccessText message={message} />
      <ErrorText message={error} />

      <section>
        <h2 className="text-lg font-bold text-ink">進行中的任務</h2>
        {loading ? (
          <Card className="mt-4 p-6 text-sm text-muted">載入中…</Card>
        ) : activeMissions.length ? (
          <div className="mt-4 grid gap-3">
            {activeMissions.map((mission) => (
              <Card key={mission.id} className="flex flex-wrap items-center justify-between gap-3 p-4">
                <div>
                  <div className="flex flex-wrap items-center gap-2">
                    <p className="font-semibold text-ink">{mission.label}</p>
                    <Badge tone={copyMissionStatusTone(mission.status)}>{copyMissionStatusLabel(mission.status)}</Badge>
                  </div>
                  <p className="mt-1 text-sm text-ink-secondary">
                    {mission.seed_query}
                    {hasMissionResearchMap(mission) ? '' : ' · 待產生地圖'}
                    {(mission.research_map?.similar_accounts?.length ?? 0) > 0
                      ? ` · ${mission.research_map?.similar_accounts?.length} 位參考帳號`
                      : ''}
                  </p>
                </div>
                <Link to={`/matrix/missions/${mission.id}`}>
                  <Button variant="soft">繼續任務</Button>
                </Link>
              </Card>
            ))}
          </div>
        ) : (
          <Card className="mt-4 p-8 text-center text-sm text-muted">尚無任務，建立第一個拷貝任務開始</Card>
        )}
      </section>

      {archivedMissions.length ? (
        <section>
          <h2 className="text-lg font-bold text-ink">已封存</h2>
          <div className="mt-4 grid gap-3">
            {archivedMissions.map((mission) => (
              <Card key={mission.id} className="flex flex-wrap items-center justify-between gap-3 p-4 opacity-90">
                <div>
                  <div className="flex flex-wrap items-center gap-2">
                    <p className="font-semibold text-ink">{mission.label}</p>
                    <Badge tone="neutral">{copyMissionStatusLabel(mission.status)}</Badge>
                  </div>
                  <p className="mt-1 text-sm text-ink-secondary">{mission.seed_query}</p>
                </div>
                <Link to={`/matrix/missions/${mission.id}`}>
                  <Button variant="ghost">查看</Button>
                </Link>
              </Card>
            ))}
          </div>
        </section>
      ) : null}
    </div>
  )
}