'use client'

import { useEffect, useMemo, useRef, useState } from 'react'
import clsx from 'clsx'
import { usePathname } from 'next/navigation'
import Link from 'next/link'
import {
  MessageSquare,
  X,
  Send,
  Sparkles,
  Loader2,
  Lock,
  Trash2,
  TrendingUp,
  Search,
  Briefcase,
  Target,
  Zap,
} from 'lucide-react'
import { useStore } from '@/lib/store'

type Role = 'system' | 'user' | 'assistant'

type ChatMessage = {
  id: string
  role: Exclude<Role, 'system'>
  content: string
  createdAt: number
}

function uid() {
  return `${Date.now()}_${Math.random().toString(16).slice(2)}`
}

function getApiBase(): string {
  if (typeof window === 'undefined') return 'http://localhost:8000/api/v1'
  const { protocol, hostname } = window.location
  if (hostname === 'localhost' || hostname === '127.0.0.1') return 'http://localhost:8000/api/v1'
  if (/^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)/.test(hostname)) return `http://${hostname}:8000/api/v1`
  return `${protocol}//${hostname}/api/v1`
}

async function streamChat(opts: {
  messages: Array<{ role: Role; content: string }>
  path: string
  onDelta: (delta: string) => void
}): Promise<void> {
  const res = await fetch(`${getApiBase()}/llm/agent`, {
    method: 'POST',
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      messages: opts.messages,
      temperature: 0.5,
      stream: true,
      path: opts.path,
    }),
  })

  if (!res.ok) {
    const data = await res.json().catch(() => null)
    throw new Error(data?.detail || res.statusText || 'Request failed')
  }

  const reader = res.body?.getReader()
  if (!reader) throw new Error('Streaming not supported')

  const decoder = new TextDecoder('utf-8')
  let buffer = ''
  for (;;) {
    const { value, done } = await reader.read()
    if (done) break
    buffer += decoder.decode(value, { stream: true })

    const parts = buffer.split('\n\n')
    buffer = parts.pop() || ''
    for (const p of parts) {
      const line = p.split('\n').find((l) => l.startsWith('data: '))
      if (!line) continue
      const payload = line.replace(/^data:\s*/, '')
      if (payload === '[DONE]') return
      try {
        const json = JSON.parse(payload)
        const delta = json?.choices?.[0]?.delta?.content
        if (typeof delta === 'string' && delta.length) opts.onDelta(delta)
      } catch {
        // ignore
      }
    }
  }
}

function getTier(subscription: any): 'scout' | 'trader' | 'tycoon' {
  const t = (subscription?.tier || '').toLowerCase()
  if (t === 'trader') return 'trader'
  if (t === 'tycoon') return 'tycoon'
  return 'scout'
}

// Simple markdown-like formatting to clean HTML
function formatMessage(text: string): string {
  if (!text) return ''
  let html = text
    // Escape HTML
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    // Bold: **text** or __text__
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/__(.+?)__/g, '<strong>$1</strong>')
    // Italic: *text* or _text_ (but not inside words)
    .replace(/(?<!\w)\*([^*]+)\*(?!\w)/g, '<em>$1</em>')
    .replace(/(?<!\w)_([^_]+)_(?!\w)/g, '<em>$1</em>')
    // Inline code: `code`
    .replace(/`([^`]+)`/g, '<code class="bg-white/10 px-1 py-0.5 text-accent">$1</code>')
    // Line breaks
    .replace(/\n/g, '<br />')
    // Bullet points: - item or • item
    .replace(/<br \/>[-•]\s+/g, '<br />• ')
  return html
}

// Suggestion chips based on current page
function getSuggestions(path: string): Array<{ label: string; prompt: string }> {
  const p = (path || '').split('?')[0]
  
  if (p.startsWith('/terminal/hunt')) {
    return [
      { label: 'Ending soon', prompt: 'Show auctions ending in the next 2 hours' },
      { label: 'Find brandables', prompt: 'Generate 10 available 5-letter brandable .com domains' },
      { label: 'Trending now', prompt: 'What keywords are trending today?' },
    ]
  }
  if (p.startsWith('/terminal/market')) {
    return [
      { label: 'Best deals', prompt: 'Show the best deals under $100' },
      { label: 'Ending today', prompt: 'What auctions are ending today?' },
    ]
  }
  if (p.startsWith('/terminal/watchlist')) {
    return [
      { label: 'My watchlist', prompt: 'Show my watchlist' },
      { label: 'Analyze top', prompt: 'Analyze my most recently added domain' },
    ]
  }
  if (p.startsWith('/terminal/portfolio')) {
    return [
      { label: 'Portfolio ROI', prompt: 'What is my overall portfolio ROI?' },
      { label: 'Renewals', prompt: 'Which domains are up for renewal soon?' },
      { label: 'Top performers', prompt: 'Show my top 5 domains by value' },
    ]
  }
  if (p.startsWith('/terminal/sniper')) {
    return [
      { label: 'My alerts', prompt: 'Show my sniper alerts' },
      { label: 'Matching now', prompt: 'Are there auctions matching my alerts right now?' },
    ]
  }
  if (p.startsWith('/terminal/listing')) {
    return [
      { label: 'My listings', prompt: 'Show my active listings' },
      { label: 'New leads', prompt: 'Do I have any new leads?' },
    ]
  }
  if (p.startsWith('/terminal/inbox')) {
    return [
      { label: 'Unread count', prompt: 'How many unread messages do I have?' },
      { label: 'Recent threads', prompt: 'Show my recent inquiry threads' },
    ]
  }
  if (p.startsWith('/terminal/yield')) {
    return [
      { label: 'Yield stats', prompt: 'Show my yield dashboard stats' },
      { label: 'Top earners', prompt: 'Which domains are earning the most?' },
    ]
  }
  // Default
  return [
    { label: 'Market snapshot', prompt: 'Give me a quick market snapshot' },
    { label: 'Analyze domain', prompt: 'Analyze ' },
  ]
}

// Teaser examples for Scout
const TEASER_EXAMPLES = [
  { icon: Search, text: '"Analyze startup.io — should I buy?"' },
  { icon: TrendingUp, text: '"What auctions are ending in 2 hours?"' },
  { icon: Briefcase, text: '"What\'s my portfolio ROI?"' },
  { icon: Target, text: '"Find 5-letter .com brandables"' },
  { icon: Zap, text: '"Any new leads on my listings?"' },
]

export function HunterCompanion() {
  const pathname = usePathname()
  const { subscription, user } = useStore()
  const tier = getTier(subscription)
  const canChat = tier === 'trader' || tier === 'tycoon'

  const storageKey = useMemo(() => {
    const uidPart = user?.id ? String(user.id) : 'anon'
    return `pounce:hunter_companion:v2:${uidPart}`
  }, [user?.id])

  const [open, setOpen] = useState(false)
  const [input, setInput] = useState('')
  const [messages, setMessages] = useState<ChatMessage[]>([])
  const [sending, setSending] = useState(false)

  const listRef = useRef<HTMLDivElement | null>(null)
  const inputRef = useRef<HTMLInputElement | null>(null)

  // Load from localStorage
  useEffect(() => {
    if (!canChat) return
    try {
      const raw = localStorage.getItem(storageKey)
      if (raw) {
        const parsed = JSON.parse(raw)
        if (Array.isArray(parsed)) setMessages(parsed)
      }
    } catch {
      // ignore
    }
  }, [storageKey, canChat])

  // Save to localStorage
  useEffect(() => {
    if (!canChat) return
    try {
      localStorage.setItem(storageKey, JSON.stringify(messages.slice(-60)))
    } catch {
      // ignore
    }
  }, [messages, storageKey, canChat])

  // Auto-scroll
  useEffect(() => {
    if (!open) return
    const el = listRef.current
    if (el) el.scrollTop = el.scrollHeight
  }, [open, messages.length])

  // Focus input
  useEffect(() => {
    if (open && canChat) {
      setTimeout(() => inputRef.current?.focus(), 50)
    }
  }, [open, canChat])

  // Only show in terminal
  if (!pathname?.startsWith('/terminal')) return null

  const send = async (text?: string) => {
    const msg = (text || input).trim()
    if (!msg || sending || !canChat) return

    const userMsg: ChatMessage = { id: uid(), role: 'user', content: msg, createdAt: Date.now() }
    const assistantId = uid()
    setMessages((prev) => [...prev, userMsg, { id: assistantId, role: 'assistant', content: '', createdAt: Date.now() }])
    setInput('')
    setSending(true)

    const history = messages.slice(-20).map((m) => ({ role: m.role as Role, content: m.content }))

    try {
      await streamChat({
        messages: [...history, { role: 'user', content: msg }],
        path: pathname || '/terminal/hunt',
        onDelta: (delta) => {
          setMessages((prev) =>
            prev.map((m) => (m.id === assistantId ? { ...m, content: (m.content || '') + delta } : m))
          )
        },
      })
    } catch (e: any) {
      setMessages((prev) =>
        prev.map((m) =>
          m.id === assistantId ? { ...m, content: `Error: ${e?.message || 'Request failed'}` } : m
        )
      )
    } finally {
      setSending(false)
      setTimeout(() => inputRef.current?.focus(), 0)
    }
  }

  const clear = () => {
    setMessages([])
    try {
      localStorage.removeItem(storageKey)
    } catch {
      // ignore
    }
  }

  const suggestions = getSuggestions(pathname || '/terminal/hunt')

  return (
    <>
      {/* FAB */}
      <button
        onClick={() => setOpen(true)}
        className={clsx(
          'fixed bottom-5 right-5 z-[150] w-14 h-14 border flex items-center justify-center transition-all',
          'bg-[#0A0A0A]/90 backdrop-blur-md hover:scale-105',
          canChat ? 'border-accent/40 text-accent' : 'border-white/10 text-white/40'
        )}
        aria-label="Open Hunter Companion"
      >
        {canChat && <div className="absolute -top-1 -left-1 w-2 h-2 bg-accent animate-pulse" />}
        {!canChat && <Lock className="absolute -top-1 -right-1 w-3 h-3 text-white/40" />}
        <MessageSquare className="w-6 h-6" />
      </button>

      {/* Panel */}
      {open && (
        <div className="fixed inset-0 z-[160]">
          <div className="absolute inset-0 bg-black/85 backdrop-blur-sm" onClick={() => setOpen(false)} />

          <div className="absolute bottom-4 right-4 w-[92vw] max-w-[440px] h-[75vh] max-h-[760px] bg-[#0A0A0A] border border-white/[0.08] shadow-2xl flex flex-col overflow-hidden">
            {/* Header */}
            <div className="px-4 py-3 border-b border-white/[0.08] bg-[#050505] flex items-center justify-between shrink-0">
              <div className="min-w-0">
                <div className="flex items-center gap-2">
                  {canChat ? (
                    <div className="w-2 h-2 bg-accent animate-pulse" />
                  ) : (
                    <Lock className="w-3.5 h-3.5 text-white/40" />
                  )}
                  <span className="text-[11px] font-mono tracking-[0.15em] text-accent uppercase font-medium">
                    Hunter Companion
                  </span>
                  {!canChat && (
                    <span className="px-1.5 py-0.5 text-[9px] font-mono bg-white/5 border border-white/10 text-white/40">
                      LOCKED
                    </span>
                  )}
                </div>
                <div className="text-[10px] font-mono text-white/30 mt-0.5">
                  {canChat ? 'Domain trading AI assistant' : 'Upgrade to unlock'}
                </div>
              </div>
              <div className="flex items-center gap-1.5">
                {canChat && messages.length > 0 && (
                  <button
                    onClick={clear}
                    className="w-8 h-8 flex items-center justify-center text-white/40 hover:text-white/70 hover:bg-white/5 transition-colors"
                    title="Clear chat"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                )}
                <button
                  onClick={() => setOpen(false)}
                  className="w-8 h-8 flex items-center justify-center text-white/40 hover:text-white/70 hover:bg-white/5 transition-colors"
                  title="Close"
                >
                  <X className="w-4 h-4" />
                </button>
              </div>
            </div>

            {/* Body */}
            <div ref={listRef} className="flex-1 overflow-y-auto p-4">
              {!canChat ? (
                /* Scout Teaser */
                <div className="h-full flex flex-col">
                  <div className="flex-1 flex flex-col items-center justify-center text-center px-4">
                    <div className="w-16 h-16 border border-accent/20 bg-accent/5 flex items-center justify-center mb-4">
                      <Sparkles className="w-8 h-8 text-accent" />
                    </div>
                    <h3 className="text-sm font-medium text-white mb-2">AI Trading Assistant</h3>
                    <p className="text-xs font-mono text-white/50 leading-relaxed max-w-[280px] mb-6">
                      Get instant domain analysis, market insights, portfolio advice, and deal recommendations.
                    </p>

                    <div className="w-full space-y-2 mb-6">
                      {TEASER_EXAMPLES.map((ex, i) => (
                        <div
                          key={i}
                          className="flex items-center gap-3 px-3 py-2 bg-white/[0.02] border border-white/[0.06] text-left"
                        >
                          <ex.icon className="w-4 h-4 text-accent/60 shrink-0" />
                          <span className="text-[11px] font-mono text-white/50">{ex.text}</span>
                        </div>
                      ))}
                    </div>

                    <Link
                      href="/pricing"
                      className="px-6 py-3 bg-accent text-black text-xs font-bold uppercase tracking-wider hover:bg-accent/90 transition-colors"
                    >
                      Upgrade to Trader
                    </Link>
                    <p className="text-[10px] font-mono text-white/30 mt-3">
                      Available on Trader & Tycoon plans
                    </p>
                  </div>
                </div>
              ) : messages.length === 0 ? (
                /* Empty state for Trader/Tycoon */
                <div className="h-full flex flex-col items-center justify-center text-center px-4">
                  <div className="w-12 h-12 border border-accent/20 bg-accent/5 flex items-center justify-center mb-3">
                    <Sparkles className="w-6 h-6 text-accent" />
                  </div>
                  <h3 className="text-sm font-medium text-white mb-1">Ready to hunt</h3>
                  <p className="text-[11px] font-mono text-white/40 mb-4">
                    Ask me anything about domains, auctions, or your portfolio.
                  </p>

                  {/* Quick suggestions */}
                  <div className="flex flex-wrap justify-center gap-2">
                    {suggestions.map((s, i) => (
                      <button
                        key={i}
                        onClick={() => {
                          if (s.prompt.endsWith(' ')) {
                            setInput(s.prompt)
                            inputRef.current?.focus()
                          } else {
                            send(s.prompt)
                          }
                        }}
                        className="px-3 py-1.5 text-[10px] font-mono border border-accent/20 bg-accent/5 text-accent hover:bg-accent/10 transition-colors"
                      >
                        {s.label}
                      </button>
                    ))}
                  </div>
                </div>
              ) : (
                /* Chat messages */
                <div className="space-y-3">
                  {messages.map((m) => (
                    <div key={m.id} className={clsx('flex', m.role === 'user' ? 'justify-end' : 'justify-start')}>
                      <div
                        className={clsx(
                          'max-w-[88%] px-3 py-2 text-xs leading-relaxed',
                          m.role === 'user'
                            ? 'bg-accent/10 border border-accent/20 text-accent'
                            : 'bg-white/[0.03] border border-white/[0.08] text-white/80'
                        )}
                      >
                        {m.role === 'assistant' ? (
                          <div
                            className="prose-chat"
                            dangerouslySetInnerHTML={{ __html: formatMessage(m.content) || (sending ? '…' : '') }}
                          />
                        ) : (
                          <span className="font-mono">{m.content}</span>
                        )}
                      </div>
                    </div>
                  ))}

                  {/* Suggestion chips after messages */}
                  {!sending && messages.length > 0 && (
                    <div className="flex flex-wrap gap-1.5 pt-2">
                      {suggestions.slice(0, 2).map((s, i) => (
                        <button
                          key={i}
                          onClick={() => send(s.prompt)}
                          className="px-2 py-1 text-[9px] font-mono border border-white/10 text-white/40 hover:text-white/60 hover:border-white/20 transition-colors"
                        >
                          {s.label}
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              )}
            </div>

            {/* Input (only for Trader/Tycoon) */}
            {canChat && (
              <div className="p-3 border-t border-white/[0.08] bg-[#050505] shrink-0">
                <div className="flex items-center gap-2">
                  <input
                    ref={inputRef}
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' && !e.shiftKey) {
                        e.preventDefault()
                        send()
                      }
                    }}
                    placeholder="Ask about domains, auctions, portfolio…"
                    className="flex-1 px-3 py-2.5 bg-white/[0.03] border border-white/[0.08] text-white text-xs font-mono outline-none focus:border-accent/30 placeholder:text-white/25"
                    disabled={sending}
                  />
                  <button
                    onClick={() => send()}
                    disabled={sending || !input.trim()}
                    className={clsx(
                      'w-10 h-10 flex items-center justify-center border transition-all',
                      'disabled:opacity-40 disabled:cursor-not-allowed',
                      'border-accent/30 bg-accent/10 text-accent hover:bg-accent/20'
                    )}
                    aria-label="Send"
                  >
                    {sending ? <Loader2 className="w-4 h-4 animate-spin" /> : <Send className="w-4 h-4" />}
                  </button>
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* Styles for formatted messages */}
      <style jsx global>{`
        .prose-chat {
          font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
          font-size: 12px;
          line-height: 1.6;
        }
        .prose-chat strong {
          color: rgba(255, 255, 255, 0.95);
          font-weight: 600;
        }
        .prose-chat em {
          color: rgba(255, 255, 255, 0.7);
          font-style: italic;
        }
        .prose-chat code {
          background: rgba(255, 255, 255, 0.08);
          padding: 1px 4px;
          border-radius: 2px;
          font-size: 11px;
        }
      `}</style>
    </>
  )
}
