import './chatbot.scss';
import ReactDOM from 'react-dom';
import { useState, useEffect } from '@wordpress/element';
import { Dashicon } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { applyFilters } from '@wordpress/hooks';

const cacheKey_history = 'faqtastic-chatbot-history';
const cacheKey_status = 'faqtastic-chatbot-status';

const Chatbot = ({
    dataset
}) => {
    const [open, setOpen] = useState(null);

    const chatbotHeaderText = dataset.chatbotHeaderText || 'Chatbot';
    const chatbotHeaderSubtitle = dataset.chatbotHeaderSubtitle || '';
    const chatbotFirstMsg = dataset.chatbotFirstMsg || 'Ask me a question';
    const chatInputPlaceholder = dataset.chatInputPlaceholder || 'Type your question...';
    const chatbotPosition = dataset.chatbotPosition || 'bottom-right';
    const toggleIconType = dataset.toggleIconType || 'dashicon';
    const toggleIconDashicon = dataset.toggleIconDashicon || 'format-chat';
    const toggleIconSvg = dataset.toggleIconSvg || '';
    const toggleIconImageUrl = dataset.toggleIconImageUrl || '';

    useEffect(() => {
        let status = localStorage.getItem(cacheKey_status);
        if (status === 'open') {
            setOpen(true);
        }
    }, []);

    const toggleChatbot = (status) => {
        localStorage.setItem(cacheKey_status, status ? 'open' : 'closed');
        setOpen(status);
    };

    const renderToggleIcon = () => {
        if (toggleIconType === 'image' && toggleIconImageUrl) {
            return (
                <img
                    src={toggleIconImageUrl}
                    alt=""
                    className="faqtastic-chatbot-custom-image"
                />
            );
        }
        if (toggleIconType === 'svg' && toggleIconSvg) {
            return (
                <span
                    className="faqtastic-chatbot-custom-icon"
                    dangerouslySetInnerHTML={{ __html: toggleIconSvg }}
                />
            );
        }
        return <Dashicon icon={toggleIconDashicon || 'format-chat'} />;
    };

    return (
        <div className="faqtastic-chatbot-wrapper" data-position={chatbotPosition}>
            {open && (
                <ChatbotWindow
                    onClose={() => toggleChatbot(false)}
                    chatbotHeaderText={chatbotHeaderText}
                    chatbotHeaderSubtitle={chatbotHeaderSubtitle}
                    chatbotFirstMsg={chatbotFirstMsg}
                    chatInputPlaceholder={chatInputPlaceholder}
                    dataset={dataset}
                />
            )}
            <button
                className="faqtastic-chatbot-toggle"
                onClick={() => toggleChatbot(!open)}
                aria-label={__('Open chatbot', 'faqtastic')}
            >
                {renderToggleIcon()}
            </button>
        </div>
    );
}

export default Chatbot;

const isReactElement = (element) => {
    if (element && element.$$typeof && element.$$typeof.toString() === 'Symbol(react.element)') {
        return element;
    }
    return null;
}

function ChatbotWindow({ onClose, chatbotHeaderText, chatbotHeaderSubtitle, chatbotFirstMsg, chatInputPlaceholder, dataset }) {
    const [term, setTerm] = useState('');
    const [suggestions, setSuggestions] = useState([]);
    const [conversation, setConversation] = useState([]);
    const [keyboardSelectedIndex, setKeyboardSelectedIndex] = useState(-1);
    const [initialized, setInitialized] = useState(false);
    const firstMessage = { type: 'bot', text: chatbotFirstMsg };

    const addMessageToCache = (message) => {
        let history = JSON.parse(localStorage.getItem(cacheKey_history)) || [firstMessage];
        history.push(message);
        localStorage.setItem(cacheKey_history, JSON.stringify(history));
    };

    const loadHistoryFromCache = () => {
        let history = JSON.parse(localStorage.getItem(cacheKey_history)) || [firstMessage];
        setConversation(history);
    };

    useEffect(() => {
        loadHistoryFromCache();
    }, []);

    const addMessage = (message) => {
        setConversation(prev => {
            const updated = [...prev, message];
            addMessageToCache(message);
            return updated;
        });
    }

    useEffect(() => {
        if (!initialized) {
            const input = document.querySelector('.faqtastic-chatbot-input');
            if (input) input.focus();
            setInitialized(true);
        };
    }, [initialized]);

    useEffect(() => {
        let timeout;
        if (term.length < 2) {
            setSuggestions([]);
            return;
        }

        timeout = setTimeout(() => {
            fetch(
                `${faqtastic_ajax.ajax_url}?action=faqtastic_chatbot_suggestions&nonce=${faqtastic_ajax.nonce}&term=${encodeURIComponent(term)}`
            )
                .then(res => res.json())
                .then(data => setSuggestions(data))
                .catch(() => setSuggestions([]));
        }, 300);

        return () => clearTimeout(timeout);
    }, [term]);

    const handleSelect = (faq) => {
        addMessage({ type: 'user', text: faq.title });
        setSuggestions([]);
        setTerm(faq.title);

        fetch(`${faqtastic_ajax.ajax_url}?action=faqtastic_chatbot_get_answer&nonce=${faqtastic_ajax.nonce}&id=${faq.id}`)
            .then(res => res.json())
            .then(data => {
                addMessage({ type: 'bot', text: data.content || __('No answer found.', 'faqtastic') });
                setTerm('');
                setKeyboardSelectedIndex(-1);
                if(data.url && window.Matomo) {
                    window.Matomo.getTracker().trackEvent('Chatbot', 'FAQ Clicked', faq.title, data.url);
                    window.Matomo.getTracker().trackPageView(data.url);
                }
            })
            .catch(() => {
                addMessage({ type: 'bot', text: __('An error occurred. Please try again.', 'faqtastic') });
            });
    };

    useEffect(() => {
        const container = document.querySelector('.faqtastic-chatbot-conversation');
        if (container) container.scrollTop = container.scrollHeight;
    }, [conversation]);

    useEffect(() => {
        const handleKeyDown = (e) => {
            if (suggestions.length === 0) return;

            if (e.key === 'ArrowDown') {
                e.preventDefault();
                setKeyboardSelectedIndex((prev) => (prev + 1) % suggestions.length);
            } else if (e.key === 'ArrowUp') {
                e.preventDefault();
                setKeyboardSelectedIndex((prev) => (prev - 1 + suggestions.length) % suggestions.length);
            } else if (e.key === 'Enter') {
                e.preventDefault();
                if (keyboardSelectedIndex >= 0 && keyboardSelectedIndex < suggestions.length) {
                    handleSelect(suggestions[keyboardSelectedIndex]);
                }
            }
        };

        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, [suggestions, keyboardSelectedIndex]);

    const hookData = {
      // Local state
      term,
      setTerm,
      suggestions,
      setSuggestions,
      conversation,
      setConversation,
      // Global params
      addMessage,
      dataset,
    };

    return (
        <div className="faqtastic-chatbot-window">
            <div className="faqtastic-chatbot-header">
                <div className="faqtastic-chatbot-header-text">
                    {isReactElement(applyFilters(
                        'faqtastic.chatbot.front.header.before',
                        null,
                        hookData
                    ))}
                    <span className="faqtastic-chatbot-title">{chatbotHeaderText}</span>
                    {chatbotHeaderSubtitle && (
                        <span className="faqtastic-chatbot-subtitle">{chatbotHeaderSubtitle}</span>
                    )}
                    {isReactElement(applyFilters(
                        'faqtastic.chatbot.front.header.after',
                        null,
                        hookData
                    ))}
                </div>
                <button onClick={onClose} className="faqtastic-close-btn">×</button>
            </div>

            <div className="faqtastic-chatbot-conversation">
                {isReactElement(applyFilters(
                    'faqtastic.chatbot.front.conversation.before',
                    null,
                    hookData
                ))}
                {conversation.map((msg, i) => (
                    <div
                        key={i}
                        className={`faqtastic-chatbot-bubble ${msg.type}`}
                        dangerouslySetInnerHTML={{ __html: msg.text }}
                    ></div>
                ))}
                {isReactElement(applyFilters(
                    'faqtastic.chatbot.front.conversation.after',
                    null,
                    hookData
                ))}
            </div>

            <input
                type="text"
                className="faqtastic-chatbot-input"
                placeholder={chatInputPlaceholder}
                value={term}
                onChange={(e) => setTerm(e.target.value)}
                autoComplete="off"
                onFocus={() => setInitialized(true)}
            />
            {isReactElement(applyFilters(
                'faqtastic.chatbot.front.input.after',
                null,
                hookData
            ))}

            {suggestions.length > 0 && (
                <ul className="faqtastic-chatbot-suggestions">
                    {suggestions.map((faq) => (
                        <li
                            key={faq.id}
                            onClick={() => handleSelect(faq)}
                            className={keyboardSelectedIndex === suggestions.indexOf(faq) ? 'selected' : ''}
                        >
                            {faq.title}
                        </li>
                    ))}
                </ul>
            )}
            {isReactElement(applyFilters(
                'faqtastic.chatbot.front.end',
                null,
                hookData
            ))}
        </div>
    );
}

document.addEventListener('DOMContentLoaded', () => {
    if (!document.body.classList.contains('wp-admin')) {
        document.querySelectorAll('.faqtastic-chatbot').forEach((container) => {
            ReactDOM.render(
                <Chatbot
                    dataset={container.dataset}
                />,
                container
            );
        });
    };
});