import React, { useState, useRef, useEffect, useCallback, type KeyboardEvent } from 'react';
import { FaSpinner, FaUser } from 'react-icons/fa';
import type { MentionUser } from '../services/commentService';
import API_CONFIG from '../config/api';

interface MentionInputProps {
  value: string;
  onChange: (text: string) => void;
  onSubmit: (html: string) => void;
  placeholder?: string;
  disabled?: boolean;
  mentionUsers: MentionUser[];
  mentionLoading: boolean;
  onMentionSearch: (query: string) => void;
  posting?: boolean;
}

interface InsertedMention {
  startIndex: number;
  displayText: string;
  userId: string;
  fullName: string;
}

const MentionInput: React.FC<MentionInputProps> = ({
  value,
  onChange,
  onSubmit,
  placeholder = 'Type a comment… Use @ to mention someone',
  disabled = false,
  mentionUsers,
  mentionLoading,
  onMentionSearch,
  posting = false,
}) => {
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const [showMentionDropdown, setShowMentionDropdown] = useState(false);
  const [mentionQuery, setMentionQuery] = useState('');
  const [mentionStartPos, setMentionStartPos] = useState<number | null>(null);
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [insertedMentions, setInsertedMentions] = useState<InsertedMention[]>([]);

  const updateDropdownPosition = useCallback(() => {
    const ta = textareaRef.current;
    if (!ta) return;
    ta.getBoundingClientRect();
    ta.offsetParent?.getBoundingClientRect();
  }, []);

  const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const newValue = e.target.value;
    const cursorPos = e.target.selectionStart ?? 0;
    onChange(newValue);

    const textBeforeCursor = newValue.substring(0, cursorPos);
    const lastAtIndex = textBeforeCursor.lastIndexOf('@');

    if (lastAtIndex !== -1) {
      const charBefore = lastAtIndex > 0 ? newValue[lastAtIndex - 1] : ' ';
      if (charBefore === ' ' || charBefore === '\n' || lastAtIndex === 0) {
        const query = textBeforeCursor.substring(lastAtIndex + 1);
        if (!query.includes(' ') || query.length <= 30) {
          setShowMentionDropdown(true);
          setMentionQuery(query);
          setMentionStartPos(lastAtIndex);
          setSelectedIndex(0);
          onMentionSearch(query);
          updateDropdownPosition();
          return;
        }
      }
    }

    setShowMentionDropdown(false);
    setMentionStartPos(null);
  };

  const insertMention = useCallback(
    (user: MentionUser) => {
      if (mentionStartPos === null) return;

      const ta = textareaRef.current;
      const before = value.substring(0, mentionStartPos);
      const cursorPos = ta?.selectionStart ?? mentionStartPos + mentionQuery.length + 1;
      const after = value.substring(cursorPos);

      const displayText = user.full_name || user.name;
      const newText = `${before}@${displayText} ${after}`;

      setInsertedMentions((prev) => [
        ...prev,
        {
          startIndex: mentionStartPos,
          displayText,
          userId: user.name,
          fullName: user.full_name || user.name,
        },
      ]);

      onChange(newText);
      setShowMentionDropdown(false);
      setMentionStartPos(null);
      setMentionQuery('');

      setTimeout(() => {
        if (ta) {
          ta.focus();
          const newPos = before.length + displayText.length + 2;
          ta.selectionStart = newPos;
          ta.selectionEnd = newPos;
        }
      }, 0);
    },
    [mentionStartPos, mentionQuery, value, onChange]
  );

  const buildHtml = useCallback(
    (text: string): string => {
      let html = text;
      const baseUrl = API_CONFIG.BASE_URL || window.location.origin;
      const sorted = [...insertedMentions].sort((a, b) => b.startIndex - a.startIndex);

      for (const m of sorted) {
        const mentionText = `@${m.displayText}`;
        const idx = html.indexOf(mentionText);
        if (idx === -1) continue;

        const profileUrl = `${baseUrl}/app/user-profile/${encodeURIComponent(m.userId)}`;
        const mentionHtml =
          `<span class="mention" ` +
          `data-id="${m.userId}" ` +
          `data-value="&lt;a href=&quot;${profileUrl}&quot; target=&quot;_blank&quot;&gt;${m.fullName}" ` +
          `data-denotation-char="@" ` +
          `data-is-group="false" ` +
          `data-link="${profileUrl}">` +
          `\uFEFF<span contenteditable="false">` +
          `<span class="ql-mention-denotation-char">@</span>` +
          `<a href="${profileUrl}" target="_blank">${m.fullName}</a>` +
          `</span>\uFEFF</span>`;

        html = html.substring(0, idx) + mentionHtml + html.substring(idx + mentionText.length);
      }

      html = html.replace(/\n/g, '<br>');
      return `<div class="ql-editor read-mode"><p>${html}</p></div>`;
    },
    [insertedMentions]
  );

  const handleSubmit = () => {
    const trimmed = value.trim();
    if (!trimmed || posting) return;
    const html = buildHtml(trimmed);
    onSubmit(html);
    setInsertedMentions([]);
  };

  const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
    if (showMentionDropdown && mentionUsers.length > 0) {
      switch (e.key) {
        case 'ArrowDown':
          e.preventDefault();
          setSelectedIndex((prev) => Math.min(prev + 1, mentionUsers.length - 1));
          return;
        case 'ArrowUp':
          e.preventDefault();
          setSelectedIndex((prev) => Math.max(prev - 1, 0));
          return;
        case 'Enter':
          e.preventDefault();
          insertMention(mentionUsers[selectedIndex]);
          return;
        case 'Escape':
          e.preventDefault();
          setShowMentionDropdown(false);
          return;
      }
    }

    if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
      e.preventDefault();
      handleSubmit();
    }
  };

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(e.target as Node) &&
        textareaRef.current &&
        !textareaRef.current.contains(e.target as Node)
      ) {
        setShowMentionDropdown(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  useEffect(() => {
    if (!dropdownRef.current) return;
    const item = dropdownRef.current.querySelector(`[data-idx="${selectedIndex}"]`);
    item?.scrollIntoView({ block: 'nearest' });
  }, [selectedIndex]);

  const baseUrl = API_CONFIG.BASE_URL || '';

  return (
    <div className="relative">
      {showMentionDropdown && (
        <div
          ref={dropdownRef}
          className="absolute z-50 bottom-full mb-1 w-72 max-h-52 overflow-y-auto
                     bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600
                     rounded-lg shadow-lg"
          style={{ left: 0 }}
        >
          {mentionLoading && mentionUsers.length === 0 ? (
            <div className="flex items-center gap-2 px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
              <FaSpinner className="animate-spin" size={12} />
              Searching users…
            </div>
          ) : mentionUsers.length === 0 ? (
            <div className="px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
              No users found
            </div>
          ) : (
            mentionUsers.map((user, idx) => (
              <button
                key={user.name}
                data-idx={idx}
                type="button"
                className={`w-full flex items-center gap-2.5 px-3 py-2 text-left transition-colors
                  ${idx === selectedIndex
                    ? 'bg-teal-50 dark:bg-teal-900/30 text-teal-800 dark:text-teal-200'
                    : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700'
                  }`}
                onMouseEnter={() => setSelectedIndex(idx)}
                onMouseDown={(e) => {
                  e.preventDefault();
                  insertMention(user);
                }}
              >
                {user.user_image ? (
                  <img
                    src={`${baseUrl}${user.user_image}`}
                    alt=""
                    className="w-7 h-7 rounded-full object-cover flex-shrink-0"
                  />
                ) : (
                  <div className="w-7 h-7 rounded-full bg-gray-200 dark:bg-gray-600 flex items-center justify-center flex-shrink-0">
                    <FaUser className="text-gray-500 dark:text-gray-400" size={10} />
                  </div>
                )}
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-medium truncate">
                    {user.full_name || user.name}
                  </p>
                  <p className="text-xs text-gray-500 dark:text-gray-400 truncate">
                    {user.name}
                  </p>
                </div>
              </button>
            ))
          )}
        </div>
      )}

      <div className="flex gap-2 items-end">
        <textarea
          ref={textareaRef}
          value={value}
          onChange={handleChange}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          disabled={disabled || posting}
          rows={3}
          className="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
                     bg-white dark:bg-gray-700 text-gray-900 dark:text-white text-sm
                     disabled:bg-gray-100 dark:disabled:bg-gray-800
                     focus:outline-none focus:ring-2 focus:ring-teal-500 resize-none
                     placeholder:text-gray-400 dark:placeholder:text-gray-500"
        />
        <button
          type="button"
          onClick={handleSubmit}
          disabled={disabled || posting || !value.trim()}
          className="px-4 py-2 bg-teal-600 hover:bg-teal-700 disabled:bg-teal-600/50
                     text-white text-sm font-medium rounded-lg transition-colors
                     disabled:cursor-not-allowed flex items-center gap-1.5 h-10 flex-shrink-0"
        >
          {posting ? (
            <>
              <FaSpinner className="animate-spin" size={12} />
              <span>Posting…</span>
            </>
          ) : (
            <span>Comment</span>
          )}
        </button>
      </div>

      <p className="mt-1 text-[10px] text-gray-400 dark:text-gray-500">
        <kbd className="px-1 py-0.5 bg-gray-100 dark:bg-gray-700 rounded text-[9px]">@</kbd> to mention
        &nbsp;·&nbsp;
        <kbd className="px-1 py-0.5 bg-gray-100 dark:bg-gray-700 rounded text-[9px]">Ctrl+Enter</kbd> to post
      </p>
    </div>
  );
};

export default MentionInput;
