'use client'

import React, { useState, isValidElement, ReactNode, createContext, useContext } from 'react'
import { cn } from '@/lib/utils'
import { Copy, Check } from '@phosphor-icons/react'

/**
 * Pre and Code components for code block styling
 */

// Context to detect if we're inside a CodeGroup
export const CodeGroupContext = createContext(false)

// Extract text content from nested React elements
function extractTextContent(node: ReactNode): string {
  if (typeof node === 'string') return node
  if (typeof node === 'number') return String(node)
  if (Array.isArray(node)) return node.map(extractTextContent).join('')
  if (isValidElement(node)) {
    const props = node.props as { children?: ReactNode }
    if (props.children) {
      return extractTextContent(props.children)
    }
  }
  return ''
}

// Get display name for language
function getDisplayName(language: string): string {
  const displayNames: Record<string, string> = {
    javascript: 'JavaScript',
    typescript: 'TypeScript',
    python: 'Python',
    java: 'Java',
    go: 'Go',
    rust: 'Rust',
    ruby: 'Ruby',
    php: 'PHP',
    csharp: 'C#',
    cpp: 'C++',
    c: 'C',
    swift: 'Swift',
    kotlin: 'Kotlin',
    bash: 'Bash',
    shell: 'Shell',
    json: 'JSON',
    yaml: 'YAML',
    html: 'HTML',
    css: 'CSS',
    sql: 'SQL',
    markdown: 'Markdown',
    text: 'Text',
    plaintext: 'Text',
  }
  return displayNames[language.toLowerCase()] || language.charAt(0).toUpperCase() + language.slice(1)
}

/**
 * Pre - Code block wrapper component
 * Styled to match CodeGroup default variant
 */
interface PreProps extends React.HTMLAttributes<HTMLPreElement> {
  children?: ReactNode
  'data-language'?: string
}

export function Pre({ children, className, 'data-language': dataLanguage, ...props }: PreProps) {
  const isInCodeGroup = useContext(CodeGroupContext)
  const [copied, setCopied] = useState(false)
  
  // If inside CodeGroup, render plain pre (CodeGroup handles styling)
  if (isInCodeGroup) {
    return (
      <pre className={cn('overflow-x-auto', className)} {...props}>
        {children}
      </pre>
    )
  }
  
  // Extract language from children's className or data attribute
  let language = dataLanguage || 'text'
  let content = ''
  
  if (isValidElement(children)) {
    const childProps = children.props as { className?: string; children?: ReactNode }
    const childClassName = childProps.className || ''
    const match = childClassName.match(/language-(\w+)/)
    if (match) {
      language = match[1]
    }
    content = extractTextContent(childProps.children)
  }
  
  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(content.trim())
      setCopied(true)
      setTimeout(() => setCopied(false), 2000)
    } catch (err) {
      console.error('Failed to copy:', err)
    }
  }
  
  const displayName = getDisplayName(language)
  
  // Standalone code block - styled like CodeGroup
  return (
    <div className="docs-code-block my-4 rounded-xl border border-zinc-800 overflow-hidden bg-[#1a1a1a]">
      {/* Header */}
      <div className="docs-code-header flex items-center justify-between bg-[#262626] px-2">
        <div className="flex overflow-x-auto">
          <div className="docs-code-tab px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white relative">
            {displayName}
            <span className="absolute bottom-0 left-0 right-0 h-0.5 bg-emerald-500 rounded-full" />
          </div>
        </div>
        
        {/* Copy button */}
        <div className="docs-code-actions flex items-center gap-1 pr-2">
          <button
            type="button"
            onClick={handleCopy}
            className={cn(
              'p-1.5 rounded text-zinc-500 hover:text-zinc-300',
              'hover:bg-zinc-700/50 transition-colors',
              'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50'
            )}
            title="Copy code"
          >
            {copied ? (
              <Check className="h-4 w-4 text-emerald-500" weight="bold" />
            ) : (
              <Copy className="h-4 w-4" />
            )}
          </button>
        </div>
      </div>
      
      {/* Code content */}
      <div className="docs-code-content overflow-x-auto">
        <pre
          className={cn(
            'p-4 m-0 bg-transparent text-sm',
            className
          )}
          {...props}
        >
          {children}
        </pre>
      </div>
    </div>
  )
}

/**
 * Code - Inline code styling
 */
interface CodeProps extends React.HTMLAttributes<HTMLElement> {
  children?: ReactNode
}

export function Code({ children, className, ...props }: CodeProps) {
  const isCodeBlock = className?.includes('language-')
  
  if (isCodeBlock) {
    return (
      <code className={cn(className, 'bg-transparent')} {...props}>
        {children}
      </code>
    )
  }
  
  // Inline code
  return (
    <code
      className={cn(
        'docs-inline-code px-1.5 py-0.5 rounded text-sm font-mono',
        'bg-zinc-800 text-zinc-200',
        className
      )}
      {...props}
    >
      {children}
    </code>
  )
}
