import { createContext, useContext, useState, useEffect, useMemo, useRef } from 'react'
import { ThinkingIndicator } from '../thinking-indicator'
import type {
  ResponseContextValue,
  ResponseRootProps,
  ResponseBlock,
  ResponseRound,
  ResponseStep,
} from './types'

// ===== Demo 数据 =====

const DEMO_STEP_1: ResponseStep = {
  text: 'Scanning local photo library',
  description: 'Indexing metadata and building a rename plan',
  details: [
    { type: 'action', action: 'Discover photos', desc: 'Found 1,000 images in /Pictures/Unsorted' },
    { type: 'action', action: 'Extract metadata', desc: 'Read EXIF timestamps, GPS, and camera model' },
    { type: 'action', action: 'Detect duplicates', desc: 'Hash-based matching + perceptual similarity' },
  ],
}

const DEMO_STEP_2: ResponseStep = {
  text: 'Classifying photos into albums',
  description: 'Clustering by time, location, and scene',
  details: [
    { type: 'action', action: 'Time buckets', desc: 'Group into events using temporal gaps' },
    { type: 'action', action: 'Location clusters', desc: 'Reverse geocode GPS into city/area labels' },
    { type: 'action', action: 'Scene tags', desc: 'Detect indoor/outdoor, portraits, food, and documents' },
  ],
}

const DEMO_STEP_3: ResponseStep = {
  text: 'Renaming files safely',
  description: 'Dry-run, collision check, then atomic move',
  details: [
    { type: 'action', action: 'Dry run', desc: 'Preview 1,000 rename operations' },
    { type: 'action', action: 'Collision handling', desc: 'Append counter suffix to avoid overwrites' },
    { type: 'action', action: 'Write changes', desc: 'Move files into album folders' },
  ],
}

const DEMO_ROUNDS: ResponseRound[] = [
  { step: DEMO_STEP_1, simpleMd: "I'm **scanning** your library and building the index. Found 1,000 photos in `Pictures/Unsorted`; EXIF and duplicates are being analyzed.\n\n" },
  { step: DEMO_STEP_2, simpleMd: "**Classifying** into albums by time, location, and scene. Time buckets and GPS labels are done; next I'll tag indoor/outdoor and document vs. portrait.\n\n" },
  { step: DEMO_STEP_3, simpleMd: "**Dry-run** is done and collision handling is in place. No overwrites; an audit log (CSV) is ready. Pending your confirmation to run the renames.\n\n" },
]

const DEMO_FINAL_MD = `## Plan

I will organize your **1,000 local photos** by building an index, clustering them into albums, and then performing a safe rename + move operation.

### Folder structure

\`\`\`text
Pictures/
  Organized/
    2026-01-18 — San Francisco — Golden Gate Park/
    2026-01-05 — Home — Documents/
    2025-12-31 — New Year's Eve/
    _Duplicates/
    _Unsorted/
\`\`\`

### Naming scheme

\`YYYY-MM-DD_HH-mm-ss__<Location>__<Scene>__<Counter>.<ext>\`

Example:

\`2026-01-18_15-42-11__San-Francisco__Outdoor__001.jpg\`

### Safety checks

- [x] Dry-run all operations
- [x] Detect collisions and append counters
- [x] Keep an audit log (CSV)
- [ ] Execute moves (requires confirmation)

---

## Next step

If you want, I can generate a **preview report** first (top 50 renames + album summary) before applying changes.
`

// ===== 工具函数 =====

function buildBlocks(rounds: ResponseRound[], finalMd: string): ResponseBlock[] {
  const blocks: ResponseBlock[] = []
  for (const r of rounds) {
    blocks.push({ type: 'think' })
    blocks.push({ type: 'composer', step: r.step })
    blocks.push({ type: 'md', md: r.simpleMd })
  }
  blocks.push({ type: 'think' })
  blocks.push({ type: 'md', md: finalMd })
  return blocks
}

// ===== Context =====

const ResponseContext = createContext<ResponseContextValue | null>(null)
ResponseContext.displayName = 'ResponseContext'

export function useResponseContext() {
  const ctx = useContext(ResponseContext)
  if (!ctx) throw new Error('Response compound components must be used within Response.Root')
  return ctx
}

// ===== Default ThinkingIndicator =====

const DEFAULT_THINK = <ThinkingIndicator text="Spark is thinking..." />

// ===== Provider =====

export function ResponseRootProvider({
  simulate = true,
  phase = 'thinking',
  rounds,
  finalMarkdown,
  onSimulateComplete,
  onStepChange,
  thinkingIndicator,
  children,
}: ResponseRootProps) {
  const allRounds = rounds ?? DEMO_ROUNDS
  const finalMd = finalMarkdown ?? DEMO_FINAL_MD
  const thinkNode = thinkingIndicator ?? DEFAULT_THINK

  const blocks = useMemo(() => buildBlocks(allRounds, finalMd), [allRounds, finalMd])
  const [visibleIndex, setVisibleIndex] = useState(0)
  const prevBlocksLengthRef = useRef(blocks.length)

  const isSimDone = simulate ? visibleIndex >= blocks.length - 1 : phase === 'done'
  const currentBlock = blocks[visibleIndex] ?? null
  const showThink = currentBlock?.type === 'think'

  // 步骤变化回调
  useEffect(() => {
    if (!simulate || blocks.length === 0) return
    const block = blocks[visibleIndex] ?? null
    if (block?.type === 'composer' && block.step) {
      onStepChange?.(block.step.text, block.step.toolType)
    } else if (block?.type === 'think') {
      onStepChange?.('Thinking...')
    }
    if (visibleIndex >= blocks.length) {
      onSimulateComplete?.()
    }
  }, [simulate, blocks, visibleIndex, onStepChange, onSimulateComplete])

  // blocks 变化时重置
  useEffect(() => {
    if (!simulate || blocks.length === 0) return
    if (prevBlocksLengthRef.current !== blocks.length) {
      prevBlocksLengthRef.current = blocks.length
      // 使用 requestAnimationFrame 避免同步 setState
      requestAnimationFrame(() => setVisibleIndex(0))
    }
  }, [simulate, blocks.length])

  // 定时器推进
  useEffect(() => {
    if (!simulate || blocks.length === 0) return
    const block = blocks[visibleIndex] ?? null
    if (block?.type === 'think' || block?.type === 'composer') {
      const id = window.setTimeout(() => setVisibleIndex((v) => Math.min(v + 1, blocks.length)), 580)
      return () => window.clearTimeout(id)
    }
  }, [simulate, blocks, visibleIndex])

  const ctxValue: ResponseContextValue = {
    phase,
    simulate,
    rounds: allRounds,
    finalMarkdown: finalMd,
    blocks,
    visibleIndex,
    setVisibleIndex,
    isSimDone,
    currentBlock,
    showThink,
    onSimulateComplete,
    onStepChange,
    thinkingIndicator: thinkNode,
  }

  return (
    <ResponseContext.Provider value={ctxValue}>
      {children}
    </ResponseContext.Provider>
  )
}

ResponseRootProvider.displayName = 'ResponseRoot'

// 导出 Demo 数据供测试使用
export { DEMO_ROUNDS, DEMO_FINAL_MD }
