'use client'

import { useState, useEffect } from 'react'
import type { ReactElement } from 'react'
import { ChevronDown, ChevronRight, XCircle, Loader2, Sparkles, FileDiff, Globe, Terminal, FileText, Search } from 'lucide-react'
import { cn } from '@/lib/utils'
import type { ToolRawContent } from '@/lib/types'
import { MarkdownRenderer } from '@/components/markdown-renderer'
import { formatTokens, formatTurnElapsed, getDomain, getToolDisplayName, getToolSummary, getToolParamPreview } from './chat-utils'

/* ── Tool icon by name ── */

export function getToolIcon(name: string): ReactElement {
  switch (name) {
    case 'WebSearch':
    case 'WebFetch':
      return <Globe size={14} className="text-green shrink-0" />
    case 'Bash':
      return <Terminal size={14} className="text-green shrink-0" />
    case 'Read':
    case 'Write':
    case 'Edit':
      return <FileText size={14} className="text-green shrink-0" />
    case 'Grep':
    case 'Glob':
    case 'ToolSearch':
      return <Search size={14} className="text-green shrink-0" />
    default:
      return <FileText size={14} className="text-green shrink-0" />
  }
}

/* ── Turn Stats ── */

export function TurnStats({ elapsedSeconds, inputTokens, outputTokens, streaming }: {
  elapsedSeconds: number
  inputTokens?: number
  outputTokens?: number
  streaming: boolean
}) {
  const hasTokens = (inputTokens != null && inputTokens > 0) || (outputTokens != null && outputTokens > 0)
  return (
    <div className="flex justify-end items-center gap-1.5 mt-2">
      <span className="text-[12px] text-muted font-mono tabular-nums">
        {formatTurnElapsed(elapsedSeconds)}
      </span>
      {hasTokens && (
        <>
          <span className="text-[12px] text-muted font-mono">·</span>
          <span className="text-[12px] text-muted font-mono tabular-nums">
            ↑{formatTokens(inputTokens || 0)} ↓{formatTokens(outputTokens || 0)}
          </span>
        </>
      )}
      {streaming && !hasTokens && (
        <Loader2 size={10} className="animate-spin text-muted" />
      )}
    </div>
  )
}

/* ── Thinking Panel (Collapsible) ── */

export function ThinkingPanel({ text, streaming }: { text: string; streaming?: boolean }) {
  const [expanded, setExpanded] = useState(false)
  if (!text && !streaming) return null

  return (
    <div className="rounded-lg border border-subtle bg-elevated overflow-hidden">
      <button
        onClick={() => setExpanded(!expanded)}
        className="flex items-center gap-2 w-full px-3 py-2 hover:bg-surface-hover transition-colors text-left"
      >
        {expanded ? (
          <ChevronDown size={14} className="text-tertiary shrink-0" />
        ) : (
          <ChevronRight size={14} className="text-tertiary shrink-0" />
        )}
        <Sparkles size={14} className="text-indigo shrink-0" />
        <span className="text-[13px] font-medium text-secondary">Thinking</span>
        {streaming && <Loader2 size={12} className="text-indigo animate-spin shrink-0" />}
      </button>
      <div
        className="grid transition-[grid-template-rows] duration-200 ease-in-out"
        style={{ gridTemplateRows: expanded ? '1fr' : '0fr' }}
      >
        <div className="overflow-hidden">
          <div className="px-3 pb-3 pt-0">
            <p className="text-[12px] text-secondary italic leading-relaxed whitespace-pre-wrap">{text}</p>
          </div>
        </div>
      </div>
    </div>
  )
}

/* ── Streaming cursor / waiting indicator ── */

export function StreamingCursor() {
  return <span className="inline-block w-2 h-4 bg-indigo/60 animate-pulse rounded-sm" />
}

/**
 * Loading indicator shown while waiting for the first response.
 * Shows "Thinking..." only when the model is actively using extended thinking.
 * Otherwise shows a generic spinner with elapsed time.
 */
export function WaitingIndicator({ label }: { label?: string }) {
  const [elapsed, setElapsed] = useState(0)

  useEffect(() => {
    const start = Date.now()
    const timer = setInterval(() => {
      setElapsed(Math.floor((Date.now() - start) / 1000))
    }, 1000)
    return () => clearInterval(timer)
  }, [])

  return (
    <div className="flex items-center gap-2 py-1">
      <Loader2 size={14} className="text-indigo animate-spin shrink-0" />
      {label && <span className="text-[13px] text-secondary">{label}</span>}
      <span className="text-[12px] text-muted font-mono tabular-nums">
        {formatTurnElapsed(elapsed)}
      </span>
    </div>
  )
}

/* ── Text Block with Markdown rendering ── */

export function TextBlock({ text, isLast }: { text: string; isLast: boolean }) {
  if (!text && isLast) return <StreamingCursor />

  return (
    <div>
      <MarkdownRenderer content={text} />
      {isLast && <StreamingCursor />}
    </div>
  )
}

/* ── Tool Result Content (rendered inside ToolUseBlock when expanded) ── */

export function ToolResultContent({ name, rawContent, resultContent, isError }: {
  name: string
  rawContent?: ToolRawContent
  resultContent?: string
  isError?: boolean
}) {
  // Web search: structured results with domain icon + title + domain link
  if (rawContent?.type === 'web_search') {
    return (
      <div className="border-t border-subtle bg-elevated">
        {rawContent.results.map((r, i) => {
          const domain = getDomain(r.url)
          return (
            <a
              key={i}
              href={r.url}
              target="_blank"
              rel="noopener noreferrer"
              className="flex items-center gap-2.5 px-3 py-1.5 border-b border-subtle last:border-b-0 hover:bg-surface-hover transition-colors"
            >
              <span className="w-4 h-4 rounded-sm bg-surface flex items-center justify-center text-[8px] text-muted font-semibold shrink-0 uppercase">
                {domain.charAt(0)}
              </span>
              <span className="text-[11px] text-secondary truncate flex-1">{r.title}</span>
              <span className="text-[10px] text-muted shrink-0">{domain}</span>
            </a>
          )
        })}
      </div>
    )
  }

  // Raw text content (from tool execution)
  if (rawContent?.type === 'text') {
    return <DiffOrCodeView text={rawContent.text} name={name} isError={isError} />
  }

  // Fallback: tool_use_summary text
  if (resultContent) {
    return <DiffOrCodeView text={resultContent} name={name} isError={isError} />
  }

  return null
}

/**
 * Renders tool result text as either a diff view (with color-coded +/- lines)
 * or plain code view, matching the Pencil design.
 */
export function DiffOrCodeView({ text, name, isError }: { text: string; name: string; isError?: boolean }) {
  const lines = text.split('\n')
  const hasDiffLines = lines.some(l => l.startsWith('+') || l.startsWith('-') || l.startsWith('@@'))
  const isDiff = hasDiffLines && (name === 'Edit' || name === 'Write' || lines.some(l => l.startsWith('---') || l.startsWith('+++')))

  if (isDiff) {
    // Count additions and deletions for the badge
    const added = lines.filter(l => l.startsWith('+') && !l.startsWith('+++')).length
    const removed = lines.filter(l => l.startsWith('-') && !l.startsWith('---')).length
    // Try to extract filename from diff header
    const fileHeader = lines.find(l => l.startsWith('---') || l.startsWith('+++'))
    const fileName = fileHeader?.replace(/^[+-]{3}\s+/, '').replace(/^[ab]\//, '') || ''

    return (
      <div className="border-t border-subtle overflow-hidden">
        {/* Diff Header */}
        {(fileName || added > 0 || removed > 0) && (
          <div className="flex items-center gap-2 px-3.5 py-2 bg-elevated">
            <FileDiff size={14} className="text-amber shrink-0" />
            {fileName && <span className="text-[12px] font-semibold text-primary truncate">{fileName}</span>}
            {(added > 0 || removed > 0) && (
              <span className="text-[10px] font-semibold text-green bg-green/10 px-1.5 py-0.5 rounded shrink-0">
                +{added} -{removed}
              </span>
            )}
          </div>
        )}
        {/* Diff Body */}
        <div className="px-3.5 py-2 max-h-[300px] overflow-y-auto">
          {lines.map((line, i) => {
            if (line.startsWith('---') || line.startsWith('+++') || line.startsWith('@@')) return null
            const lineColor = line.startsWith('+') ? 'text-green' : line.startsWith('-') ? 'text-coral' : 'text-secondary'
            return (
              <div key={i} className={cn('text-[11px] font-mono leading-[1.6] whitespace-pre-wrap', lineColor)}>
                {line || ' '}
              </div>
            )
          })}
        </div>
      </div>
    )
  }

  // Plain code/text view
  return (
    <pre className={cn(
      'px-3.5 py-2 text-[11px] font-mono overflow-x-auto max-h-[300px] overflow-y-auto border-t border-subtle whitespace-pre-wrap leading-[1.6]',
      isError ? 'bg-coral/5 text-coral' : 'bg-elevated text-secondary'
    )}>
      {text}
    </pre>
  )
}

/* ── Tool Use Block ── */

export function ToolUseBlock({ name, input, hasResult, isResultError, resultContent, rawContent, streaming }: {
  name: string
  input: Record<string, unknown>
  hasResult?: boolean
  isResultError?: boolean
  resultContent?: string
  rawContent?: ToolRawContent
  streaming?: boolean
}) {
  const [expanded, setExpanded] = useState(false)
  const summary = getToolSummary(name, input)
  const isDone = hasResult || !streaming
  const isExecuting = !isDone
  // Can expand if we have raw content or result text
  const canExpand = !!(rawContent || (hasResult && resultContent))
  const toolIcon = getToolIcon(name)
  // Show inline parameter preview for executing tools
  const paramPreview = isExecuting ? getToolParamPreview(name, input) : null

  return (
    <div className={cn(
      'rounded-lg border overflow-hidden my-1',
      isResultError ? 'border-coral/30' : isExecuting ? 'border-indigo/40 tool-executing' : 'border-subtle'
    )}>
      <button
        onClick={() => canExpand && setExpanded(!expanded)}
        className={cn(
          'flex items-center gap-2 w-full px-2.5 py-2.5 bg-surface transition-colors text-left',
          canExpand ? 'hover:bg-surface-hover cursor-pointer' : 'cursor-default'
        )}
      >
        {isDone ? (
          isResultError ? <XCircle size={14} className="text-coral shrink-0" /> : toolIcon
        ) : (
          <Loader2 size={14} className="text-indigo animate-spin shrink-0" />
        )}
        <span className={cn('text-[12px] font-semibold shrink-0', isDone && !isResultError ? 'text-green' : isResultError ? 'text-coral' : 'text-indigo')}>{getToolDisplayName(name)}</span>
        {summary && <span className="text-[12px] text-tertiary truncate flex-1">{summary}</span>}
        {rawContent?.type === 'web_search' && (
          <span className="text-[10px] text-muted shrink-0">{rawContent.results.length} results</span>
        )}
        {canExpand && (
          <ChevronDown size={12} className={cn('text-muted shrink-0 transition-transform ml-auto', expanded && 'rotate-180')} />
        )}
      </button>
      {/* Inline parameter preview — shown while tool is executing */}
      {paramPreview && isExecuting && (
        <div className="px-3 py-2 border-t border-subtle/50 bg-elevated">
          <pre className="text-[11px] text-muted font-mono whitespace-pre-wrap break-all leading-relaxed max-h-[120px] overflow-hidden">{paramPreview}</pre>
        </div>
      )}
      {canExpand && (
        <div
          className="grid transition-[grid-template-rows] duration-200 ease-in-out"
          style={{ gridTemplateRows: expanded ? '1fr' : '0fr' }}
        >
          <div className="overflow-hidden">
            <ToolResultContent
              name={name}
              rawContent={rawContent}
              resultContent={resultContent}
              isError={isResultError}
            />
          </div>
        </div>
      )}
    </div>
  )
}
