import React, { useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import CodeBlock from "./CodeBlock";
import { getAttachmentUrl } from "../api";
import {
  User, Flame, ChevronDown, ChevronRight, Brain, Copy, Check,
  Image, Film, FileText, ExternalLink,
} from "lucide-react";

const FILE_TYPE_ICONS = {
  image: Image, video: Film, document: FileText, text: FileText,
};

const MessageBubble = React.memo(function MessageBubble({ message, isStreaming, isThinking, token, onCommitFile }) {
  const { role, content, thinking_content, input_tokens, output_tokens, attachments } = message;
  const isUser = role === "user";
  const [showThinking, setShowThinking] = useState(false);
  const [copied, setCopied] = useState(false);
  const [expandedImage, setExpandedImage] = useState(null);

  function handleCopy() {
    navigator.clipboard.writeText(content || "");
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  }

  const hasAttachments = attachments && attachments.length > 0;

  return (
    <div className={`flex gap-3 animate-fade-in ${isUser ? "justify-end" : ""}`}>
      {!isUser && (
        <div className="shrink-0 mt-1">
          <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-anton-accent to-red-600 flex items-center justify-center shadow-lg shadow-anton-accent/10">
            <Flame size={16} className="text-white" />
          </div>
        </div>
      )}

      <div className={`max-w-[80%] ${isUser ? "order-first" : ""}`}>
        {thinking_content && (
          <div className="mb-2">
            <button onClick={() => setShowThinking(!showThinking)}
              className="flex items-center gap-1.5 text-xs text-purple-400 hover:text-purple-300 transition mb-1">
              <Brain size={12} />
              {showThinking ? <ChevronDown size={12} /> : <ChevronRight size={12} />}
              {isThinking ? <span className="thinking-pulse">Reasoning…</span> : <span>View reasoning</span>}
            </button>
            {(showThinking || isThinking) && (
              <div className="bg-purple-500/5 border border-purple-500/20 rounded-lg p-3 text-xs text-purple-300/80 font-mono whitespace-pre-wrap max-h-60 overflow-y-auto">
                {thinking_content}
                {isThinking && <span className="inline-block w-1.5 h-4 bg-purple-400 ml-0.5 animate-pulse" />}
              </div>
            )}
          </div>
        )}

        {hasAttachments && (
          <div className="mb-2 flex flex-wrap gap-2">
            {attachments.map((att) => {
              const Icon = FILE_TYPE_ICONS[att.file_type] || FileText;
              const url = getAttachmentUrl(att.id);
              if (att.file_type === "image") {
                return (
                  <div key={att.id} className="relative group">
                    <img src={`${url}?token=${token}`} alt={att.original_filename}
                      className="max-w-[240px] max-h-[200px] rounded-lg border border-anton-border object-cover cursor-pointer hover:opacity-90 transition"
                      onClick={() => setExpandedImage(expandedImage === att.id ? null : att.id)}
                      onError={(e) => { e.target.style.display = "none"; }} />
                    {expandedImage === att.id && (
                      <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-8 cursor-pointer"
                        onClick={() => setExpandedImage(null)}>
                        <img src={`${url}?token=${token}`} alt={att.original_filename}
                          className="max-w-full max-h-full object-contain rounded-lg" />
                      </div>
                    )}
                    <div className="absolute bottom-1 left-1 bg-black/60 text-[9px] text-white px-1.5 py-0.5 rounded">
                      {att.original_filename}
                    </div>
                  </div>
                );
              }
              return (
                <a key={att.id} href={`${url}?token=${token}`} target="_blank" rel="noopener noreferrer"
                  className="flex items-center gap-2 bg-anton-card border border-anton-border rounded-lg px-3 py-2 hover:border-anton-accent transition group">
                  <Icon size={16} className="shrink-0 text-blue-400" />
                  <div className="min-w-0">
                    <div className="text-xs text-white truncate max-w-[160px]">{att.original_filename}</div>
                    <div className="text-[10px] text-anton-muted">{(att.file_size / 1024).toFixed(0)}KB</div>
                  </div>
                  <ExternalLink size={12} className="text-anton-muted group-hover:text-anton-accent shrink-0" />
                </a>
              );
            })}
          </div>
        )}

        <div className={`rounded-2xl px-4 py-3 ${
          isUser ? "bg-anton-accent text-white rounded-br-md" : "bg-anton-card border border-anton-border rounded-bl-md"
        }`}>
          {isUser ? (
            <div className="text-sm whitespace-pre-wrap">{_stripPrefixes(content)}</div>
          ) : (
            <div className="prose-anton text-sm">
              <ReactMarkdown remarkPlugins={[remarkGfm]} components={{
                code({ node, inline, className, children, ...props }) {
                  const match = /language-(\S+)/.exec(className || "");
                  const rawLang = match?.[1] || "";
                  if (inline) return <code className={className} {...props}>{children}</code>;
                  let lang = rawLang, filename = null;
                  if (rawLang.includes(":")) {
                    const idx = rawLang.indexOf(":");
                    lang = rawLang.slice(0, idx);
                    filename = rawLang.slice(idx + 1);
                  }
                  return (
                    <CodeBlock
                      language={lang}
                      filename={filename}
                      code={String(children).replace(/\n$/, "")}
                      onCommitFile={onCommitFile}
                    />
                  );
                },
                pre({ children }) { return <>{children}</>; },
              }}>
                {content || ""}
              </ReactMarkdown>
              {isStreaming && !isThinking && (
                <span className="inline-block w-1.5 h-4 bg-anton-accent ml-0.5 animate-pulse" />
              )}
            </div>
          )}
        </div>

        {!isUser && !isStreaming && content && (
          <div className="flex items-center gap-3 mt-1.5 px-1">
            <button onClick={handleCopy} className="flex items-center gap-1 text-[11px] text-anton-muted hover:text-white transition">
              {copied ? <Check size={11} className="text-anton-success" /> : <Copy size={11} />}
              {copied ? "Copied" : "Copy"}
            </button>
            {(input_tokens > 0 || output_tokens > 0) && (
              <span className="text-[11px] text-anton-muted">
                {input_tokens?.toLocaleString()}↓ / {output_tokens?.toLocaleString()}↑ tokens
              </span>
            )}
          </div>
        )}
      </div>

      {isUser && (
        <div className="shrink-0 mt-1">
          <div className="w-8 h-8 rounded-lg bg-anton-card border border-anton-border flex items-center justify-center">
            <User size={16} className="text-anton-muted" />
          </div>
        </div>
      )}
    </div>
  );
});

function _stripPrefixes(text) {
  if (!text) return "";
  return text.replace(/^\[(?:Image|Video|Document|File):\s[^\]]*\]\n?/gm, "").trim();
}

export default MessageBubble;