import { useEffect, useRef, useState } from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { queryDocuments } from '../api/api'
import CitationPanel from './CitationPanel'
import { useToast } from './Toast'
import { useAuth } from '../contexts/AuthContext'

const WELCOME = {
  role: 'assistant',
  content: `Hello! I'm **ASK Docs**, your intelligent document assistant.\n\nUpload a document using the sidebar, then ask me anything about it — I'll answer with contextual accuracy, grounded in your document content.`,
  citations: [],
}

function mdToHtml(raw) {
  const escaped = raw
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')

  const lines = escaped.split('\n')
  const out = []
  let inUl = false, inOl = false, inPre = false

  for (let i = 0; i < lines.length; i++) {
    let l = lines[i]

    // fenced code blocks
    if (l.trim().startsWith('```')) {
      if (!inPre) { out.push('<pre>'); inPre = true }
      else         { out.push('</pre>'); inPre = false }
      continue
    }
    if (inPre) { out.push(l + '\n'); continue }

    // close lists on blank line
    if (!l.trim()) {
      if (inUl) { out.push('</ul>'); inUl = false }
      if (inOl) { out.push('</ol>'); inOl = false }
      out.push('<br/>')
      continue
    }

    // headings
    if (/^### /.test(l)) { out.push(`<h3>${l.slice(4)}</h3>`); continue }
    if (/^## /.test(l))  { out.push(`<h2>${l.slice(3)}</h2>`); continue }
    if (/^# /.test(l))   { out.push(`<h1>${l.slice(2)}</h1>`); continue }

    // unordered list
    if (/^[-*] /.test(l)) {
      if (!inUl) { out.push('<ul>'); inUl = true }
      l = `<li>${l.slice(2)}</li>`
      out.push(inlineMd(l)); continue
    }

    // ordered list
    if (/^\d+\. /.test(l)) {
      if (!inOl) { out.push('<ol>'); inOl = true }
      l = `<li>${l.replace(/^\d+\. /, '')}</li>`
      out.push(inlineMd(l)); continue
    }

    // close open lists
    if (inUl) { out.push('</ul>'); inUl = false }
    if (inOl) { out.push('</ol>'); inOl = false }

    out.push('<p>' + inlineMd(l) + '</p>')
  }
  if (inUl) out.push('</ul>')
  if (inOl) out.push('</ol>')
  return out.join('')
}

function inlineMd(s) {
  return s
    .replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>')
    .replace(/\*\*(.+?)\*\*/g,     '<strong>$1</strong>')
    .replace(/\*(.+?)\*/g,         '<em>$1</em>')
    .replace(/`([^`]+)`/g,         '<code>$1</code>')
    .replace(/~~(.+?)~~/g,         '<del>$1</del>')
}

function buildChatHtml(messages, userName, userPhoto) {
  const count = messages.length - 1
  const date  = new Date().toLocaleString('en-US', { dateStyle: 'long', timeStyle: 'short' })

  const rows = messages.slice(1).map((msg) => {
    const isUser = msg.role === 'user'

    const avatar = isUser
      ? (userPhoto
          ? `<img src="${userPhoto}" style="width:32px;height:32px;border-radius:50%;object-fit:cover;flex-shrink:0;border:2px solid #f3e8f0"/>`
          : `<div style="width:32px;height:32px;border-radius:50%;background:#8B004A;color:#fff;
               display:flex;align-items:center;justify-content:center;font-size:13px;
               font-weight:700;flex-shrink:0">${(userName || 'U')[0].toUpperCase()}</div>`)
      : `<div style="width:32px;height:32px;border-radius:50%;background:#8B004A;color:#fff;
           display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0">✦</div>`

    const name = isUser ? (userName || 'You') : 'ASK Docs'

    const body = isUser
      ? `<p style="margin:0;font-size:13px;line-height:1.65;color:#292524;white-space:pre-wrap">${msg.content.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}</p>`
      : mdToHtml(msg.content)

    const citBlock = (!isUser && msg.citations?.length)
      ? `<div style="margin-top:12px;padding-top:10px;border-top:1px dashed #e7d5e0">
           <p style="margin:0 0 6px;font-size:9px;font-weight:700;color:#8B004A;
             text-transform:uppercase;letter-spacing:.08em">Sources</p>
           ${msg.citations.map((c, ci) => `
             <div style="display:flex;align-items:baseline;gap:6px;margin-bottom:4px">
               <span style="min-width:16px;height:16px;border-radius:50%;background:#8B004A;
                 color:#fff;font-size:8px;font-weight:700;display:inline-flex;
                 align-items:center;justify-content:center">${ci+1}</span>
               <span style="font-size:10px;color:#57534e">
                 <strong style="color:#292524">${c.documentName}</strong>
                 &nbsp;·&nbsp; Page ${c.pageNumber}
                 &nbsp;·&nbsp; ${Math.round(c.score * 100)}% match
               </span>
             </div>`).join('')}
         </div>`
      : ''

    return `
      <div style="display:flex;gap:12px;margin-bottom:20px;align-items:flex-start;
        ${isUser ? 'flex-direction:row-reverse' : ''}">
        ${avatar}
        <div style="flex:1;max-width:88%">
          <p style="margin:0 0 5px;font-size:10px;font-weight:700;color:#8B004A;
            text-transform:uppercase;letter-spacing:.07em;
            ${isUser ? 'text-align:right' : ''}">${name}</p>
          <div style="padding:12px 16px;border-radius:${isUser ? '16px 4px 16px 16px' : '4px 16px 16px 16px'};
            background:${isUser ? '#f9f0f5' : '#ffffff'};
            border:1px solid ${isUser ? '#e8d0e0' : '#e7e5e4'};
            box-shadow:0 1px 3px rgba(0,0,0,.06)">
            <div class="md">${body}</div>
            ${citBlock}
          </div>
        </div>
      </div>`
  }).join('')

  return `<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8"/>
  <title>ASK Docs — Chat Export</title>
  <style>
    *{box-sizing:border-box;margin:0;padding:0}
    body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
         background:#f2efe7;color:#1c1917;padding:0}
    .page{max-width:760px;margin:0 auto;background:#fff;min-height:100vh;
          box-shadow:0 0 40px rgba(0,0,0,.08)}
    .header{background:linear-gradient(135deg,#8B004A 0%,#b5196b 100%);
            padding:28px 36px;color:#fff}
    .header-top{display:flex;align-items:center;gap:12px;margin-bottom:10px}
    .logo{width:36px;height:36px;border-radius:10px;background:rgba(255,255,255,.2);
          display:flex;align-items:center;justify-content:center;font-size:18px}
    .header h1{font-size:22px;font-weight:700;letter-spacing:-.3px}
    .header-meta{display:flex;gap:20px;font-size:11px;opacity:.75}
    .header-meta span{display:flex;align-items:center;gap:4px}
    .body{padding:28px 36px}
    .md h1{font-size:16px;font-weight:700;color:#8B004A;margin:10px 0 4px}
    .md h2{font-size:14px;font-weight:700;color:#8B004A;margin:8px 0 4px}
    .md h3{font-size:13px;font-weight:600;color:#57384d;margin:6px 0 3px}
    .md p{font-size:12.5px;line-height:1.7;color:#292524;margin-bottom:6px}
    .md ul,.md ol{padding-left:18px;margin-bottom:8px}
    .md li{font-size:12.5px;line-height:1.6;color:#292524;margin-bottom:2px}
    .md strong{font-weight:700;color:#1c1917}
    .md em{font-style:italic;color:#57534e}
    .md code{background:#fdf4f7;color:#8B004A;padding:1px 5px;border-radius:4px;
             font-size:11px;font-family:'Courier New',monospace;border:1px solid #f3dce8}
    .md pre{background:#1a0a10;color:#f2efe7;padding:14px 16px;border-radius:10px;
            font-size:11px;font-family:'Courier New',monospace;overflow:auto;
            margin:8px 0;line-height:1.6;white-space:pre-wrap;word-break:break-word}
    .md del{text-decoration:line-through;color:#a8a29e}
    .footer{padding:16px 36px;background:#faf8f6;border-top:1px solid #f0ece6;
            text-align:center;font-size:10px;color:#a8a29e}
    @media print{
      body{background:#fff}
      .page{box-shadow:none;max-width:100%}
      .header{-webkit-print-color-adjust:exact;print-color-adjust:exact}
    }
  </style>
</head>
<body>
  <div class="page">
    <div class="header">
      <div class="header-top">
        <div class="logo">✦</div>
        <div>
          <h1>ASK Docs</h1>
          <p style="font-size:11px;opacity:.7;margin-top:1px">AI Document Assistant</p>
        </div>
      </div>
      <div class="header-meta">
        <span>📅 ${date}</span>
        <span>💬 ${count} message${count !== 1 ? 's' : ''}</span>
        ${userName ? `<span>👤 ${userName}</span>` : ''}
      </div>
    </div>

    <div class="body">
      ${rows}
    </div>

    <div class="footer">
      Generated by ASK Docs &nbsp;·&nbsp; AI-powered document intelligence
    </div>
  </div>
</body></html>`
}

const CHAT_KEY = 'askdocs_chat'

export default function ChatInterface() {
  const toast = useToast()
  const { user } = useAuth()

  // Load from sessionStorage so chat survives F5 reloads.
  // sessionStorage is cleared automatically when the tab is closed.
  const [messages, setMessages] = useState(() => {
    try {
      const stored = sessionStorage.getItem(CHAT_KEY)
      if (stored) return JSON.parse(stored)
    } catch {}
    return [WELCOME]
  })

  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)
  const bottomRef = useRef(null)
  const textareaRef = useRef(null)

  // Persist messages to sessionStorage whenever they change
  useEffect(() => {
    try { sessionStorage.setItem(CHAT_KEY, JSON.stringify(messages)) } catch {}
  }, [messages])

  const downloadPDF = () => {
    if (messages.length <= 1) { toast.error('No chat to export yet.'); return }
    const win = window.open('', '_blank')
    if (!win) { toast.error('Allow pop-ups to download the chat PDF.'); return }
    const userName  = user?.firebaseUser?.displayName  || ''
    const userPhoto = user?.firebaseUser?.photoURL     || ''
    win.document.open()
    win.document.write(buildChatHtml(messages, userName, userPhoto))
    win.document.close()
    win.focus()
    setTimeout(() => { win.print(); win.close() }, 500)
  }

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages, loading])

  useEffect(() => {
    const ta = textareaRef.current
    if (!ta) return
    ta.style.height = 'auto'
    ta.style.height = `${Math.min(ta.scrollHeight, 160)}px`
  }, [input])

  const send = async () => {
    const question = input.trim()
    if (!question || loading) return
    setMessages(m => [...m, { role: 'user', content: question, citations: [] }])
    setInput('')
    setLoading(true)
    try {
      const data = await queryDocuments(question)
      setMessages(m => [...m, { role: 'assistant', content: data.answer, citations: data.citations ?? [] }])
    } catch (err) {
      const msg = err.response?.data?.error ?? err.message ?? 'Something went wrong.'
      toast.error(msg)
      setMessages(m => [...m, { role: 'assistant', content: `**Error:** ${msg}`, citations: [] }])
    } finally {
      setLoading(false)
    }
  }

  const handleKey = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send() }
  }

  return (
    <div className="flex flex-col h-full">
      {/* Toolbar */}
      <div className="flex items-center justify-between mb-3 shrink-0">
        <p className="text-[11px] text-stone-400 font-medium">
          {messages.length - 1} message{messages.length - 1 !== 1 ? 's' : ''}
        </p>
        {messages.length > 1 && (
          <div className="flex items-center gap-3">
            <button onClick={downloadPDF}
              className="text-[11px] text-stone-400 hover:text-brand flex items-center gap-1
                transition-colors font-medium">
              <DownloadIcon /> Download PDF
            </button>
            <button onClick={() => setMessages([WELCOME])}
              className="text-[11px] text-stone-400 hover:text-brand flex items-center gap-1
                transition-colors font-medium">
              <ClearIcon /> Clear chat
            </button>
          </div>
        )}
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto space-y-4 pr-1 pb-2">
        {messages.map((msg, i) => (
          <MessageBubble key={i} msg={msg} />
        ))}
        {loading && <ThinkingBubble />}
        {/* Nudge shown only when no conversation has started yet */}
        {messages.length === 1 && !loading && (
          <div className="mx-auto mt-2 max-w-xs rounded-xl border border-brand/20
            bg-brand/[0.04] px-4 py-3 text-center">
            <p className="text-xs font-semibold text-brand">Upload a document first</p>
            <p className="text-[11px] text-stone-400 mt-0.5">
              Use the sidebar to upload a PDF, DOCX, image, or spreadsheet, then ask away.
            </p>
          </div>
        )}
        <div ref={bottomRef} />
      </div>

      {/* Input area */}
      <div className="mt-3 shrink-0">
        <div className={`flex gap-2 items-end rounded-2xl border-2 transition-all duration-200
          bg-white shadow-card
          ${input ? 'border-brand/40 shadow-brand-sm' : 'border-stone-200'}`}>
          <textarea
            ref={textareaRef}
            rows={1}
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={handleKey}
            placeholder="Ask a question about your documents…"
            disabled={loading}
            className="flex-1 resize-none bg-transparent px-4 py-3 text-sm text-stone-800
              placeholder-stone-400 focus:outline-none leading-relaxed min-h-[44px] max-h-40"
          />
          <button onClick={send} disabled={!input.trim() || loading}
            className="shrink-0 m-1.5 w-9 h-9 flex items-center justify-center rounded-xl
              bg-brand hover:bg-brand-600 disabled:opacity-30 disabled:pointer-events-none
              text-white transition-all duration-150 active:scale-95 shadow-brand-sm
              disabled:shadow-none glow-brand-sm">
            <SendIcon />
          </button>
        </div>
        <p className="text-[10px] text-stone-400 mt-1.5 text-center">
          Enter to send · Shift+Enter for new line
        </p>
      </div>
    </div>
  )
}

function MessageBubble({ msg }) {
  const [copied, setCopied] = useState(false)
  const isUser = msg.role === 'user'

  const copy = () => {
    navigator.clipboard.writeText(msg.content)
    setCopied(true)
    setTimeout(() => setCopied(false), 1500)
  }

  return (
    <div className={`msg-enter flex ${isUser ? 'justify-end' : 'justify-start'} gap-2.5`}>
      {!isUser && <AssistantAvatar />}

      <div className={`max-w-[85%] group relative`}>
        <div className={`rounded-2xl px-4 py-3 text-sm leading-relaxed
          ${isUser
            ? 'bg-brand text-white rounded-br-none shadow-brand-sm'
            : 'bg-white border border-stone-200/80 text-stone-800 rounded-bl-none shadow-card'}`}>
          {isUser ? (
            <p className="whitespace-pre-wrap">{msg.content}</p>
          ) : (
            <>
              <div className="ai-prose max-w-none text-sm">
                <ReactMarkdown remarkPlugins={[remarkGfm]}>
                  {msg.content}
                </ReactMarkdown>
              </div>
              <CitationPanel citations={msg.citations} />
            </>
          )}
        </div>

        <button onClick={copy}
          className={`absolute top-2
            ${isUser ? 'left-0 -translate-x-full pr-1.5' : 'right-0 translate-x-full pl-1.5'}
            opacity-0 group-hover:opacity-100 transition-opacity`}>
          <div className="w-6 h-6 rounded-lg bg-white border border-stone-200 shadow-card
            hover:border-brand/30 flex items-center justify-center transition-colors">
            {copied ? <CheckIcon /> : <CopyIcon />}
          </div>
        </button>
      </div>

      {isUser && <UserAvatar />}
    </div>
  )
}

function ThinkingBubble() {
  return (
    <div className="msg-enter flex justify-start gap-2.5">
      <AssistantAvatar />
      <div className="bg-white border border-stone-200/80 rounded-2xl rounded-bl-none
        px-4 py-3.5 shadow-card">
        <div className="flex gap-1.5 items-center">
          {[0, 1, 2].map(i => (
            <span key={i} className="w-2 h-2 rounded-full bg-brand/60 thinking-dot"
              style={{ animationDelay: `${i * 0.2}s` }} />
          ))}
        </div>
      </div>
    </div>
  )
}

const AssistantAvatar = () => (
  <div className="w-7 h-7 rounded-xl bg-brand flex items-center justify-center
    shrink-0 mt-0.5 shadow-brand-sm">
    <svg className="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor"
      strokeWidth={2} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round"
        d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z"/>
    </svg>
  </div>
)

const UserAvatar = () => {
  const { user } = useAuth()
  const photoURL = user?.firebaseUser?.photoURL
  const displayName = user?.firebaseUser?.displayName
  const [imgFailed, setImgFailed] = useState(false)

  if (photoURL && !imgFailed) {
    return (
      <img src={photoURL} alt={displayName || 'You'} referrerPolicy="no-referrer"
        onError={() => setImgFailed(true)}
        className="w-7 h-7 rounded-xl object-cover shrink-0 mt-0.5 ring-2 ring-brand/20" />
    )
  }

  return (
    <div className="w-7 h-7 rounded-xl bg-brand/20 flex items-center justify-center shrink-0 mt-0.5">
      {displayName
        ? <span className="text-[11px] font-bold text-brand">{displayName[0].toUpperCase()}</span>
        : <svg className="w-4 h-4 text-stone-500" fill="currentColor" viewBox="0 0 20 20">
            <path fillRule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clipRule="evenodd"/>
          </svg>
      }
    </div>
  )
}

const SendIcon = () => (
  <svg className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth={2.5} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/>
  </svg>
)
const ClearIcon = () => (
  <svg className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"/>
  </svg>
)
const CopyIcon = () => (
  <svg className="w-3 h-3 text-stone-400" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"/>
  </svg>
)
const CheckIcon = () => (
  <svg className="w-3 h-3 text-brand" fill="none" stroke="currentColor" strokeWidth={2.5} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
  </svg>
)
const DownloadIcon = () => (
  <svg className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/>
  </svg>
)
