/**
 * @Description: Scroll List
 * @Version: 0.0.1
 * @Author: yujiangping
 * @Date: 2025-11-18 16:19:58
 * @LastEditors: yujiangping
 * @LastEditTime: 2025-12-22 13:47:53
 */
import { FileOutlined, FieldTimeOutlined, EditOutlined } from '@ant-design/icons';
import { Skeleton } from 'antd';
import { useTranslation } from 'react-i18next';
import type { RecallTestData } from '@/views/KnowledgeBase/types';
import { NoData } from './noData';
import { formatDateTime } from '@/utils/format';
import InfiniteScroll from 'react-infinite-scroll-component';
import RbMarkdown from '@/components/Markdown';
import { useMemo } from 'react';

interface RecallTestResultProps {
  data: RecallTestData[];
  showEmpty?: boolean;
  hasMore?: boolean;
  loadMore?: () => void;
  loading?: boolean;
  scrollableTarget?: string;
  editable?: boolean; // Whether editable
  onItemClick?: (item: RecallTestData, index: number) => void; // Click item callback
  parserMode?: number; // Parser mode, 1 means QA format
}

const RecallTestResult = ({ 
  data, 
  showEmpty = true,
  hasMore = false,
  loadMore,
  loading = false,
  scrollableTarget,
  editable = false,
  onItemClick,
  parserMode = 0,
}: RecallTestResultProps) => {
  const { t } = useTranslation();

  // Parse QA format content
  const parseQAContent = (content: string) => {
    if (!content || parserMode !== 1) return null;
    
    const qaRegex = /question:\s*(.*?)\s*answer:\s*(.*?)$/s;
    const match = content.match(qaRegex);
    
    if (match) {
      const question = match[1]?.trim() || '';
      const answer = match[2]?.trim() || '';
      return { question, answer };
    }
    
    return null;
  };

  // Format QA content for display
  const formatQAContent = (question: string, answer: string) => {
    return `**${t('knowledgeBase.question')}:** ${question}\n**${t('knowledgeBase.answer')}:** ${answer}`;
  };

  // Check if content is valid HTML
  const isValidHTML = (content: string): boolean => {
    if (!content) return false;
    // Check if content contains HTML tags
    const htmlTagPattern = /<[^>]+>/;
    return htmlTagPattern.test(content);
  };

  // Render content with HTML or Markdown fallback
  const renderTextContent = useMemo(() => {
    return (content: string) => {
      // Try to render as HTML first
      if (isValidHTML(content)) {
        try {
          return (
            <div 
              className='rb:prose rb:prose-sm rb:max-w-none'
              dangerouslySetInnerHTML={{ __html: content }}
            />
          );
        } catch (error) {
          console.warn('HTML parsing failed, falling back to Markdown:', error);
        }
      }
      
      // Fallback to Markdown rendering
      return <RbMarkdown content={content} showHtmlComments={true} />;
    };
  }, []);

  const handleItemClick = (e: React.MouseEvent, item: RecallTestData, index: number) => {
    // Check if the click is on an image or image-related element
    const target = e.target as HTMLElement;
    
    // Check if clicked on image itself, image container, preview layer, close button or SVG icon
    if (
      target.tagName === 'IMG' || 
      target.tagName === 'SVG' || // SVG icon
      target.tagName === 'PATH' || // SVG path
      target.closest('.ant-image') ||
      target.closest('.ant-image-preview') ||
      target.closest('.ant-image-preview-wrap') ||
      target.closest('.ant-image-preview-operations') ||
      target.closest('.anticon') || // Ant Design icon
      target.classList.contains('ant-image-img') ||
      target.classList.contains('ant-image-mask') ||
      target.classList.contains('ant-image-preview-close') ||
      target.classList.contains('anticon')
    ) {
      return;
    }
    
    if (editable && onItemClick) {
      onItemClick(item, index);
    }
  };

  // Get color class based on score
  const getScoreColorClass = (score: number): string => {
    const percentage = score * 100;
    if (percentage >= 90) {
      return 'rb:text-[#155EEF]';
    } else if (percentage >= 80) {
      return 'rb:text-[#369F21]';
    } else {
      return 'rb:text-[#FF5D34]';
    }
  };

  // Show skeleton when initial loading
  if (loading && data.length === 0) {
    return (
      <div className='rb:flex rb:flex-col'>
        <div className='rb:flex rb:items-center rb:justify-start rb:gap-2 rb:mb-4'>
          <span className='rb:text-lg rb:font-medium'>{t('knowledgeBase.recallResult')}</span>
        </div>
        <Skeleton active paragraph={{ rows: 3 }} />
        <Skeleton active paragraph={{ rows: 3 }} className='rb:mt-4' />
        <Skeleton active paragraph={{ rows: 3 }} className='rb:mt-4' />
      </div>
    );
  }

  if (data.length === 0 && showEmpty) {
    return (
      <NoData
        title={t('knowledgeBase.recallTestUnStart')}
        subTitle={t('knowledgeBase.recallTestUnStartSubTitle')}
      />
    );
  }

  if (data.length === 0) {
    return null;
  }

  const renderContent = () => (
    <div className='rb:flex rb:flex-col rb:mt-4'>
      {data.map((item, index) => {
        const score = item.metadata?.score ?? 1;
        const scorePercentage = score * 100;
        const colorClass = getScoreColorClass(score);
        const showScore = item.metadata?.score !== null && item.metadata?.score !== undefined;
        
        return (
          <div
            key={`${item.metadata?.sort_id || index}-${index}`}
            className={`rb:flex rb:flex-col rb:mb-4 rb:rounded-xl rb:bg-[#F6F6F6] rb:p-4 rb:pt-2 rb:pb-3 rb:relative rb:group ${editable ? 'rb:cursor-pointer rb:transition-all hover:rb:border-[#155EEF] hover:rb:shadow-md' : ''}`}
            onClick={(e) => handleItemClick(e, item, index)}
          >
            {editable && (
              <div className='rb:absolute rb:top-2 rb:right-2 rb:opacity-0 group-hover:rb:opacity-100 rb:transition-opacity'>
                <EditOutlined className='rb:text-[#155EEF] rb:text-base' />
              </div>
            )}
            <div className='rb:flex rb:items-center rb:justify-between'>
              {showScore && (
                <span className={`${colorClass} rb:text-xl rb:font-semibold`}>
                  {scorePercentage.toFixed(1)}% {t('knowledgeBase.similarity')}
                </span>
              )}
              <div className={`rb:flex rb:mt-2 rb:flex rb:items-end rb:justify-end rb:gap-4 ${!showScore ? 'rb:w-full' : ''}`}>
                <span className='rb:text-gray-800'>
                  <FileOutlined /> {item.metadata?.file_name || '-'}
                </span>
                <span className='rb:text-gray-500 rb:text-xs rb:bg-[#DFDFDF] rb:px-1 rb:py-[2px] rb:rounded'>
                  chunk_{item.metadata?.sort_id || index}
                </span>
              </div>
            </div>
            <div className='rb:flex rb:text-left rb:px-4 rb:py-3 rb:bg-white rb:rounded-lg rb:mt-2'>
              <div className='rb:text-gray-800 rb:text-sm rb:whitespace-pre-wrap rb:break-words rb:w-full'>
                {(() => {
                  const qaContent = parseQAContent(item.page_content);
                  if (qaContent) {
                    const formattedContent = formatQAContent(qaContent.question, qaContent.answer);
                    return renderTextContent(formattedContent);
                  }
                  return renderTextContent(item.page_content);
                })()}
              </div>
            </div>
            {item.metadata?.file_created_at && (
              <div className='rb:flex rb:items-center rb:justify-start rb:mt-3'>
                <span className='rb:text-gray-500 rb:text-xs'>
                  <FieldTimeOutlined /> {formatDateTime(item.metadata.file_created_at)}
                </span>
              </div>
            )}
          </div>
        );
      })}
      {loading && (
        <div className='rb:mb-4'>
          <Skeleton active paragraph={{ rows: 3 }} />
        </div>
      )}
    </div>
  );

  // If loadMore and hasMore are provided, use InfiniteScroll
  if (loadMore && hasMore !== undefined) {
    return (
      <div className='rb:flex rb:h-full rb:flex-col'>
        <div className='rb:flex rb:items-center rb:justify-start rb:gap-2'>
          <span className='rb:text-lg rb:font-medium'>{t('knowledgeBase.recallResult')}</span>
          <span className='rb:text-gray-500 rb:text-xs rb:pt-[2px]'>
            (<span className='rb:text-[#155EEF]'>{data.length}</span> results)
          </span>
        </div>
        <InfiniteScroll
          dataLength={data.length}
          next={loadMore}
          hasMore={hasMore}
          loader={<Skeleton active paragraph={{ rows: 3 }} className='rb:mt-4' />}
          scrollableTarget={scrollableTarget}
        >
          {renderContent()}
        </InfiniteScroll>
      </div>
    );
  }

  // Otherwise use normal rendering
  return (
    <div className='rb:flex rb:flex-col'>
      <div className='rb:flex rb:items-center rb:justify-start rb:gap-2'>
        <span className='rb:text-lg rb:font-medium'>{t('knowledgeBase.recallResult')}</span>
        <span className='rb:text-gray-500 rb:text-xs rb:pt-[2px]'>
          (<span className='rb:text-[#155EEF]'>{data.length}</span> results)
        </span>
      </div>
      {renderContent()}
    </div>
  );
};

export default RecallTestResult;
