import {
    faBook,
    faBookOpen,
    faExclamationTriangle,
    faLock,
    faPaperPlane,
    faRobot,
    faUser
} from '@fortawesome/free-solid-svg-icons';
import {Dispatch, RefObject, SetStateAction, useContext, useEffect, useRef, useState,} from 'react';
import QuillSense, {Conversation, ConversationType, Message} from "@/lib/models/QuillSense";
import {ChapterContext} from "@/context/ChapterContext";
import {BookContext} from "@/context/BookContext";
import {AlertContext} from "@/context/AlertContext";
import {SessionContext} from '@/context/SessionContext';
import System from "@/lib/models/System";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext";
import {AIUsageContext, AIUsageContextProps} from "@/context/AIUsageContext";

interface QuillConversationProps {
    disabled: boolean;
    selectedConversation: string;
    setSelectConversation: Dispatch<SetStateAction<string>>;
}

type ContextType = 'none' | 'chapter' | 'book';

export default function QuillConversation(
    {
        disabled,
        selectedConversation,
        setSelectConversation,
    }: QuillConversationProps) {
    const t = useTranslations();
    const {lang} = useContext<LangContextProps>(LangContext);
    const {session} = useContext(SessionContext);
    const {errorMessage} = useContext(AlertContext);
    const {book} = useContext(BookContext);
    const {chapter} = useContext(ChapterContext);
    const {setTotalPrice} = useContext<AIUsageContextProps>(AIUsageContext)
    
    const [inputText, setInputText] = useState<string>('');
    const [messages, setMessages] = useState<Message[]>([]);
    const [isLoading, setIsLoading] = useState<boolean>(false);
    const [contextType, setContextType] = useState<ContextType>('none');
    const [showContextAlert, setShowContextAlert] = useState<boolean>(false);
    const [pendingContextType, setPendingContextType] = useState<ContextType>('none');
    const messageContainerRef: RefObject<HTMLDivElement | null> = useRef<HTMLDivElement>(null);
    const textareaRef: RefObject<HTMLTextAreaElement | null> = useRef<HTMLTextAreaElement>(null);
    
    const [mode, setMode] = useState<ConversationType>('chatbot');
    
    const isGeminiEnabled: boolean = QuillSense.isGeminiEnabled(session);
    const isSubTierTwo: boolean = QuillSense.getSubLevel(session) >= 2;
    const hasAccess: boolean = isGeminiEnabled || isSubTierTwo;
    
    function adjustTextareaHeight(): void {
        const textarea: HTMLTextAreaElement | null = textareaRef.current;
        if (textarea) {
            textarea.style.height = 'auto';
            const newHeight: number = Math.min(Math.max(textarea.scrollHeight, 42), 120);
            textarea.style.height = `${newHeight}px`;
        }
    }
    
    function scrollToBottom(): void {
        const messageContainer: HTMLDivElement | null = messageContainerRef.current;
        if (messageContainer) {
            messageContainer.scrollTop = messageContainer.scrollHeight;
        }
    }
    
    function LoadingMessage() {
        return (
            <div className="flex mb-6 justify-start">
                <div
                    className="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-primary-dark flex items-center justify-center text-text-primary mr-3 shadow-lg">
                    <FontAwesomeIcon icon={faRobot} className={'w-5 h-5'}/>
                </div>
                <div
                    className="max-w-[75%] p-4 rounded-2xl bg-secondary/80 text-text-primary rounded-bl-md backdrop-blur-sm border border-secondary/50">
                    <div className="flex items-center space-x-2">
                        <span className="text-text-secondary text-sm">{t('quillConversation.loadingMessage')}</span>
                        <div className="flex space-x-1">
                            <div className="w-2 h-2 bg-primary rounded-full animate-pulse"
                                 style={{animationDelay: '0ms', animationDuration: '1.5s'}}></div>
                            <div className="w-2 h-2 bg-primary rounded-full animate-pulse"
                                 style={{animationDelay: '0.3s', animationDuration: '1.5s'}}></div>
                            <div className="w-2 h-2 bg-primary rounded-full animate-pulse"
                                 style={{animationDelay: '0.6s', animationDuration: '1.5s'}}></div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
    
    function WelcomeMessage() {
        return (
            <div className="flex flex-col items-center justify-center h-full p-8">
                <div
                    className="w-20 h-20 rounded-2xl bg-gradient-to-br from-primary to-primary-dark flex items-center justify-center text-text-primary mb-6 shadow-2xl">
                    <FontAwesomeIcon icon={faRobot} className={'w-10 h-10'}/>
                </div>
                <h2 className="text-2xl font-['ADLaM_Display'] text-text-primary mb-3">{t('quillConversation.welcomeTitle')}</h2>
                <p className="text-muted text-center leading-relaxed text-lg max-w-md mb-6">
                    {t('quillConversation.welcomeDescription')}
                </p>
                <div className="bg-secondary/30 rounded-xl p-4 border border-secondary/50 backdrop-blur-sm shadow-md">
                    <p className="text-sm text-text-secondary text-center">
                        {t('quillConversation.welcomeTip')}
                    </p>
                </div>
            </div>
        );
    }
    
    function ContextAlert() {
        const contextDescription: string = pendingContextType === 'chapter'
            ? t('quillConversation.contextAlert.chapter')
            : t('quillConversation.contextAlert.book');

        return (
            <div className="fixed inset-0 bg-overlay flex items-center justify-center z-50">
                <div
                    className="bg-tertiary/90 backdrop-blur-sm border border-secondary/50 rounded-2xl p-6 max-w-md mx-4 shadow-2xl">
                    <div className="flex items-center mb-4">
                        <div
                            className="w-12 h-12 rounded-xl bg-warning/20 flex items-center justify-center mr-3 shadow-sm">
                            <FontAwesomeIcon icon={faExclamationTriangle} className="w-6 h-6 text-warning"/>
                        </div>
                        <h3 className="text-xl font-['ADLaM_Display'] text-text-primary">{t('quillConversation.contextAlert.title')}</h3>
                    </div>
                    <p className="text-muted mb-6 leading-relaxed text-lg">
                        {contextDescription}
                    </p>
                    <div className="flex space-x-3">
                        <button
                            onClick={(): void => {
                                setShowContextAlert(false);
                                setPendingContextType('none');
                            }}
                            className="flex-1 px-4 py-2.5 bg-secondary/50 text-text-secondary rounded-xl hover:bg-secondary hover:text-text-primary transition-all duration-200 hover:scale-105 shadow-sm hover:shadow-md border border-secondary/50 font-medium"
                        >
                            {t('common.cancel')}
                        </button>
                        <button
                            onClick={(): void => {
                                setContextType(pendingContextType);
                                setShowContextAlert(false);
                                setPendingContextType('none');
                            }}
                            className="flex-1 px-4 py-2.5 bg-primary text-text-primary rounded-xl hover:bg-primary-dark transition-all duration-200 hover:scale-105 shadow-md hover:shadow-lg font-medium"
                        >
                            {t('common.confirm')}
                        </button>
                    </div>
                </div>
            </div>
        );
    }
    
    function handleContextChange(type: ContextType): void {
        if (type === 'none') {
            setContextType('none');
        } else {
            setPendingContextType(type);
            setShowContextAlert(true);
        }
    }
    
    useEffect((): void => {
        if (selectedConversation !== '' && hasAccess) {
            getMessages().then();
        }
    }, []);
    
    useEffect((): void => {
        scrollToBottom();
    }, [messages, isLoading]);
    
    useEffect((): void => {
        adjustTextareaHeight();
    }, [inputText]);
    
    
    async function getMessages(): Promise<void> {
        try {
            const response: Conversation =
                await System.authGetQueryToServer<Conversation>(
                    `quillsense/conversation`,
                    session.accessToken,
                    "fr",
                    {id: selectedConversation},
                );
            if (response) {
                setMessages(response.messages);
                setMode((response.type as ConversationType) ?? 'chatbot');
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('quillConversation.genericError'));
            }
        }
    }
    
    function getCurrentTime(): string {
        const now: Date = new Date();
        return now.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
    }
    
    async function handleSend(): Promise<void> {
        if (!inputText.trim()) {
            errorMessage(t('quillConversation.emptyMessageError'));
            return;
        }
        try {
            const tempId: number = Date.now();
            const newMessage: Message = {
                id: tempId,
                message: inputText,
                type: 'user',
                date: getCurrentTime(),
            };
            setMessages((prevMessages: Message[]): Message[] => [...prevMessages, newMessage]);
            setInputText('');
            setIsLoading(true);
            
            const response: Conversation = await System.authPostToServer<Conversation>('quillsense/chatbot/send', {
                message: inputText,
                bookId: book?.bookId || null,
                chapterId: chapter?.chapterId || null,
                conversationId: selectedConversation ?? '',
                mode: mode,
                contextType: contextType,
                version: chapter?.chapterContent.version || null,
            }, session.accessToken, lang);
            console.log(response);
            
            setIsLoading(false);
            if (response) {
                setMessages((prevMessages: Message[]): Message[] => {
                    const userMessageFromServer: Message | undefined =
                        response.messages.find(
                            (msg: Message): boolean => msg.type === 'user',
                        );
                    const aiMessageFromServer: Message | undefined =
                        response.messages.find(
                            (msg: Message): boolean => msg.type === 'model',
                        );
                    
                    const updatedMessages: Message[] = prevMessages.map(
                        (msg: Message): Message =>
                            msg.id === tempId && userMessageFromServer
                                ? {
                                    ...msg,
                                    id: userMessageFromServer.id,
                                    date: userMessageFromServer.date,
                                }
                                : msg,
                    );
                    
                    return aiMessageFromServer
                        ? [...updatedMessages, aiMessageFromServer]
                        : updatedMessages;
                });
                
                setTotalPrice((prevTotal: number): number => prevTotal + (response.totalPrice || 0));
                
                if (selectedConversation === '') {
                    setSelectConversation(response.id);
                }
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(t('quillConversation.sendError'));
            } else {
                errorMessage(t('quillConversation.genericError'));
            }
            setIsLoading(false);
        }
    }
    
    if (!hasAccess) {
        return (
            <div className="flex flex-col h-full">
                <div className="flex-1 p-6 overflow-y-auto flex items-center justify-center">
                    <div className="max-w-md mx-auto">
                        <div
                            className="bg-tertiary/90 backdrop-blur-sm border border-secondary/50 rounded-2xl p-8 text-center shadow-2xl">
                            <div
                                className="w-20 h-20 mx-auto mb-6 bg-primary rounded-2xl flex items-center justify-center shadow-lg">
                                <FontAwesomeIcon icon={faLock} className="w-10 h-10 text-text-primary"/>
                            </div>
                            
                            <h3 className="text-xl font-['ADLaM_Display'] text-text-primary mb-4">
                                {t('quillConversation.accessRequired.title')}
                            </h3>
                            
                            <p className="text-muted leading-relaxed text-lg">
                                {t('quillConversation.accessRequired.description')}
                            </p>
                        </div>
                    </div>
                </div>
                <div className="bg-secondary/30 backdrop-blur-sm border-t border-secondary/50 p-4 shadow-inner">
                    <div
                        className="flex items-center rounded-2xl bg-tertiary/30 p-3 border border-secondary/50 opacity-50">
                        <textarea
                            disabled={true}
                            placeholder={t('quillConversation.inputPlaceholder')}
                            rows={1}
                            className="flex-1 bg-transparent border-0 outline-none px-4 py-2 text-text-primary placeholder-text-secondary resize-none overflow-hidden min-h-[42px] max-h-[120px] cursor-not-allowed"
                        />
                        <button
                            disabled={true}
                            className="p-3 rounded-xl text-text-secondary cursor-not-allowed ml-2"
                        >
                            <FontAwesomeIcon icon={faPaperPlane} className="w-5 h-5"/>
                        </button>
                    </div>
                </div>
            </div>
        );
    }
    
    return (
        <>
            <div ref={messageContainerRef} className="flex-1 p-6 overflow-y-auto">
                {messages.length === 0 && !isLoading ? (
                    <WelcomeMessage/>
                ) : (
                    messages.map((message: Message) => (
                        <div
                            key={message.id}
                            className={`flex mb-6 ${message.type === 'user' ? 'justify-end' : 'justify-start'}`}
                        >
                            {message.type === 'model' && (
                                <div
                                    className="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-primary-dark flex items-center justify-center text-text-primary mr-3 shadow-lg">
                                    <FontAwesomeIcon icon={faRobot} className={'w-5 h-5'}/>
                                </div>
                            )}
                            <div
                                className={`max-w-[75%] p-4 rounded-2xl shadow-sm ${
                                    message.type === 'user'
                                        ? 'bg-gradient-to-br from-primary to-primary-dark text-text-primary rounded-br-md'
                                        : 'bg-secondary/80 text-text-primary rounded-bl-md backdrop-blur-sm border border-secondary/50'
                                }`}
                            >
                                <p className="leading-relaxed whitespace-pre-wrap">{message.message}</p>
                                <p className={`text-xs mt-2 ${
                                    message.type === 'user'
                                        ? 'text-text-primary/70'
                                        : 'text-text-secondary'
                                }`}>
                                    {message.date}
                                </p>
                            </div>
                            {message.type === 'user' && (
                                <div
                                    className="w-10 h-10 rounded-full bg-gradient-to-br from-primary-dark to-tertiary flex items-center justify-center text-text-primary ml-3 shadow-lg">
                                    <FontAwesomeIcon icon={faUser} className={'w-5 h-5'}/>
                                </div>
                            )}
                        </div>
                    ))
                )}
                {isLoading && <LoadingMessage/>}
            </div>
            
            <div className="p-4">
                <div className="flex items-center space-x-4 mb-3 px-2">
                    <span
                        className="text-sm text-text-secondary font-medium">{t('quillConversation.contextLabel')}</span>
                    <div className="flex items-center space-x-2">
                        <button
                            onClick={(): void => handleContextChange('none')}
                            className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
                                contextType === 'none'
                                    ? 'bg-primary text-text-primary'
                                    : 'bg-secondary/50 text-text-secondary hover:bg-secondary hover:text-text-primary'
                            }`}
                        >
                            {t('quillConversation.context.none')}
                        </button>
                        {chapter && (
                            <button
                                onClick={(): void => handleContextChange('chapter')}
                                className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center space-x-1 ${
                                    contextType === 'chapter'
                                        ? 'bg-primary text-text-primary'
                                        : 'bg-secondary/50 text-text-secondary hover:bg-secondary hover:text-text-primary'
                                }`}
                            >
                                <FontAwesomeIcon icon={faBookOpen} className="w-3 h-3"/>
                                <span>{t('quillConversation.context.chapter')}</span>
                            </button>
                        )}
                        {book && (
                            <button
                                onClick={(): void => handleContextChange('book')}
                                className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center space-x-1 ${
                                    contextType === 'book'
                                        ? 'bg-primary text-text-primary'
                                        : 'bg-secondary/50 text-text-secondary hover:bg-secondary hover:text-text-primary'
                                }`}
                            >
                                <FontAwesomeIcon icon={faBook} className="w-3 h-3"/>
                                <span>{t('quillConversation.context.book')}</span>
                            </button>
                        )}
                    </div>
                </div>
                <div className="flex items-end rounded-2xl bg-tertiary border border-secondary/50 shadow-inner">
                    <textarea
                        disabled={disabled || isLoading}
                        ref={textareaRef}
                        value={inputText}
                        onChange={(e) => setInputText(e.target.value)}
                        onKeyDown={async (e) => {
                            if (e.key === 'Enter' && !e.shiftKey) {
                                e.preventDefault();
                                await handleSend();
                            }
                        }}
                        placeholder={t('quillConversation.inputPlaceholder')}
                        rows={1}
                        className="flex-1 bg-transparent border-0 outline-none px-4 text-text-primary placeholder-text-secondary resize-none overflow-hidden min-h-[42px] max-h-[120px] leading-relaxed"
                    />
                    <button
                        onClick={handleSend}
                        disabled={inputText.trim() === '' || isLoading}
                        className={`m-2 p-3 rounded-xl transition-all duration-200 ${
                            inputText.trim() === '' || isLoading
                                ? 'text-text-secondary bg-secondary/50 cursor-not-allowed'
                                : 'text-text-primary bg-gradient-to-br from-primary to-primary-dark hover:from-primary-dark hover:to-primary shadow-lg hover:shadow-xl transform hover:scale-105'
                        }`}
                    >
                        <FontAwesomeIcon icon={faPaperPlane} className={'w-5 h-5'}/>
                    </button>
                </div>
            </div>
            
            {showContextAlert && <ContextAlert/>}
        </>
    );
}