/* eslint-disable @next/next/no-img-element */
'use client';

import { getSuggestions } from '@/lib/actions';
import { cn } from '@/lib/utils';
import {
  BookCopy,
  CheckCheck,
  Copy as CopyIcon,
  Disc3,
  ImagesIcon,
  Layers3,
  Plus,
  Sparkles,
  StopCircle,
  VideoIcon,
  Volume2,
} from 'lucide-react';
import Markdown, { MarkdownToJSX } from 'markdown-to-jsx';
import { useEffect, useState } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { useSpeech } from 'react-text-to-speech';
import { Message } from './ChatWindow';
import Copy from './MessageActions/Copy';
import ModelInfoButton from './MessageActions/ModelInfo';
import Rewrite from './MessageActions/Rewrite';
import MessageSources from './MessageSources';
import SearchImages from './SearchImages';
import SearchVideos from './SearchVideos';
import ThinkBox from './ThinkBox';

const ThinkTagProcessor = ({ children }: { children: React.ReactNode }) => {
  return <ThinkBox content={children as string} />;
};

const CodeBlock = ({
  className,
  children,
}: {
  className?: string;
  children: React.ReactNode;
}) => {
  // Extract language from className (format could be "language-javascript" or "lang-javascript")
  let language = '';
  if (className) {
    if (className.startsWith('language-')) {
      language = className.replace('language-', '');
    } else if (className.startsWith('lang-')) {
      language = className.replace('lang-', '');
    }
  }

  const content = children as string;
  const [isCopied, setIsCopied] = useState(false);

  const handleCopyCode = () => {
    navigator.clipboard.writeText(content);
    setIsCopied(true);
    setTimeout(() => setIsCopied(false), 2000);
  };

  return (
    <div className="rounded-md overflow-hidden my-4 relative group border border-dark-secondary">
      <div className="flex justify-between items-center px-4 py-2 bg-dark-200 border-b border-dark-secondary text-xs text-white/70 font-mono">
        <span>{language}</span>
        <button
          onClick={handleCopyCode}
          className="p-1 rounded-md hover:bg-dark-secondary transition duration-200"
          aria-label="Copy code to clipboard"
        >
          {isCopied ? (
            <CheckCheck size={14} className="text-green-500" />
          ) : (
            <CopyIcon size={14} className="text-white/70" />
          )}
        </button>
      </div>
      <SyntaxHighlighter
        language={language || 'text'}
        style={oneDark}
        customStyle={{
          margin: 0,
          padding: '1rem',
          borderRadius: 0,
          backgroundColor: '#1c1c1c',
        }}
        wrapLines={true}
        wrapLongLines={true}
        showLineNumbers={language !== '' && content.split('\n').length > 1}
        useInlineStyles={true}
        PreTag="div"
      >
        {content}
      </SyntaxHighlighter>
    </div>
  );
};

type TabType = 'text' | 'sources' | 'images' | 'videos';

interface SearchTabsProps {
  chatHistory: Message[];
  query: string;
  messageId: string;
  message: Message;
  isLast: boolean;
  loading: boolean;
  rewrite: (messageId: string) => void;
  sendMessage: (
    message: string,
    options?: {
      messageId?: string;
      rewriteIndex?: number;
      suggestions?: string[];
    },
  ) => void;
}

const MessageTabs = ({
  chatHistory,
  query,
  messageId,
  message,
  isLast,
  loading,
  rewrite,
  sendMessage,
}: SearchTabsProps) => {
  const [activeTab, setActiveTab] = useState<TabType>('text');
  const [imageCount, setImageCount] = useState(0);
  const [videoCount, setVideoCount] = useState(0);
  const [parsedMessage, setParsedMessage] = useState(message.content);
  const [speechMessage, setSpeechMessage] = useState(message.content);
  const [loadingSuggestions, setLoadingSuggestions] = useState(false);
  const { speechStatus, start, stop } = useSpeech({ text: speechMessage });

  // Callback functions to update counts
  const updateImageCount = (count: number) => {
    setImageCount(count);
  };

  const updateVideoCount = (count: number) => {
    setVideoCount(count);
  };

  // Load suggestions handling
  const handleLoadSuggestions = async () => {
    if (
      loadingSuggestions ||
      (message?.suggestions && message.suggestions.length > 0)
    )
      return;

    setLoadingSuggestions(true);
    try {
      const suggestions = await getSuggestions([...chatHistory, message]);
      // Update the message.suggestions property through parent component
      sendMessage('', { messageId: message.messageId, suggestions });
    } catch (error) {
      console.error('Error loading suggestions:', error);
    } finally {
      setLoadingSuggestions(false);
    }
  };

  // Process message content
  useEffect(() => {
    const citationRegex = /\[([^\]]+)\]/g;
    const regex = /\[(\d+)\]/g;
    let processedMessage = message.content;

    if (message.role === 'assistant' && message.content.includes('<think>')) {
      const openThinkTag = processedMessage.match(/<think>/g)?.length || 0;
      const closeThinkTag = processedMessage.match(/<\/think>/g)?.length || 0;

      if (openThinkTag > closeThinkTag) {
        processedMessage += '</think> <a> </a>'; // The extra <a> </a> is to prevent the think component from looking bad
      }
    }

    if (
      message.role === 'assistant' &&
      message?.sources &&
      message.sources.length > 0
    ) {
      setParsedMessage(
        processedMessage.replace(
          citationRegex,
          (_, capturedContent: string) => {
            const numbers = capturedContent
              .split(',')
              .map((numStr) => numStr.trim());

            const linksHtml = numbers
              .map((numStr) => {
                const number = parseInt(numStr);

                if (isNaN(number) || number <= 0) {
                  return `[${numStr}]`;
                }

                const source = message.sources?.[number - 1];
                const url = source?.metadata?.url;

                if (url) {
                  return `<a href="${url}" target="_blank" className="bg-light-secondary dark:bg-dark-secondary px-1 rounded ml-1 no-underline text-xs text-black/70 dark:text-white/70 relative">${numStr}</a>`;
                } else {
                  return `[${numStr}]`;
                }
              })
              .join('');

            return linksHtml;
          },
        ),
      );
      setSpeechMessage(message.content.replace(regex, ''));
      return;
    }

    setSpeechMessage(message.content.replace(regex, ''));
    setParsedMessage(processedMessage);
  }, [message.content, message.sources, message.role]);

  // Auto-suggest effect (similar to MessageBox)
  useEffect(() => {
    const autoSuggestions = localStorage.getItem('autoSuggestions');
    if (
      isLast &&
      message.role === 'assistant' &&
      !loading &&
      autoSuggestions === 'true'
    ) {
      handleLoadSuggestions();
    }
  }, [isLast, loading, message.role]);

  // Markdown formatting options
  const markdownOverrides: MarkdownToJSX.Options = {
    overrides: {
      think: {
        component: ThinkTagProcessor,
      },
      code: {
        component: ({ className, children }) => {
          // Check if it's an inline code block or a fenced code block
          if (className) {
            // This is a fenced code block (```code```)
            return <CodeBlock className={className}>{children}</CodeBlock>;
          }
          // This is an inline code block (`code`)
          return (
            <code className="px-1.5 py-0.5 rounded bg-dark-secondary text-white font-mono text-sm">
              {children}
            </code>
          );
        },
      },
      pre: {
        component: ({ children }) => children,
      },
    },
  };

  return (
    <div className="flex flex-col w-full">
      {/* Tabs */}
      <div className="flex border-b border-light-200 dark:border-dark-200 overflow-x-auto no-scrollbar sticky top-0 bg-light-primary dark:bg-dark-primary z-10 -mx-4 px-4 mb-2 shadow-sm">
        <button
          onClick={() => setActiveTab('text')}
          className={cn(
            'flex items-center px-4 py-3 text-sm font-medium transition-all duration-200 relative',
            activeTab === 'text'
              ? 'border-b-2 border-[#24A0ED] text-[#24A0ED] bg-light-100 dark:bg-dark-100'
              : 'text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:bg-light-100 dark:hover:bg-dark-100',
          )}
          aria-selected={activeTab === 'text'}
          role="tab"
        >
          <Disc3 size={16} className="mr-2" />
          <span className="whitespace-nowrap">Answer</span>
        </button>

        {message.sources && message.sources.length > 0 && (
          <button
            onClick={() => setActiveTab('sources')}
            className={cn(
              'flex items-center space-x-2 px-4 py-3 text-sm font-medium transition-all duration-200 relative',
              activeTab === 'sources'
                ? 'border-b-2 border-[#24A0ED] text-[#24A0ED] bg-light-100 dark:bg-dark-100'
                : 'text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:bg-light-100 dark:hover:bg-dark-100',
            )}
            aria-selected={activeTab === 'sources'}
            role="tab"
          >
            <BookCopy size={16} />
            <span className="whitespace-nowrap">Sources</span>
            <span
              className={cn(
                'ml-1.5 px-1.5 py-0.5 text-xs rounded-full',
                activeTab === 'sources'
                  ? 'bg-[#24A0ED]/20 text-[#24A0ED]'
                  : 'bg-light-200 dark:bg-dark-200 text-black/70 dark:text-white/70',
              )}
            >
              {message.sources.length}
            </span>
          </button>
        )}

        <button
          onClick={() => setActiveTab('images')}
          className={cn(
            'flex items-center space-x-2 px-4 py-3 text-sm font-medium transition-all duration-200 relative',
            activeTab === 'images'
              ? 'border-b-2 border-[#24A0ED] text-[#24A0ED] bg-light-100 dark:bg-dark-100'
              : 'text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:bg-light-100 dark:hover:bg-dark-100',
          )}
          aria-selected={activeTab === 'images'}
          role="tab"
        >
          <ImagesIcon size={16} />
          <span className="whitespace-nowrap">Images</span>
          {imageCount > 0 && (
            <span
              className={cn(
                'ml-1.5 px-1.5 py-0.5 text-xs rounded-full',
                activeTab === 'images'
                  ? 'bg-[#24A0ED]/20 text-[#24A0ED]'
                  : 'bg-light-200 dark:bg-dark-200 text-black/70 dark:text-white/70',
              )}
            >
              {imageCount}
            </span>
          )}
        </button>

        <button
          onClick={() => setActiveTab('videos')}
          className={cn(
            'flex items-center space-x-2 px-4 py-3 text-sm font-medium transition-all duration-200 relative',
            activeTab === 'videos'
              ? 'border-b-2 border-[#24A0ED] text-[#24A0ED] bg-light-100 dark:bg-dark-100'
              : 'text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:bg-light-100 dark:hover:bg-dark-100',
          )}
          aria-selected={activeTab === 'videos'}
          role="tab"
        >
          <VideoIcon size={16} />
          <span className="whitespace-nowrap">Videos</span>
          {videoCount > 0 && (
            <span
              className={cn(
                'ml-1.5 px-1.5 py-0.5 text-xs rounded-full',
                activeTab === 'videos'
                  ? 'bg-[#24A0ED]/20 text-[#24A0ED]'
                  : 'bg-light-200 dark:bg-dark-200 text-black/70 dark:text-white/70',
              )}
            >
              {videoCount}
            </span>
          )}
        </button>
      </div>

      {/* Tab content */}
      <div
        className="min-h-[150px] transition-all duration-200 ease-in-out"
        role="tabpanel"
      >
        {/* Answer Tab */}
        {activeTab === 'text' && (
          <div className="flex flex-col space-y-4 animate-fadeIn">
            <Markdown
              className={cn(
                'prose prose-h1:mb-3 prose-h2:mb-2 prose-h2:mt-6 prose-h2:font-[800] prose-h3:mt-4 prose-h3:mb-1.5 prose-h3:font-[600] prose-invert prose-p:leading-relaxed prose-pre:p-0 font-[400]',
                'prose-code:bg-transparent prose-code:p-0 prose-code:text-inherit prose-code:font-normal prose-code:before:content-none prose-code:after:content-none',
                'prose-pre:bg-transparent prose-pre:border-0 prose-pre:m-0 prose-pre:p-0',
                'max-w-none break-words px-4 text-black dark:text-white',
              )}
              options={markdownOverrides}
            >
              {parsedMessage}
            </Markdown>

            {loading && isLast ? null : (
              <div className="flex flex-row items-center justify-between w-full text-black dark:text-white px-4 py-4">
                <div className="flex flex-row items-center space-x-1">
                  <Rewrite rewrite={rewrite} messageId={message.messageId} />
                  {message.modelStats && (
                    <ModelInfoButton modelStats={message.modelStats} />
                  )}
                </div>
                <div className="flex flex-row items-center space-x-1">
                  <Copy initialMessage={message.content} message={message} />
                  <button
                    onClick={() => {
                      if (speechStatus === 'started') {
                        stop();
                      } else {
                        start();
                      }
                    }}
                    className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary transition duration-200 hover:text-black dark:hover:text-white"
                  >
                    {speechStatus === 'started' ? (
                      <StopCircle size={18} />
                    ) : (
                      <Volume2 size={18} />
                    )}
                  </button>
                </div>
              </div>
            )}

            {isLast && message.role === 'assistant' && !loading && (
              <>
                <div className="border-t border-light-secondary dark:border-dark-secondary px-4 pt-4 mt-4">
                  <div className="flex flex-row items-center space-x-2 mb-3">
                    <Layers3 size={20} />
                    <h3 className="text-xl font-medium">Related</h3>

                    {(!message.suggestions ||
                      message.suggestions.length === 0) && (
                      <button
                        onClick={handleLoadSuggestions}
                        disabled={loadingSuggestions}
                        className="px-4 py-2 flex flex-row items-center justify-center space-x-2 rounded-lg bg-light-secondary dark:bg-dark-secondary hover:bg-light-200 dark:hover:bg-dark-200 transition duration-200 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white"
                      >
                        {loadingSuggestions ? (
                          <div className="w-4 h-4 border-2 border-t-transparent border-gray-400 dark:border-gray-500 rounded-full animate-spin" />
                        ) : (
                          <Sparkles size={16} />
                        )}
                        <span>
                          {loadingSuggestions
                            ? 'Loading suggestions...'
                            : 'Load suggestions'}
                        </span>
                      </button>
                    )}
                  </div>

                  {message.suggestions && message.suggestions.length > 0 && (
                    <div className="flex flex-col space-y-3 mt-2">
                      {message.suggestions.map((suggestion, i) => (
                        <div
                          className="flex flex-col space-y-3 text-sm"
                          key={i}
                        >
                          <div className="h-px w-full bg-light-secondary dark:bg-dark-secondary" />
                          <div
                            onClick={() => {
                              sendMessage(suggestion);
                            }}
                            className="cursor-pointer flex flex-row justify-between font-medium space-x-2 items-center"
                          >
                            <p className="transition duration-200 hover:text-[#24A0ED]">
                              {suggestion}
                            </p>
                            <Plus
                              size={20}
                              className="text-[#24A0ED] flex-shrink-0"
                            />
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </>
            )}
          </div>
        )}

        {/* Sources Tab */}
        {activeTab === 'sources' &&
          message.sources &&
          message.sources.length > 0 && (
            <div className="p-4 animate-fadeIn">
              {message.searchQuery && (
                <div className="mb-4 text-sm bg-light-secondary dark:bg-dark-secondary rounded-lg p-3">
                  <span className="font-medium text-black/70 dark:text-white/70">
                    Search query:
                  </span>{' '}
                  {message.searchUrl ? (
                    <a
                      href={message.searchUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="dark:text-white text-black hover:underline"
                    >
                      {message.searchQuery}
                    </a>
                  ) : (
                    <span className="text-black dark:text-white">
                      {message.searchQuery}
                    </span>
                  )}
                </div>
              )}
              <MessageSources sources={message.sources} />
            </div>
          )}

        {/* Images Tab */}
        {activeTab === 'images' && (
          <div className="p-3 animate-fadeIn">
            <SearchImages
              query={query}
              chatHistory={chatHistory}
              messageId={messageId}
              onImagesLoaded={updateImageCount}
            />
          </div>
        )}

        {/* Videos Tab */}
        {activeTab === 'videos' && (
          <div className="p-3 animate-fadeIn">
            <SearchVideos
              query={query}
              chatHistory={chatHistory}
              messageId={messageId}
              onVideosLoaded={updateVideoCount}
            />
          </div>
        )}
      </div>
    </div>
  );
};

export default MessageTabs;
