'use client'

import {
  forwardRef,
  useCallback,
  useRef,
  type FormEvent,
  type InputEvent,
  type KeyboardEvent,
  type TextareaHTMLAttributes,
} from 'react'
import { cn } from './utils'

export interface ChatInputProps extends Omit<
  TextareaHTMLAttributes<HTMLTextAreaElement>,
  'onSubmit'
> {
  onSubmit?: (value: string) => void
  loading?: boolean
  submitLabel?: string
  formClassName?: string
}

const ChatInput = forwardRef<HTMLTextAreaElement, ChatInputProps>(
  (
    {
      onSubmit,
      loading = false,
      submitLabel = 'Send',
      className,
      formClassName,
      onInput,
      onKeyDown,
      disabled,
      ...props
    },
    ref
  ) => {
    const internalRef = useRef<HTMLTextAreaElement | null>(null)
    const effectiveDisabled = loading || disabled === true

    const resize = useCallback(() => {
      const el = internalRef.current
      if (!el) return
      el.style.height = 'auto'
      el.style.height = `${Math.min(el.scrollHeight, 200)}px`
    }, [])

    const handleKeyDown = useCallback(
      (e: KeyboardEvent<HTMLTextAreaElement>) => {
        onKeyDown?.(e)
        if (e.defaultPrevented) return
        if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
          e.preventDefault()
          const value = internalRef.current?.value.trim()
          if (value && onSubmit && !effectiveDisabled) {
            onSubmit(value)
            if (internalRef.current) {
              internalRef.current.value = ''
              resize()
            }
          }
        }
      },
      [onKeyDown, onSubmit, effectiveDisabled, resize]
    )

    const handleInput = useCallback(
      (e: InputEvent<HTMLTextAreaElement>) => {
        onInput?.(e)
        resize()
      },
      [onInput, resize]
    )

    const handleSubmit = useCallback(
      (e: FormEvent) => {
        e.preventDefault()
        const value = internalRef.current?.value.trim()
        if (value && onSubmit && !effectiveDisabled) {
          onSubmit(value)
          if (internalRef.current) {
            internalRef.current.value = ''
            resize()
          }
        }
      },
      [onSubmit, effectiveDisabled, resize]
    )

    const setRef = useCallback(
      (el: HTMLTextAreaElement | null) => {
        internalRef.current = el
        if (typeof ref === 'function') ref(el)
        else if (ref) ref.current = el
      },
      [ref]
    )

    return (
      <form onSubmit={handleSubmit} className={cn('flex items-end gap-2', formClassName)}>
        <textarea
          ref={setRef}
          rows={1}
          placeholder="Type a message..."
          {...props}
          onInput={handleInput}
          onKeyDown={handleKeyDown}
          disabled={effectiveDisabled}
          className={cn(
            'flex-1 resize-none rounded-lg border border-border-glass bg-glass px-3 py-2 text-sm text-foreground placeholder:text-foreground-tertiary focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50',
            className
          )}
        />
        <button
          type="submit"
          disabled={effectiveDisabled}
          aria-label={submitLabel}
          className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-40"
        >
          {loading ? (
            <svg
              className="h-4 w-4 animate-spin"
              viewBox="0 0 24 24"
              fill="none"
              aria-hidden="true"
            >
              <circle
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                strokeWidth="3"
                strokeDasharray="31.42 31.42"
                strokeLinecap="round"
              />
            </svg>
          ) : (
            <svg
              className="h-4 w-4"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
              aria-hidden="true"
            >
              <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" />
            </svg>
          )}
        </button>
      </form>
    )
  }
)
ChatInput.displayName = 'ChatInput'
export { ChatInput }
