import { useState, useEffect, useRef, useCallback } from "react";
import { FiX, FiPaperclip } from "react-icons/fi";
import { IoSend } from "react-icons/io5";
import MentionSuggestions from "./MentionSuggestions";
import FileAttachmentPreview from "./FileAttachmentPreview";
import { getUserColor } from "../../utils/userColor";
import { useSelector } from "react-redux";

// Allowed file types
const ALLOWED_FILE_TYPES = [
  "application/pdf",
  "image/jpeg",
  "image/jpg",
  "image/png",
  "image/gif",
  "image/webp",
  "image/svg+xml",
];

// Max file size: 10MB
const MAX_FILE_SIZE = 10 * 1024 * 1024;

function ChatInput({
  isDark,
  placeholder,
  replyTo,
  onSend,
  onTyping,
  onStopTyping,
  typingSender,
  disabled,
}) {
  const [showMentions, setShowMentions] = useState(false);
  const [mentionFilter, setMentionFilter] = useState("");
  const [mentionStartOffset, setMentionStartOffset] = useState(-1);
  const [selectedMentionIndex, setSelectedMentionIndex] = useState(0);
  const [mentions, setMentions] = useState([]);
  const [isEmpty, setIsEmpty] = useState(true);
  const [selectedFiles, setSelectedFiles] = useState([]);
  const editorRef = useRef(null);
  const containerRef = useRef(null);
  const fileInputRef = useRef(null);

  // Get real users from Redux for mentions
  const { conversations } = useSelector((state) => state.dm);
  const { membersMap } = useSelector((state) => state.space);

  const allUsers = (() => {
    const users = [];
    const seenIds = new Set();

    // Add StudyBot as a mentionable user
    users.push({
      id: "studybot",
      name: "StudyBot",
      isBot: true,
    });
    seenIds.add("studybot");

    conversations.forEach((conv) => {
      const ou = conv.other_user;
      if (ou && !seenIds.has(ou.id)) {
        seenIds.add(ou.id);
        users.push({
          id: ou.id,
          name: ou.display_name || ou.name || "Unknown",
        });
      }
    });

    Object.values(membersMap).flat().forEach((member) => {
      if (member && !seenIds.has(member.id)) {
        seenIds.add(member.id);
        users.push({
          id: member.id,
          name: member.display_name || member.name || member.email || "Unknown",
        });
      }
    });

    return users;
  })();

  const placeholderText = placeholder;

  useEffect(() => {
    const handleClickOutside = (e) => {
      if (containerRef.current && !containerRef.current.contains(e.target)) {
        setShowMentions(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const getPlainText = useCallback(() => {
    if (editorRef.current) {
      return editorRef.current.innerText || "";
    }
    return "";
  }, []);

  const getCursorOffset = useCallback(() => {
    const selection = window.getSelection();
    if (!selection.rangeCount) return 0;

    const range = selection.getRangeAt(0);
    const preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(editorRef.current);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    return preCaretRange.toString().length;
  }, []);

  const checkForMention = useCallback(() => {
    const cursorOffset = getCursorOffset();
    const plainText = getPlainText();
    const textBeforeCursor = plainText.substring(0, cursorOffset);
    const mentionMatch = textBeforeCursor.match(/@([a-zA-Z0-9À-ỹ_]*)$/);

    if (mentionMatch) {
      setMentionFilter(mentionMatch[1]);
      setMentionStartOffset(cursorOffset - mentionMatch[0].length);
      setShowMentions(true);
      setSelectedMentionIndex(0);
    } else {
      setShowMentions(false);
      setMentionStartOffset(-1);
    }
  }, [getCursorOffset, getPlainText]);

  const handleInput = (e) => {
    checkForMention();
    const plainText = getPlainText();
    setIsEmpty(plainText.trim() === "");
    if (onTyping && plainText.trim().length > 0) {
      onTyping();
    }
  };

  const handleMentionSelect = (user) => {
    console.log("[ChatInput] Mention selected:", user);
    if (user === null) {
      setShowMentions(false);
      return;
    }

    const selection = window.getSelection();
    if (!selection.rangeCount) return;

    const plainText = getPlainText();
    const cursorOffset = getCursorOffset();

    const textBeforeCursor = plainText.substring(0, cursorOffset);
    const mentionMatch = textBeforeCursor.match(/@([a-zA-Z0-9À-ỹ_]*)$/);
    if (!mentionMatch) return;

    const atPosition = cursorOffset - mentionMatch[0].length;
    const beforeText = plainText.substring(0, atPosition);
    const afterText = plainText.substring(cursorOffset);

    const mentionColor = getUserColor(user.name);
    const mentionSpan = document.createElement("span");
    mentionSpan.className = "mention-tag";
    mentionSpan.contentEditable = "false";
    mentionSpan.style.cssText = `color: ${mentionColor}; font-weight: 600; cursor: pointer;`;
    mentionSpan.textContent = `@${user.name}`;
    mentionSpan.dataset.userId = user.id;
    mentionSpan.dataset.userName = user.name;

    // Rebuild editor content
    editorRef.current.innerHTML = "";

    if (beforeText) {
      editorRef.current.appendChild(document.createTextNode(beforeText));
    }

    editorRef.current.appendChild(mentionSpan);

    // Add a zero-width space followed by regular space after the mention
    const spaceNode = document.createTextNode("\u200B ");
    editorRef.current.appendChild(spaceNode);

    if (afterText) {
      editorRef.current.appendChild(document.createTextNode(afterText));
    }

    setMentions((prev) => [...prev, { id: user.id, name: user.name }]);

    // Focus editor and set cursor after the zero-width space + space
    editorRef.current.focus();

    // Place cursor at position 2 (after zero-width space and regular space)
    selection.collapse(spaceNode, 2);

    setShowMentions(false);

    // Log final content
    setTimeout(() => {
      console.log("[ChatInput] After mention, plainText:", getPlainText());
    }, 0);
  };

  const handleSend = () => {
    const content = getPlainText().trim();
    if (content || selectedFiles.length > 0) {
      if (onSend) {
        onSend(content, replyTo, selectedFiles);
        if (editorRef.current) {
          editorRef.current.innerHTML = "";
        }
        setMentions([]);
        setSelectedFiles([]);
        setIsEmpty(true);
      }
      setShowMentions(false);
      if (onStopTyping) onStopTyping();
    }
  };

  // Handle file selection
  const handleFileSelect = (e) => {
    const files = Array.from(e.target.files);
    const imageFiles = [];
    const nonImageFiles = [];

    files.forEach((file) => {
      // Check file type
      if (!ALLOWED_FILE_TYPES.includes(file.type)) {
        alert(
          `File "${file.name}" có định dạng không được hỗ trợ. Chỉ chấp nhận file PDF và hình ảnh.`,
        );
        return;
      }

      // Check file size
      if (file.size > MAX_FILE_SIZE) {
        alert(`File "${file.name}" vượt quá kích thước tối đa (10MB).`);
        return;
      }

      // Separate images (async) from non-images (sync)
      if (file.type.startsWith("image/")) {
        imageFiles.push(file);
      } else {
        nonImageFiles.push({
          file,
          name: file.name,
          type: file.type,
          size: file.size,
          preview: null,
        });
      }
    });

    // Add non-image files immediately
    if (nonImageFiles.length > 0) {
      setSelectedFiles((prev) => [...prev, ...nonImageFiles]);
    }

    // Process images asynchronously with Promise.all
    if (imageFiles.length > 0) {
      Promise.all(
        imageFiles.map(
          (file) =>
            new Promise((resolve) => {
              const reader = new FileReader();
              reader.onload = (e) => {
                resolve({
                  file,
                  name: file.name,
                  type: file.type,
                  size: file.size,
                  preview: e.target.result,
                });
              };
              reader.readAsDataURL(file);
            }),
        ),
      ).then((imageResults) => {
        setSelectedFiles((prev) => [...prev, ...imageResults]);
      });
    }

    // Reset file input
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  };

  // Remove selected file
  const handleRemoveFile = (index) => {
    setSelectedFiles((prev) => prev.filter((_, i) => i !== index));
  };

  // Trigger file input click
  const handleAttachmentClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  const handleKeyDown = (e) => {
    if (showMentions) {
      const filteredUsers = allUsers.filter((user) =>
        user.name.toLowerCase().includes(mentionFilter.toLowerCase()),
      );

      if (e.key === "ArrowDown") {
        e.preventDefault();
        e.stopPropagation();
        setSelectedMentionIndex((prev) =>
          prev < filteredUsers.length - 1 ? prev + 1 : prev,
        );
        return;
      }

      if (e.key === "ArrowUp") {
        e.preventDefault();
        e.stopPropagation();
        setSelectedMentionIndex((prev) => (prev > 0 ? prev - 1 : prev));
        return;
      }

      if (e.key === "Enter" || e.key === "Tab") {
        e.preventDefault();
        e.stopPropagation();
        if (filteredUsers[selectedMentionIndex]) {
          handleMentionSelect(filteredUsers[selectedMentionIndex]);
        }
        return;
      }

      if (e.key === "Escape") {
        e.preventDefault();
        e.stopPropagation();
        setShowMentions(false);
        return;
      }
    }

    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }

    if (e.key === "Backspace") {
      const selection = window.getSelection();
      if (!selection.rangeCount) return;

      const range = selection.getRangeAt(0);
      const cursorOffset = getCursorOffset();

      if (cursorOffset > 0 && range.startOffset === 0) {
        const prevNode = range.startContainer.previousSibling;
        if (
          prevNode &&
          prevNode.classList &&
          prevNode.classList.contains("mention-tag")
        ) {
          e.preventDefault();
          prevNode.remove();
          setMentions((prev) =>
            prev.filter((m) => m.id !== prevNode.dataset.userId),
          );
          return;
        }
      }

      if (cursorOffset > 0) {
        const plainText = getPlainText();
        const charBeforeCursor = plainText[cursorOffset - 1];

        if (charBeforeCursor === " ") {
          const textBeforeSpace = plainText.substring(0, cursorOffset - 1);
          const lastAtPos = textBeforeSpace.lastIndexOf("@");
          if (lastAtPos >= 0) {
            const potentialMention = textBeforeSpace.substring(lastAtPos);
            const mentionedUser = allUsers.find(
              (u) =>
                `@${u.name} ` === potentialMention ||
                `@${u.name}` === potentialMention,
            );
            if (mentionedUser) {
              e.preventDefault();
              const beforeMention = plainText.substring(0, lastAtPos);
              const afterMention = plainText.substring(cursorOffset);
              editorRef.current.innerHTML = "";
              if (beforeMention) {
                editorRef.current.appendChild(
                  document.createTextNode(beforeMention),
                );
              }
              if (afterMention) {
                editorRef.current.appendChild(
                  document.createTextNode(afterMention),
                );
              }
              const newRange = document.createRange();
              const textNode = editorRef.current.lastChild || editorRef.current;
              newRange.setStart(textNode, beforeMention.length);
              newRange.collapse(true);
              selection.removeAllRanges();
              selection.addRange(newRange);
              setMentions((prev) =>
                prev.filter((m) => m.id !== mentionedUser.id),
              );
              return;
            }
          }
        }
      }
    }
  };

  return (
    <div
      ref={containerRef}
      className="border-t shrink-0 relative"
      style={{
        borderColor: "var(--border-primary)",
        background: "var(--bg-surface-secondary)",
      }}
    >
      {/* Typing indicator — nằm TRÊN box input, absolute position */}
      {typingSender && (
        <div className="absolute top-[-28px] left-0 flex items-center gap-2 px-4 pt-2 pb-1">
          <span className="text-xs italic" style={{ color: "var(--primary)" }}>
            {typingSender} đang nhập
          </span>
          <span className="flex gap-0.5">
            <span
              className="w-1 h-1 rounded-full animate-bounce"
              style={{
                background: "var(--primary)",
                animationDelay: "0ms",
              }}
            />
            <span
              className="w-1 h-1 rounded-full animate-bounce"
              style={{
                background: "var(--primary)",
                animationDelay: "150ms",
              }}
            />
            <span
              className="w-1 h-1 rounded-full animate-bounce"
              style={{
                background: "var(--primary)",
                animationDelay: "300ms",
              }}
            />
          </span>
        </div>
      )}

      <div className="px-4 py-3">
        {/* File attachment preview */}
        {selectedFiles.length > 0 && (
          <FileAttachmentPreview
            files={selectedFiles}
            onRemove={handleRemoveFile}
            isDark={isDark}
          />
        )}

        {showMentions && (
          <div
            className="absolute bottom-full left-4 right-4 mb-2 rounded-lg shadow-lg border overflow-hidden z-50"
            style={{
              background: isDark ? "var(--bg-surface-secondary)" : "#fff",
              borderColor: "var(--border-primary)",
            }}
          >
            <MentionSuggestions
              onSelect={handleMentionSelect}
              isDark={isDark}
              filterText={mentionFilter}
              selectedIndex={selectedMentionIndex}
            />
          </div>
        )}

        <div
          className={`chat-input-wrapper border rounded-lg p-1 transition-colors relative ${disabled ? "opacity-50" : ""}`}
          style={{
            background: "var(--input-bg)",
            borderColor: "var(--input-border)",
          }}
          onFocus={(e) =>
            !disabled && (e.currentTarget.style.borderColor = "var(--primary)")
          }
          onBlur={(e) =>
            !disabled && (e.currentTarget.style.borderColor = "var(--input-border)")
          }
        >
          <div className="flex items-center gap-2">
            <div
              className={`chat-input-placeholder ${isEmpty ? "" : "hidden"}`}
            >
              {disabled ? "Chọn một cuộc trò chuyện để bắt đầu" : placeholderText}
            </div>
            <div
              ref={editorRef}
              contentEditable={!disabled}
              className="flex-1 border-none bg-transparent px-3 py-2 text-sm outline-none font-sans min-h-9 max-h-32 overflow-y-auto relative z-10"
              style={{
                color: "var(--input-text)",
              }}
              onInput={disabled ? undefined : handleInput}
              onKeyDown={disabled ? undefined : handleKeyDown}
              suppressContentEditableWarning
            />
            {/* Hidden file input */}
            <input
              ref={fileInputRef}
              type="file"
              accept=".pdf,.jpg,.jpeg,.png,.gif,.webp,.svg"
              multiple
              className="hidden"
              onChange={handleFileSelect}
              disabled={disabled}
            />
            <button
              type="button"
              disabled={disabled}
              className="w-9 h-9 border-none rounded-md cursor-pointer flex items-center justify-center transition-colors disabled:cursor-not-allowed"
              style={{
                background: "transparent",
                color: "var(--text-secondary)",
              }}
              onMouseEnter={(e) =>
                !disabled && (e.currentTarget.style.background = "var(--hover-primary)")
              }
              onMouseLeave={(e) =>
                !disabled && (e.currentTarget.style.background = "transparent")
              }
              onClick={handleAttachmentClick}
              title="Đính kèm file (PDF, hình ảnh)"
            >
              <FiPaperclip size={18} />
            </button>
            <button
              type="button"
              disabled={disabled}
              className="w-9 h-9 border-none rounded-md cursor-pointer flex items-center justify-center transition-colors disabled:cursor-not-allowed"
              style={{
                background: "var(--primary)",
                color: isDark ? "var(--bg-surface)" : "#fff",
              }}
              onMouseEnter={(e) =>
                !disabled && (e.currentTarget.style.background = "var(--primary-hover)")
              }
              onMouseLeave={(e) =>
                !disabled && (e.currentTarget.style.background = "var(--primary)")
              }
              onClick={handleSend}
              title="Gửi"
            >
              <IoSend size={18} />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default ChatInput;
