import { useState, useCallback, useEffect, useRef } from 'react';
import { searchMessages, type SearchResult } from '@/api/sessions';
import { useSessionStore } from '@/store/sessionStore';

interface SearchModalProps {
  isOpen: boolean;
  onClose: () => void;
}

/** 高亮文本中的关键词 */
function highlightText(text: string, keyword: string): React.ReactNode {
  if (!keyword.trim()) return text;
  const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  const regex = new RegExp(`(${escaped})`, 'gi');
  const parts = text.split(regex);
  return parts.map((part, i) =>
    regex.test(part) ? (
      <mark key={i} className="bg-yellow-200 dark:bg-yellow-700 text-inherit rounded px-0.5">
        {part}
      </mark>
    ) : (
      part
    )
  );
}

/** 截取围绕关键词的上下文片段 */
function snippetAroundKeyword(text: string, keyword: string, contextLen: number = 40): string {
  if (!keyword.trim()) {
    return text.length > 100 ? text.slice(0, 100) + '...' : text;
  }
  const idx = text.toLowerCase().indexOf(keyword.toLowerCase());
  if (idx === -1) return text.length > 100 ? text.slice(0, 100) + '...' : text;

  const start = Math.max(0, idx - contextLen);
  const end = Math.min(text.length, idx + keyword.length + contextLen);
  let snippet = text.slice(start, end);
  if (start > 0) snippet = '…' + snippet;
  if (end < text.length) snippet = snippet + '…';
  return snippet;
}

/** 格式化时间戳 */
function formatTime(ts: number): string {
  const date = new Date(ts);
  if (isNaN(date.getTime())) return '';
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMin = Math.floor(diffMs / 60000);
  if (diffMin < 1) return '刚刚';
  if (diffMin < 60) return `${diffMin}分钟前`;
  const diffHour = Math.floor(diffMin / 60);
  if (diffHour < 24) return `${diffHour}小时前`;
  return date.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
}

export function SearchModal({ isOpen, onClose }: SearchModalProps) {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<SearchResult[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [searched, setSearched] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const setCurrentSessionId = useSessionStore((s) => s.setCurrentSessionId);
  const loadMessagesFromServer = useSessionStore((s) => s.loadMessagesFromServer);

  const userId = localStorage.getItem('user_id') || '';

  const doSearch = useCallback(
    async (q: string) => {
      if (!q.trim()) {
        setResults([]);
        setTotal(0);
        setSearched(false);
        setLoading(false);
        return;
      }
      setLoading(true);
      setSearched(true);
      const resp = await searchMessages(q.trim(), userId, 50, 0);
      setResults(resp.results);
      setTotal(resp.total);
      setLoading(false);
    },
    [userId]
  );

  // 防抖输入
  const handleInputChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const val = e.target.value;
      setQuery(val);
      if (debounceRef.current) clearTimeout(debounceRef.current);
      debounceRef.current = setTimeout(() => {
        doSearch(val);
      }, 300);
    },
    [doSearch]
  );

  // 打开时聚焦输入框
  useEffect(() => {
    if (isOpen) {
      setQuery('');
      setResults([]);
      setTotal(0);
      setSearched(false);
      setLoading(false);
      setTimeout(() => inputRef.current?.focus(), 100);
    }
  }, [isOpen]);

  // 清理定时器
  useEffect(() => {
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, []);

  // 点击结果跳转到对应会话
  const handleResultClick = useCallback(
    async (result: SearchResult) => {
      onClose();
      setCurrentSessionId(result.session_id);
      await loadMessagesFromServer(result.session_id);
    },
    [onClose, setCurrentSessionId, loadMessagesFromServer]
  );

  // ESC 关闭
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isOpen) {
        onClose();
      }
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-start justify-center pt-[15vh]">
      {/* 背景遮罩 */}
      <div className="absolute inset-0 bg-black/30 backdrop-blur-sm" onClick={onClose} />

      {/* 搜索面板 */}
      <div className="relative w-full max-w-lg mx-4 bg-white dark:bg-gray-850 rounded-2xl shadow-2xl border border-pink-100 dark:border-pink-800 flex flex-col max-h-[60vh]">
        {/* 搜索输入框 */}
        <div className="flex items-center gap-3 px-4 py-3 border-b border-pink-100 dark:border-pink-800">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            className="h-5 w-5 text-gray-400 shrink-0"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
            />
          </svg>
          <input
            ref={inputRef}
            type="text"
            value={query}
            onChange={handleInputChange}
            placeholder="搜索历史消息…"
            className="flex-1 bg-transparent border-none outline-none text-sm text-gray-700 dark:text-gray-200 placeholder-gray-400"
          />
          {loading && (
            <div className="h-4 w-4 animate-spin rounded-full border-2 border-pink-400 border-t-transparent" />
          )}
          <button
            onClick={onClose}
            className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
          >
            <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        {/* 结果列表 */}
        <div className="flex-1 overflow-y-auto">
          {!searched && query.length === 0 && (
            <div className="py-12 text-center text-sm text-gray-400">
              输入关键词搜索你的历史消息
            </div>
          )}
          {searched && loading && results.length === 0 && (
            <div className="py-12 text-center text-sm text-gray-400">
              搜索中…
            </div>
          )}
          {searched && !loading && results.length === 0 && (
            <div className="py-12 text-center text-sm text-gray-400">
              未找到匹配的消息
            </div>
          )}
          {results.length > 0 && (
            <>
              <div className="px-4 py-2 text-xs text-gray-400 border-b border-pink-50 dark:border-pink-900">
                找到 {total} 条结果
              </div>
              {results.map((result) => (
                <button
                  key={result.message_id}
                  onClick={() => handleResultClick(result)}
                  className="w-full text-left px-4 py-3 hover:bg-pink-50 dark:hover:bg-pink-900/20 transition-colors border-b border-pink-50 dark:border-pink-900/50 last:border-b-0"
                >
                  <div className="flex items-center gap-2 mb-1">
                    <span className="text-xs font-medium text-pink-500 dark:text-pink-400 truncate max-w-[60%]">
                      {result.session_title || '新的对话'}
                    </span>
                    <span className="text-xs text-gray-400 ml-auto shrink-0">
                      {formatTime(result.created_at)}
                    </span>
                  </div>
                  <p className="text-sm text-gray-600 dark:text-gray-300 line-clamp-2">
                    {highlightText(snippetAroundKeyword(result.content, query), query)}
                  </p>
                </button>
              ))}
            </>
          )}
        </div>

        {/* 底部提示 */}
        <div className="px-4 py-2 border-t border-pink-100 dark:border-pink-800 text-xs text-gray-400 text-center">
          <kbd className="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 rounded text-xs">ESC</kbd> 关闭
          {' · '}
          点击结果跳转到对应会话
        </div>
      </div>
    </div>
  );
}
