import { useMemo, type ReactNode } from 'react'
import { cn } from '../../lib/utils'
import { MarkdownBody } from '../markdown'
import { ReasoningStep } from '../reasoning-step'
import { StreamingMarkdownBlock } from '../streaming-markdown-block'
import { ImageGenerating as ImageGeneratingBase } from '../image-generating'
import { useResponseContext } from './context'
import type {
  ResponseThinkingProps,
  ResponseStepsProps,
  ResponseStepProps,
  ResponseContentProps,
  ResponseImageGeneratingProps,
  ResponseDefaultLayoutProps,
} from './types'

// ===== Response.Thinking =====

export function ResponseThinking({ className }: ResponseThinkingProps) {
  const ctx = useResponseContext()
  const effectiveShowThink = ctx.simulate
    ? ctx.showThink
    : ctx.phase === 'thinking' || ctx.phase === 'streaming'

  if (!effectiveShowThink) return null

  return <span className={className}>{ctx.thinkingIndicator}</span>
}

ResponseThinking.displayName = 'ResponseThinking'

// ===== Response.Steps =====

export function ResponseSteps({ className, children }: ResponseStepsProps) {
  return <div className={cn('flex flex-col gap-1', className)}>{children}</div>
}

ResponseSteps.displayName = 'ResponseSteps'

// ===== Response.Step =====

export function ResponseStepComponent({ step, status = 'completed' }: ResponseStepProps) {
  return (
    <ReasoningStep
      text={step.text}
      description={step.description}
      details={step.details}
      status={status}
    />
  )
}

ResponseStepComponent.displayName = 'ResponseStep'

// ===== Response.Content =====

export function ResponseContent({
  markdown,
  streaming = false,
  onStreamComplete,
  className,
}: ResponseContentProps) {
  const ctx = useResponseContext()
  const content = markdown ?? ctx.finalMarkdown

  if (streaming) {
    return (
      <div className={cn('mt-1', className)}>
        <StreamingMarkdownBlock
          content={content}
          isActive={streaming}
          onStreamComplete={onStreamComplete}
        />
      </div>
    )
  }

  return (
    <div className={cn('mt-1', className)}>
      <MarkdownBody>{content}</MarkdownBody>
    </div>
  )
}

ResponseContent.displayName = 'ResponseContent'

// ===== Response.ImageGenerating =====

export function ResponseImageGenerating({
  width = '320px',
  height = '240px',
  className,
}: ResponseImageGeneratingProps) {
  return <ImageGeneratingBase width={width} height={height} className={className} />
}

ResponseImageGenerating.displayName = 'ResponseImageGenerating'

// ===== Response.DefaultLayout =====

export function ResponseDefaultLayout({ className }: ResponseDefaultLayoutProps) {
  const ctx = useResponseContext()

  // 模拟模式：流式渲染 - useMemo 必须在条件语句前调用
  const contentElements = useMemo(() => {
    if (!ctx.simulate) return []

    const el: ReactNode[] = []
    const upTo = Math.min(ctx.visibleIndex, ctx.blocks.length - 1)
    let lastVisibleComposerIndex = -1
    for (let j = 0; j <= upTo; j++) {
      if (ctx.blocks[j]?.type === 'composer') lastVisibleComposerIndex = j
    }
    for (let i = 0; i <= upTo; i++) {
      const b = ctx.blocks[i]
      if (!b) continue
      if (b.type === 'think') {
        if (i === ctx.visibleIndex) {
          el.push(<span key={`think-${i}`}>{ctx.thinkingIndicator}</span>)
        }
        continue
      }
      if (b.type === 'composer' && b.step) {
        const inProgress = i === lastVisibleComposerIndex && !ctx.isSimDone
        el.push(
          <ReasoningStep
            key={i}
            text={b.step.text}
            description={b.step.description}
            details={b.step.details}
            status={inProgress ? 'in-progress' : 'completed'}
          />
        )
      }
      if (b.type === 'md' && b.md) {
        el.push(
          <div key={`md-${i}`} className="mt-1">
            <StreamingMarkdownBlock
              content={b.md}
              isActive={i === upTo}
              onStreamComplete={() => {
                ctx.setVisibleIndex((v) => Math.min(v + 1, ctx.blocks.length))
                if (i + 1 >= ctx.blocks.length) ctx.onSimulateComplete?.()
              }}
            />
          </div>
        )
      }
    }
    return el
  }, [ctx])

  // 静态内容元素（非模拟模式）
  const staticElements = useMemo(() => {
    if (ctx.simulate) return []
    const staticEl: ReactNode[] = []
    for (let i = 0; i < ctx.blocks.length; i++) {
      const b = ctx.blocks[i]
      if (!b) continue
      if (b.type === 'composer' && b.step) {
        staticEl.push(
          <ReasoningStep
            key={i}
            text={b.step.text}
            description={b.step.description}
            details={b.step.details}
            status="completed"
            disableExpandAnimation
          />
        )
      }
      if (b.type === 'md' && b.md) {
        staticEl.push(
          <div key={`md-${i}`} className="mt-1">
            <MarkdownBody>{b.md}</MarkdownBody>
          </div>
        )
      }
    }
    return staticEl
  }, [ctx])

  // imageGenerating 阶段
  if (ctx.phase === 'imageGenerating') {
    return (
      <div className={cn('flex flex-col gap-3 font-body', className)}>
        <ResponseImageGenerating />
      </div>
    )
  }

  // 非模拟模式：静态渲染
  if (!ctx.simulate) {
    return (
      <div className={cn('flex flex-col gap-3 font-body', className)}>
        <div className="flex flex-col gap-1">{staticElements}</div>
        {(ctx.phase === 'thinking' || ctx.phase === 'streaming') && ctx.thinkingIndicator}
      </div>
    )
  }

  // 模拟模式
  return (
    <div className={cn('flex flex-col gap-3 font-body', className)}>
      <div className="flex flex-col gap-1">{contentElements}</div>
    </div>
  )
}

ResponseDefaultLayout.displayName = 'ResponseDefaultLayout'
