import { useCallback, useEffect, useMemo, useState } from 'react'
import type { CopyMissionData, CopyAudienceSampleData } from '../types/copyMission'
import {
  audienceSampleConfidence,
  audienceSampleConfidenceLabel,
  hasMissionResearchMap,
} from '../types/copyMission'
import {
  CopyMissionResearchEditor,
  MAX_COPY_SCAN_TAGS,
  type CopyMissionResearchMapDraft,
} from './CopyMissionResearchEditor'
import { patchCopyMissionAudienceSample } from '../lib/copyMissionAudience'
import type { KnowledgeGraphData, KnowledgeGraphNode } from '../lib/knowledgeGraph'
import { mergeCopyMissionSources } from '../lib/copyMissionGraph'
import { threadsProfileUrl } from '../lib/threadsLinks'
import { ApiError } from '../api/client'
import { CopyMissionKnowledgeTab } from './CopyMissionKnowledgeTab'
import { CopyMissionSimilarAccountsCard } from './CopyMissionSimilarAccountsCard'
import { Badge, Button, Card } from './ui'

type TabId = 'map' | 'knowledge'

type Props = {
  mission: CopyMissionData | null
  personaId?: string
  loading?: boolean
  onSaveResearchMap?: (draft: CopyMissionResearchMapDraft) => Promise<void>
  onMissionUpdate?: (mission: CopyMissionData) => void
  onAddScanTag?: (username: string) => void
  onActionMessage?: (message: string) => void
  onActionError?: (message: string) => void
  onRegenerateResearchMap?: () => void
  regenerating?: boolean
  aiReady?: boolean
  graph?: KnowledgeGraphData | null
  graphLoading?: boolean
  draftNodes?: KnowledgeGraphNode[]
  savingGraph?: boolean
  expandingKnowledge?: boolean
  discoverReady?: boolean
  onToggleGraphNode?: (nodeId: string, selected: boolean) => void
  onSelectPainNodes?: () => void
  onClearGraphSelection?: () => void
  onSaveGraphSelection?: () => void
  onExpandKnowledge?: () => void
}

function CompactList({ items, emptyLabel }: { items: string[]; emptyLabel?: string }) {
  if (!items.length) {
    return emptyLabel ? <p className="hx-research-reader__empty">{emptyLabel}</p> : null
  }
  return (
    <ol className="hx-research-reader__list hx-research-reader__list--compact">
      {items.map((item, index) => (
        <li key={`${item}-${index}`}>
          <span className="hx-research-reader__list-index">{index + 1}</span>
          <span>{item}</span>
        </li>
      ))}
    </ol>
  )
}

function resolveScanTags(mission: CopyMissionData | null): string[] {
  if (!mission) return []
  if (mission.selected_tags?.length) return mission.selected_tags
  return (mission.research_map?.suggested_tags ?? []).map((item) => item.tag).filter(Boolean)
}

function sortAudienceSamples(list: CopyAudienceSampleData[]): CopyAudienceSampleData[] {
  const rank = (item: CopyAudienceSampleData) => {
    if (item.status === 'pinned') return 0
    if (item.status === 'excluded') return 2
    return 1
  }
  return [...list].sort((a, b) => {
    const rankDiff = rank(a) - rank(b)
    if (rankDiff !== 0) return rankDiff
    return (b.appearances ?? 0) - (a.appearances ?? 0)
  })
}

function MapReadView({ mission }: { mission: CopyMissionData }) {
  const map = mission.research_map
  const scanTags = resolveScanTags(mission)
  const hasContent =
    !!map?.audience_summary?.trim() ||
    !!map?.content_goal?.trim() ||
    (map?.questions?.length ?? 0) > 0 ||
    (map?.pillars?.length ?? 0) > 0 ||
    (map?.exclusions?.length ?? 0) > 0 ||
    !!map?.benchmark_notes?.trim() ||
    scanTags.length > 0

  if (!hasContent) {
    return <p className="hx-research-reader__prose text-ink-secondary">研究地圖尚未產生。</p>
  }

  return (
    <div className="hx-research-map-layout hx-research-map-layout--overview">
      <div className="hx-research-reader__block hx-research-reader__block--accent">
        <p className="hx-research-reader__label hx-research-reader__label--brand">受眾是誰</p>
        <p className="hx-research-reader__prose hx-research-reader__prose--compact">
          {map?.audience_summary?.trim() || '—'}
        </p>
      </div>
      <div className="hx-research-reader__block">
        <p className="hx-research-reader__label">內容目標</p>
        <p className="hx-research-reader__prose hx-research-reader__prose--compact">
          {map?.content_goal?.trim() || '—'}
        </p>
      </div>
      <div className="hx-research-reader__block">
        <p className="hx-research-reader__label">受眾會問什麼</p>
        <CompactList items={map?.questions ?? []} emptyLabel="尚無提問方向" />
      </div>
      <div className="hx-research-reader__block">
        <p className="hx-research-reader__label">內容支柱</p>
        <CompactList items={map?.pillars ?? []} emptyLabel="尚無內容支柱" />
      </div>
      <div className="hx-research-reader__block hx-research-reader__block--warn">
        <p className="hx-research-reader__label">不要碰</p>
        <CompactList items={map?.exclusions ?? []} emptyLabel="尚無排除項" />
      </div>
      {map?.benchmark_notes?.trim() ? (
        <div className="hx-research-reader__block">
          <p className="hx-research-reader__label">對標筆記</p>
          <p className="hx-research-reader__prose hx-research-reader__prose--compact">{map.benchmark_notes.trim()}</p>
        </div>
      ) : null}
      <div className="hx-research-reader__block hx-research-reader__block--accent">
        <div className="hx-patrol-picks__head">
          <p className="hx-research-reader__label hx-research-reader__label--brand">優先搜尋查詢</p>
          <span className="hx-patrol-picks__meta">最多 {MAX_COPY_SCAN_TAGS} 組</span>
        </div>
        <p className="mb-2 text-xs leading-relaxed text-muted">
          保留完整主題意圖；可用來找相似帳號、人工查看 Threads，海巡只是選配。
        </p>
        {scanTags.length ? (
          <ul className="hx-patrol-chips">
            {scanTags.map((tag, index) => (
              <li key={tag} className="hx-patrol-chips__item">
                <span className="hx-patrol-chips__rank">{index + 1}</span>
                <span className="hx-patrol-chips__tag">{tag}</span>
              </li>
            ))}
          </ul>
        ) : (
          <p className="hx-research-reader__empty">研究地圖產生後會自動整理搜尋查詢。</p>
        )}
        {!mission.selected_tags?.length && scanTags.length > 0 ? (
          <p className="mt-2 text-xs leading-relaxed text-muted">
            目前顯示 AI 建議查詢；編輯並儲存後會固定為人工參考／海巡用詞。
          </p>
        ) : null}
      </div>
    </div>
  )
}

export function CopyMissionResearchOverview({
  mission,
  personaId,
  loading,
  onSaveResearchMap,
  onMissionUpdate,
  onAddScanTag,
  onActionMessage,
  onActionError,
  onRegenerateResearchMap,
  regenerating,
  aiReady,
  graph,
  graphLoading,
  draftNodes = [],
  savingGraph,
  expandingKnowledge,
  discoverReady,
  onToggleGraphNode,
  onSelectPainNodes,
  onClearGraphSelection,
  onSaveGraphSelection,
  onExpandKnowledge,
}: Props) {
  const [editing, setEditing] = useState(false)
  const [actionError, setActionError] = useState('')
  const mapReady = hasMissionResearchMap(mission)
  const nodeCount = graph?.nodes?.length ?? 0
  const sourceCount = mergeCopyMissionSources(mission?.research_map, graph).length
  const [tab, setTab] = useState<TabId>(mapReady ? 'map' : nodeCount > 0 ? 'knowledge' : 'map')

  const audienceSamples = useMemo(
    () => sortAudienceSamples(mission?.research_map?.audience_samples ?? []),
    [mission?.research_map?.audience_samples],
  )

  const patchAudience = useCallback(
    async (username: string, status: '' | 'pinned' | 'excluded') => {
      if (!personaId || !mission?.id || !onMissionUpdate) return
      const prev = mission
      const nextSamples = (mission.research_map?.audience_samples ?? []).map((item) =>
        item.username === username ? { ...item, status } : item,
      )
      onMissionUpdate({
        ...mission,
        research_map: { ...mission.research_map, audience_samples: nextSamples },
      })
      setActionError('')
      try {
        const updated = await patchCopyMissionAudienceSample(personaId, mission.id, username, status)
        onMissionUpdate(updated)
      } catch (e) {
        onMissionUpdate(prev)
        setActionError(e instanceof ApiError ? e.message : '更新 TA 樣本失敗')
      }
    },
    [mission, onMissionUpdate, personaId],
  )

  useEffect(() => {
    if (tab !== 'map') {
      setEditing(false)
    }
  }, [tab])

  const tabs: { id: TabId; label: string; count?: number }[] = [
    { id: 'map', label: '研究地圖' },
    { id: 'knowledge', label: '延伸知識', count: nodeCount || undefined },
  ]

  if (loading) {
    return (
      <div className="hx-research-reader">
        <p className="text-sm leading-relaxed text-ink-secondary">載入任務資料…</p>
      </div>
    )
  }

  if (regenerating && !mapReady) {
    return (
      <div className="hx-research-reader space-y-3">
        <p className="text-sm leading-relaxed text-ink-secondary">研究地圖產生中…</p>
        <p className="text-xs leading-relaxed text-muted">背景任務完成後會自動更新，不需重新整理頁面。</p>
      </div>
    )
  }

  if (!mapReady && !onSaveResearchMap) {
    return (
      <div className="hx-research-reader space-y-3">
        <p className="text-sm leading-relaxed text-ink-secondary">
          尚未產生研究地圖。產生後會顯示受眾方向、延伸知識與搜尋查詢。
        </p>
        {onRegenerateResearchMap ? (
          <Button
            variant="soft"
            type="button"
            onClick={onRegenerateResearchMap}
            disabled={regenerating || aiReady === false}
            title={aiReady === false ? '請先設定 AI API key' : undefined}
          >
            {regenerating ? '產生中…' : '產生研究地圖'}
          </Button>
        ) : null}
      </div>
    )
  }

  return (
    <div className="hx-research-reader space-y-4">
      <div className="hx-research-tabs">
        <div className="hx-research-tabs__head">
          <nav className="hx-research-tabs__nav" aria-label="拷貝任務研究分頁">
            {tabs.map((item) => {
              const active = tab === item.id
              return (
                <button
                  key={item.id}
                  type="button"
                  className={`hx-research-tabs__btn ${active ? 'hx-research-tabs__btn--active' : ''}`}
                  onClick={() => setTab(item.id)}
                >
                  <span>{item.label}</span>
                  {item.count !== undefined && item.count > 0 ? (
                    <span className="hx-research-tabs__count">{item.count}</span>
                  ) : null}
                  {item.id === 'knowledge' && sourceCount > 0 ? (
                    <span className="hx-research-tabs__sources-hint">· {sourceCount} 連結</span>
                  ) : null}
                </button>
              )
            })}
          </nav>
          {tab === 'map' && onSaveResearchMap && mapReady && !editing ? (
            <div className="hx-research-map-toolbar">
              <Button variant="soft" type="button" onClick={() => setEditing(true)}>
                編輯研究地圖
              </Button>
              {onRegenerateResearchMap ? (
                <Button
                  variant="ghost"
                  type="button"
                  onClick={onRegenerateResearchMap}
                  disabled={regenerating || aiReady === false}
                  title={aiReady === false ? '請先設定 AI API key' : undefined}
                >
                  {regenerating ? '產生中…' : '重新產生研究地圖'}
                </Button>
              ) : null}
            </div>
          ) : null}

        </div>

        <div className="hx-research-tabs__panel">
          {tab === 'map' ? (
            editing && mission && onSaveResearchMap ? (
              <CopyMissionResearchEditor
                mission={mission}
                onSave={async (draft) => {
                  await onSaveResearchMap(draft)
                  setEditing(false)
                }}
                onCancel={() => setEditing(false)}
              />
            ) : mission ? (
              <MapReadView mission={mission} />
            ) : (
              <p className="text-sm leading-relaxed text-ink-secondary">尚未產生研究地圖。</p>
            )
          ) : null}

          {tab === 'knowledge' && mission && mapReady ? (
            <CopyMissionKnowledgeTab
              mission={mission}
              graph={graph ?? null}
              graphLoading={graphLoading}
              draftNodes={draftNodes}
              saving={savingGraph}
              expanding={expandingKnowledge}
              discoverReady={discoverReady}
              onToggle={(id, selected) => onToggleGraphNode?.(id, selected)}
              onSelectPainNodes={() => onSelectPainNodes?.()}
              onClearSelection={() => onClearGraphSelection?.()}
              onSaveSelection={() => void onSaveGraphSelection?.()}
              onExpandKnowledge={() => onExpandKnowledge?.()}
            />
          ) : null}

          {tab === 'knowledge' && !mapReady ? (
            <p className="text-sm leading-relaxed text-ink-secondary">
              請先產生研究地圖，完成後就能在這裡瀏覽核心／延伸／周邊知識節點。
            </p>
          ) : null}
        </div>
      </div>

      {actionError ? <p className="text-sm text-danger">{actionError}</p> : null}

      {mission && personaId && onMissionUpdate ? (
        <CopyMissionSimilarAccountsCard
          mission={mission}
          personaId={personaId}
          onMissionUpdate={onMissionUpdate}
          onAddScanTag={onAddScanTag}
          onMessage={onActionMessage}
          onError={onActionError}
        />
      ) : null}

      {audienceSamples.length > 0 ? (
        <Card className="hx-audience-samples">
          <h3 className="hx-copy-section-title">TA 樣本</h3>
          <p className="text-xs text-muted">從高互動貼文留言作者彙整，作為潛在受眾參考。</p>
          <ul className="hx-audience-samples__list">
            {audienceSamples.map((sample) => {
              const profileHref = threadsProfileUrl(sample.username)
              const confidence = audienceSampleConfidence(sample.appearances)
              const rowClass = [
                'hx-audience-samples__item',
                sample.status === 'pinned' ? 'hx-audience-samples__item--pinned' : '',
                sample.status === 'excluded' ? 'hx-audience-samples__item--excluded' : '',
              ]
                .filter(Boolean)
                .join(' ')
              return (
                <li key={sample.username} className={rowClass}>
                  <div className="min-w-0 flex-1 space-y-1">
                    <div className="flex flex-wrap items-center gap-2">
                      {profileHref ? (
                        <a
                          href={profileHref}
                          target="_blank"
                          rel="noreferrer"
                          className="text-sm font-semibold text-brand hover:underline"
                        >
                          @{sample.username}
                        </a>
                      ) : (
                        <span className="text-sm font-semibold text-ink">@{sample.username}</span>
                      )}
                      <Badge tone="sky">出現 {sample.appearances ?? 0} 次</Badge>
                      <span className="text-xs text-muted">
                        {audienceSampleConfidenceLabel(confidence)}
                      </span>
                      {sample.status === 'pinned' ? <Badge tone="brand">已收藏</Badge> : null}
                      {sample.status === 'excluded' ? <Badge tone="neutral">已忽略</Badge> : null}
                    </div>
                    {sample.sample_text ? (
                      <p className="text-xs leading-relaxed text-ink-secondary">{sample.sample_text}</p>
                    ) : null}
                  </div>
                  {personaId && onMissionUpdate ? (
                    <div className="flex flex-wrap gap-2">
                      {sample.status === 'pinned' ? (
                        <Button variant="ghost" onClick={() => void patchAudience(sample.username, '')}>
                          取消收藏
                        </Button>
                      ) : sample.status !== 'excluded' ? (
                        <Button variant="soft" onClick={() => void patchAudience(sample.username, 'pinned')}>
                          收藏為長期受眾
                        </Button>
                      ) : null}
                      {sample.status === 'excluded' ? (
                        <Button variant="ghost" onClick={() => void patchAudience(sample.username, '')}>
                          取消忽略
                        </Button>
                      ) : (
                        <Button variant="ghost" onClick={() => void patchAudience(sample.username, 'excluded')}>
                          忽略
                        </Button>
                      )}
                    </div>
                  ) : null}
                </li>
              )
            })}
          </ul>
        </Card>
      ) : null}
    </div>
  )
}
