// web/src/components/Message.tsx
import React, { useMemo, useState } from "react";
import { Button } from "./ui/button";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

import {
  Copy,
  ThumbsUp,
  ThumbsDown,
  ChevronDown,
  ChevronUp,
  Check,
  X,
} from "lucide-react";
import { Badge } from "./ui/badge";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "./ui/collapsible";
import { Textarea } from "./ui/textarea";
import type { Message as MessageType } from "../App";
import { toast } from "sonner";
import clareAvatar from "../assets/dfe44dab3ad8cd93953eac4a3e68bd1a5f999653.png";

// ✅ NEW: real API call
import { apiFeedback } from "../lib/api";

interface MessageProps {
  key?: React.Key;
  message: MessageType;
  showSenderInfo?: boolean; // For group chat mode
  isFirstGreeting?: boolean; // Indicates if this is the first greeting message
  showNextButton?: boolean; // For quiz mode
  onNextQuestion?: () => void; // For quiz mode
  chatMode?: "ask" | "review" | "quiz"; // Current chat mode

  // ✅ NEW: for feedback submission
  currentUserId?: string;
  docType?: string;
  learningMode?: string;
}

// 反馈标签选项
const FEEDBACK_TAGS = {
  "not-helpful": [
    "Code was incorrect",
    "Shouldn't have used Memory",
    "Don't like the personality",
    "Don't like the style",
    "Not factually correct",
  ],
  helpful: [
    "Accurate and helpful",
    "Clear explanation",
    "Good examples",
    "Solved my problem",
    "Well structured",
  ],
};

// ---- Markdown list normalization ----
function normalizeMarkdownLists(input: string) {
  if (!input) return input;

  return input
    .replace(/(^|\n)(\s*)(\d+\.)\s*\n+\s+/g, "$1$2$3 ")
    .replace(/(^|\n)(\s*)([-*+])\s*\n+\s+/g, "$1$2$3 ");
}

export function Message({
  message,
  showSenderInfo = false,
  isFirstGreeting = false,
  showNextButton = false,
  onNextQuestion,
  chatMode = "ask",

  // ✅ NEW
  currentUserId,
  docType = "Syllabus",
  learningMode = "general",
}: MessageProps) {
  const [feedback, setFeedback] = useState<"helpful" | "not-helpful" | null>(
    null
  );
  const [copied, setCopied] = useState(false);

  // ✅ References UI state
  const [referencesOpen, setReferencesOpen] = useState(false);

  const [showFeedbackArea, setShowFeedbackArea] = useState(false);
  const [feedbackType, setFeedbackType] = useState<
    "helpful" | "not-helpful" | null
  >(null);
  const [feedbackText, setFeedbackText] = useState("");
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [nextButtonClicked, setNextButtonClicked] = useState(false);

  const isUser = message.role === "user";
  const isWelcomeMessage =
    isFirstGreeting || message.id === "review-1" || message.id === "quiz-1";
  const shouldShowActions = isUser ? true : !isWelcomeMessage;

  const handleCopy = async () => {
    await navigator.clipboard.writeText(message.content);
    setCopied(true);
    toast.success("Message copied to clipboard");
    setTimeout(() => setCopied(false), 2000);
  };

  const handleFeedbackClick = (type: "helpful" | "not-helpful") => {
    if (feedback === type) {
      setFeedback(null);
      setShowFeedbackArea(false);
      setFeedbackType(null);
      setFeedbackText("");
      setSelectedTags([]);
    } else {
      setFeedback(type);
      setFeedbackType(type);
      setShowFeedbackArea(true);
    }
  };

  const handleFeedbackClose = () => {
    setShowFeedbackArea(false);
    setFeedbackType(null);
    setFeedbackText("");
    setSelectedTags([]);
  };

  const handleTagToggle = (tag: string) => {
    setSelectedTags((prev) =>
      prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
    );
  };

  // ✅ REAL submit to backend -> LangSmith dataset
  const handleFeedbackSubmit = async () => {
    if (!currentUserId || !currentUserId.trim()) {
      toast.error("Missing user_id; cannot submit feedback.");
      return;
    }
    if (!feedbackType) {
      toast.error("Please select Helpful / Not helpful.");
      return;
    }

    // UI uses "not-helpful" (dash), backend expects "not_helpful" (underscore)
    const rating = feedbackType === "helpful" ? "helpful" : "not_helpful";

    try {
      await apiFeedback({
        user_id: currentUserId,
        rating,
        assistant_message_id: message.id,
        assistant_text: message.content,
        user_text: "", // optional
        comment: feedbackText || "",
        tags: selectedTags,
        refs: message.references ?? [],
        learning_mode: chatMode === "ask" ? learningMode : chatMode,
        doc_type: docType,
        timestamp_ms: Date.now(),
      });

      toast.success("Thanks — feedback submitted.");
      handleFeedbackClose();
    } catch (e: any) {
      // eslint-disable-next-line no-console
      console.error("feedback submit failed:", e);
      toast.error(e?.message || "Failed to submit feedback.");
    }
  };

  const normalizedMarkdown = useMemo(() => {
    return normalizeMarkdownLists(message.content || "");
  }, [message.content]);

  const markdownClass = useMemo(() => {
    return [
      "text-base leading-relaxed break-words",
      " [&_p]:my-2",
      " [&_p:first-child]:mt-0",
      " [&_p:last-child]:mb-0",
      " [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-black/5 dark:[&_code]:bg-white/10",
      " [&_pre]:my-2 [&_pre]:p-3 [&_pre]:rounded-lg [&_pre]:overflow-auto [&_pre]:bg-black/5 dark:[&_pre]:bg-white/10",
      " [&_a]:underline [&_a]:underline-offset-2",
    ].join("");
  }, []);

  const renderBubbleContent = () => {
    if (isUser) {
      return (
        <p className="whitespace-pre-wrap text-base break-words">
          {message.content}
        </p>
      );
    }

    return (
      <ReactMarkdown
        remarkPlugins={[remarkGfm]}
        className={markdownClass}
        components={{
          p: ({ children }) => (
            <p className="my-2 whitespace-pre-wrap break-words">{children}</p>
          ),
          ul: ({ children }) => (
            <ul className="my-3 pl-6 space-y-2">{children}</ul>
          ),
          ol: ({ children }) => <ol className="my-3 space-y-4">{children}</ol>,
          li: ({ children, node }) => {
            const parent = (node as any)?.parent?.tagName;
            if (parent === "ol") {
              return (
                <li className="list-none">
                  <div className="flex items-start">
                    <span className="w-6 text-right pr-2 flex-shrink-0 font-medium">
                      {(node as any)?.index + 1}.
                    </span>
                    <div className="min-w-0">{children}</div>
                  </div>
                </li>
              );
            }
            return <li>{children}</li>;
          },
          strong: ({ children }) => (
            <strong className="font-semibold">{children}</strong>
          ),
          em: ({ children }) => <em className="italic">{children}</em>,
        }}
      >
        {normalizedMarkdown}
      </ReactMarkdown>
    );
  };

  const hasRefs = !!(message.references && message.references.length > 0);

  return (
    <div
      className={`flex gap-2 ${
        isUser && !showSenderInfo ? "justify-end" : "justify-start"
      } px-4`}
    >
      {/* Avatar */}
      {showSenderInfo && message.sender ? (
        <div className="w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 overflow-hidden bg-white">
          {message.sender.isAI ? (
            <img
              src={clareAvatar}
              alt="Clare"
              className="w-full h-full object-cover"
            />
          ) : (
            <img
              src={
                message.sender.avatar ||
                `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(
                  message.sender.email || message.sender.name
                )}`
              }
              alt={message.sender.name}
              className="w-full h-full object-cover"
            />
          )}
        </div>
      ) : !isUser ? (
        <div className="w-10 h-10 rounded-full overflow-hidden bg-white flex items-center justify-center flex-shrink-0">
          <img src={clareAvatar} alt="Clare" className="w-full h-full object-cover" />
        </div>
      ) : null}

      <div
        className={`group flex flex-col gap-2 ${
          isUser && !showSenderInfo ? "items-end" : "items-start"
        }`}
        style={{ maxWidth: "min(770px, calc(100% - 2rem))" }}
      >
        {/* Sender name in group chat */}
        {showSenderInfo && message.sender && (
          <div className="flex items-center gap-2 px-1">
            <span className="text-xs">{message.sender.name}</span>
            {message.sender.isAI && (
              <Badge variant="secondary" className="text-xs h-4 px-1">
                AI
              </Badge>
            )}
          </div>
        )}

        {/* Bubble (make it relative so we can anchor the ref box to bottom-left) */}
        <div
          className={`
            relative
            rounded-2xl px-4 py-3
            ${isUser && !showSenderInfo ? "bg-primary text-primary-foreground" : "bg-muted"}
          `}
        >
          {renderBubbleContent()}

          {/* ✅ Restore "left-bottom small reference box" */}
          {!isUser && hasRefs && (
            <div className="mt-3">
              <Collapsible open={referencesOpen} onOpenChange={setReferencesOpen}>
                <CollapsibleTrigger asChild>
                  <button
                    type="button"
                    className="
                      inline-flex items-center gap-1
                      rounded-md border border-border
                      bg-background/80 dark:bg-background/30
                      px-2 py-1
                      text-xs text-foreground
                      shadow-sm
                      hover:bg-background
                      transition
                    "
                    title="References"
                  >
                    {referencesOpen ? (
                      <ChevronUp className="h-3 w-3" />
                    ) : (
                      <ChevronDown className="h-3 w-3" />
                    )}
                    <span className="font-medium">References</span>
                    <span className="opacity-70">({message.references!.length})</span>
                  </button>
                </CollapsibleTrigger>

                <CollapsibleContent className="mt-2 space-y-1">
                  {message.references!.map((ref, index) => (
                    <div
                      key={index}
                      className="rounded-md border border-border bg-background/60 dark:bg-background/20 px-2 py-1 text-xs"
                    >
                      {ref}
                    </div>
                  ))}
                </CollapsibleContent>
              </Collapsible>
            </div>
          )}
        </div>

        {/* Next Question Button for Quiz Mode */}
        {!isUser &&
          showNextButton &&
          !nextButtonClicked &&
          chatMode === "quiz" &&
          onNextQuestion && (
            <div className="mt-2">
              <Button
                onClick={() => {
                  setNextButtonClicked(true);
                  onNextQuestion();
                }}
                className="bg-primary hover:bg-primary/90"
              >
                Next Question
              </Button>
            </div>
          )}

        {/* Message Actions */}
        {shouldShowActions && (
          <div className="flex items-center gap-1">
            <Button
              variant="ghost"
              size="icon"
              className={`h-7 w-7 rounded-md transition-all hover:bg-accent hover:scale-110 active:scale-95 ${
                copied
                  ? "bg-green-100 text-green-600 dark:bg-green-900/20 dark:text-green-400"
                  : ""
              }`}
              onClick={handleCopy}
              title="Copy"
            >
              {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
            </Button>

            {!isUser && (
              <>
                <Button
                  variant="ghost"
                  size="icon"
                  className={`h-7 w-7 rounded-md transition-all hover:bg-accent hover:scale-110 active:scale-95 ${
                    feedback === "helpful"
                      ? "bg-green-100 text-green-600 dark:bg-green-900/20 dark:text-green-400"
                      : ""
                  }`}
                  onClick={() => handleFeedbackClick("helpful")}
                  title="Helpful"
                >
                  <ThumbsUp className="h-4 w-4" />
                </Button>
                <Button
                  variant="ghost"
                  size="icon"
                  className={`h-7 w-7 rounded-md transition-all hover:bg-accent hover:scale-110 active:scale-95 ${
                    feedback === "not-helpful"
                      ? "bg-red-100 text-red-600 dark:bg-red-900/20 dark:text-red-400"
                      : ""
                  }`}
                  onClick={() => handleFeedbackClick("not-helpful")}
                  title="Not helpful"
                >
                  <ThumbsDown className="h-4 w-4" />
                </Button>
              </>
            )}
          </div>
        )}

        {/* Feedback Area */}
        {!isUser && showFeedbackArea && feedbackType && (
          <div className="w-full mt-2 bg-gray-50 dark:bg-gray-800/50 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
            <div className="flex items-start justify-between mb-4">
              <h4 className="text-sm font-medium text-gray-900 dark:text-gray-100">
                Tell us more:
              </h4>
              <Button
                variant="ghost"
                size="sm"
                className="h-6 w-6 p-0"
                onClick={handleFeedbackClose}
              >
                <X className="h-4 w-4" />
              </Button>
            </div>

            <div className="flex flex-wrap gap-2 mb-4">
              {FEEDBACK_TAGS[feedbackType].map((tag) => (
                <Button
                  key={tag}
                  variant={selectedTags.includes(tag) ? "default" : "outline"}
                  size="sm"
                  className="h-7 text-xs"
                  onClick={() => handleTagToggle(tag)}
                >
                  {tag}
                </Button>
              ))}
            </div>

            <Textarea
              className="min-h-[60px] mb-4 bg-gray-100/50 dark:bg-gray-700/50 border-gray-200 dark:border-gray-600"
              value={feedbackText}
              onChange={(e) => setFeedbackText(e.target.value)}
              placeholder="Additional feedback (optional)..."
            />

            <div className="flex justify-end gap-2">
              <Button variant="outline" size="sm" onClick={handleFeedbackClose}>
                Cancel
              </Button>
              <Button
                size="sm"
                onClick={handleFeedbackSubmit}
                disabled={selectedTags.length === 0 && !feedbackText.trim()}
              >
                Submit
              </Button>
            </div>
          </div>
        )}
      </div>

      {isUser && !showSenderInfo && (
        <div className="w-10 h-10 rounded-full overflow-hidden bg-white flex items-center justify-center flex-shrink-0">
          {message.sender ? (
            <img
              src={
                message.sender.avatar ||
                `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(
                  message.sender.email || message.sender.name
                )}`
              }
              alt={message.sender.name}
              className="w-full h-full object-cover"
            />
          ) : (
            <span className="text-base">👤</span>
          )}
        </div>
      )}
    </div>
  );
}
