import React, { useCallback, useRef, useState } from 'react'
import ReactMarkdown from 'react-markdown'
import EmojiPickerButton from '../comments/EmojiPickerButton'

function BoldIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5} className="h-4 w-4">
      <path strokeLinecap="round" strokeLinejoin="round" d="M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z" />
    </svg>
  )
}

function ItalicIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5} className="h-4 w-4">
      <line x1="19" y1="4" x2="10" y2="4" />
      <line x1="14" y1="20" x2="5" y2="20" />
      <line x1="15" y1="4" x2="9" y2="20" />
    </svg>
  )
}

function CodeIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} className="h-4 w-4">
      <polyline points="16 18 22 12 16 6" />
      <polyline points="8 6 2 12 8 18" />
    </svg>
  )
}

function LinkIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} className="h-4 w-4">
      <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
      <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
    </svg>
  )
}

function ListIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} className="h-4 w-4">
      <line x1="8" y1="6" x2="21" y2="6" />
      <line x1="8" y1="12" x2="21" y2="12" />
      <line x1="8" y1="18" x2="21" y2="18" />
      <circle cx="3" cy="6" r="1" fill="currentColor" stroke="none" />
      <circle cx="3" cy="12" r="1" fill="currentColor" stroke="none" />
      <circle cx="3" cy="18" r="1" fill="currentColor" stroke="none" />
    </svg>
  )
}

function QuoteIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" className="h-4 w-4">
      <path d="M4.583 17.321C3.553 16.227 3 15 3 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311C9.591 11.68 11 13.176 11 15c0 1.933-1.567 3.5-3.5 3.5-1.073 0-2.099-.456-2.917-1.179zM15.583 17.321C14.553 16.227 14 15 14 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311C20.591 11.68 22 13.176 22 15c0 1.933-1.567 3.5-3.5 3.5-1.073 0-2.099-.456-2.917-1.179z" />
    </svg>
  )
}

function ToolbarBtn({ title, onClick, children }) {
  return (
    <button
      type="button"
      title={title}
      onMouseDown={(event) => {
        event.preventDefault()
        onClick()
      }}
      className="flex h-7 w-7 items-center justify-center rounded-md text-white/40 transition-colors hover:bg-white/[0.08] hover:text-white/70"
    >
      {children}
    </button>
  )
}

export default function CommentForm({ placeholder = 'Write a comment…', submitLabel = 'Post', onSubmit, onCancel, compact = false }) {
  const [content, setContent] = useState('')
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState('')
  const [tab, setTab] = useState('write')
  const textareaRef = useRef(null)

  const wrapSelection = useCallback((before, after) => {
    const element = textareaRef.current
    if (!element) return

    const start = element.selectionStart
    const end = element.selectionEnd
    const selected = content.slice(start, end)
    const replacement = before + (selected || 'text') + after
    const next = content.slice(0, start) + replacement + content.slice(end)
    setContent(next)

    requestAnimationFrame(() => {
      const cursorPos = selected ? start + replacement.length : start + before.length
      const cursorEnd = selected ? start + replacement.length : start + before.length + 4
      element.selectionStart = cursorPos
      element.selectionEnd = cursorEnd
      element.focus()
    })
  }, [content])

  const prefixLines = useCallback((prefix) => {
    const element = textareaRef.current
    if (!element) return

    const start = element.selectionStart
    const end = element.selectionEnd
    const selected = content.slice(start, end)
    const lines = selected ? selected.split('\n') : ['']
    const prefixed = lines.map((line) => prefix + line).join('\n')
    const next = content.slice(0, start) + prefixed + content.slice(end)
    setContent(next)

    requestAnimationFrame(() => {
      element.selectionStart = start
      element.selectionEnd = start + prefixed.length
      element.focus()
    })
  }, [content])

  const insertLink = useCallback(() => {
    const element = textareaRef.current
    if (!element) return

    const start = element.selectionStart
    const end = element.selectionEnd
    const selected = content.slice(start, end)
    const isUrl = /^https?:\/\//.test(selected)
    const replacement = isUrl ? `[link](${selected})` : `[${selected || 'link'}](https://)`
    const next = content.slice(0, start) + replacement + content.slice(end)
    setContent(next)

    requestAnimationFrame(() => {
      if (isUrl) {
        element.selectionStart = start + 1
        element.selectionEnd = start + 5
      } else {
        const urlStart = start + replacement.length - 1
        element.selectionStart = urlStart - 8
        element.selectionEnd = urlStart - 1
      }
      element.focus()
    })
  }, [content])

  const insertAtCursor = useCallback((text) => {
    const element = textareaRef.current
    if (!element) {
      setContent((current) => current + text)
      return
    }

    const start = element.selectionStart ?? content.length
    const end = element.selectionEnd ?? content.length
    const next = content.slice(0, start) + text + content.slice(end)
    setContent(next)

    requestAnimationFrame(() => {
      element.selectionStart = start + text.length
      element.selectionEnd = start + text.length
      element.focus()
    })
  }, [content])

  const handleKeyDown = useCallback((event) => {
    const mod = event.ctrlKey || event.metaKey
    if (!mod) return

    switch (event.key.toLowerCase()) {
      case 'b':
        event.preventDefault()
        wrapSelection('**', '**')
        break
      case 'i':
        event.preventDefault()
        wrapSelection('*', '*')
        break
      case 'k':
        event.preventDefault()
        insertLink()
        break
      case 'e':
        event.preventDefault()
        wrapSelection('`', '`')
        break
      default:
        break
    }
  }, [insertLink, wrapSelection])

  const handleSubmit = async (event) => {
    event.preventDefault()
    const trimmed = content.trim()
    if (!trimmed || busy) return

    setBusy(true)
    setError('')
    try {
      await onSubmit?.(trimmed)
      setContent('')
      setTab('write')
    } catch (submitError) {
      setError(submitError?.message || 'Unable to post comment.')
    } finally {
      setBusy(false)
    }
  }

  return (
    <form className="space-y-3" onSubmit={handleSubmit}>
      <div className={`rounded-2xl border border-white/[0.08] bg-white/[0.04] transition-all duration-200 focus-within:border-white/[0.12] focus-within:shadow-lg focus-within:shadow-black/20 ${compact ? 'rounded-xl' : ''}`}>
        <div className="flex items-center justify-between border-b border-white/[0.06] px-3 py-1.5">
          <div className="flex items-center gap-1">
            <button
              type="button"
              onClick={() => setTab('write')}
              className={[
                'rounded-md px-3 py-1 text-xs font-medium transition-colors',
                tab === 'write' ? 'bg-white/[0.08] text-white' : 'text-white/40 hover:text-white/60',
              ].join(' ')}
            >
              Write
            </button>
            <button
              type="button"
              onClick={() => setTab('preview')}
              className={[
                'rounded-md px-3 py-1 text-xs font-medium transition-colors',
                tab === 'preview' ? 'bg-white/[0.08] text-white' : 'text-white/40 hover:text-white/60',
              ].join(' ')}
            >
              Preview
            </button>
          </div>

          <div className="flex items-center gap-1.5">
            <span
              className={[
                'text-[11px] tabular-nums font-medium transition-colors',
                content.length > 9000 ? 'text-amber-400/80' : 'text-white/20',
              ].join(' ')}
            >
              {content.length > 0 && `${content.length.toLocaleString()}/10,000`}
            </span>
            <EmojiPickerButton onEmojiSelect={insertAtCursor} disabled={busy} />
          </div>
        </div>

        {tab === 'write' && (
          <div className="flex items-center gap-0.5 border-b border-white/[0.04] px-3 py-1">
            <ToolbarBtn title="Bold (Ctrl+B)" onClick={() => wrapSelection('**', '**')}>
              <BoldIcon />
            </ToolbarBtn>
            <ToolbarBtn title="Italic (Ctrl+I)" onClick={() => wrapSelection('*', '*')}>
              <ItalicIcon />
            </ToolbarBtn>
            <ToolbarBtn title="Inline code (Ctrl+E)" onClick={() => wrapSelection('`', '`')}>
              <CodeIcon />
            </ToolbarBtn>
            <ToolbarBtn title="Link (Ctrl+K)" onClick={insertLink}>
              <LinkIcon />
            </ToolbarBtn>

            <div className="mx-1 h-4 w-px bg-white/[0.08]" />

            <ToolbarBtn title="Bulleted list" onClick={() => prefixLines('- ')}>
              <ListIcon />
            </ToolbarBtn>
            <ToolbarBtn title="Quote" onClick={() => prefixLines('> ')}>
              <QuoteIcon />
            </ToolbarBtn>
          </div>
        )}

        {tab === 'write' && (
          <textarea
            ref={textareaRef}
            value={content}
            onChange={(event) => setContent(event.target.value)}
            onKeyDown={handleKeyDown}
            rows={compact ? 3 : 4}
            maxLength={10000}
            placeholder={placeholder}
            disabled={busy}
            className="w-full resize-none bg-transparent px-4 py-3 text-sm leading-relaxed text-white/90 placeholder-white/35 outline-none transition disabled:opacity-50"
          />
        )}

        {tab === 'preview' && (
          <div className="min-h-[7rem] px-4 py-3">
            {content.trim() ? (
              <div className="prose prose-invert prose-sm max-w-none text-[13px] leading-relaxed text-white/80 [&_a]:text-accent [&_a]:no-underline hover:[&_a]:underline [&_code]:rounded [&_code]:bg-white/[0.08] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-[12px] [&_code]:text-amber-300/80 [&_blockquote]:border-l-2 [&_blockquote]:border-accent/40 [&_blockquote]:pl-3 [&_blockquote]:text-white/50 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:text-white/70 [&_strong]:text-white [&_em]:text-white/70 [&_p]:mb-2 [&_p:last-child]:mb-0">
                <ReactMarkdown
                  allowedElements={['p', 'strong', 'em', 'a', 'code', 'pre', 'ul', 'ol', 'li', 'blockquote', 'br']}
                  unwrapDisallowed
                  components={{
                    a: ({ href, children }) => (
                      <a href={href} target="_blank" rel="noopener noreferrer nofollow">{children}</a>
                    ),
                  }}
                >
                  {content}
                </ReactMarkdown>
              </div>
            ) : (
              <p className="text-sm italic text-white/25">Nothing to preview</p>
            )}
          </div>
        )}

        {tab === 'write' && (
          <div className="px-4 pb-2">
            <p className="text-[11px] text-white/15">
              Markdown supported · <kbd className="rounded bg-white/[0.06] px-1 py-0.5 text-[10px] text-white/25">Ctrl+B</kbd> bold · <kbd className="rounded bg-white/[0.06] px-1 py-0.5 text-[10px] text-white/25">Ctrl+I</kbd> italic · <kbd className="rounded bg-white/[0.06] px-1 py-0.5 text-[10px] text-white/25">Ctrl+K</kbd> link
            </p>
          </div>
        )}
      </div>

      {error ? <p className="text-sm text-rose-300">{error}</p> : null}

      <div className="flex items-center justify-between gap-3">
        <span className="text-xs text-white/35">Use emoji and markdown to match the rest of the site.</span>
        <div className="flex items-center gap-2">
          {onCancel ? (
            <button
              type="button"
              onClick={onCancel}
              className="rounded-full border border-white/[0.08] bg-white/[0.04] px-4 py-2 text-sm font-medium text-white/70 transition hover:bg-white/[0.08] hover:text-white"
            >
              Cancel
            </button>
          ) : null}
          <button
            type="submit"
            disabled={busy || content.trim().length === 0}
            className="rounded-full bg-sky-500 px-4 py-2 text-sm font-semibold text-white transition hover:bg-sky-400 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {busy ? 'Posting…' : submitLabel}
          </button>
        </div>
      </div>
    </form>
  )
}