import {useContext, useEffect, useState, useRef, useCallback} from '@wordpress/element';
import {useNavigate, useSearchParams} from 'react-router-dom';
import {createHooks} from "@wordpress/hooks";
import {__} from "@wordpress/i18n";
import useSettings from "../../state";
import ContentHeader from "./header";
import ContentBody from "./body";
import ContentBodyIn from "./body-in";
import CurrentComponent from "../current-component";
import {
    getDefaultPageLayoutData,
    getNavLinkTo,
    getNavLinkToParams,
    getPageLayoutData,
} from "../../../../../helpers";
import {ChatbotPreviewContext} from "../../../../contexts/chatbot-preview";
import ChatbotPreview from "./chatbot-preview";
import contentHeaderBG from '../../../../../../../resources/admin/page/settings/header-bg.png'
import {PARAMETERS, SIZE_WIDTH} from "../../../../../../components/chatbots/includes/constants";
import {getCookie} from "../../../../../../helpers";
import {GetMigrationStatus, RunMigration} from "../../../../../rest/plugin";
import Migration from "../../../../popups/general/migration";
import {NotificationsContext} from "../../../../contexts/notifications";
import {handleError, handleSuccess} from "../../../../../helpers/notifications";

if (!LimbChatbot.Hooks) {
    LimbChatbot.Hooks = createHooks();
}

const getChatbotWidth = (chatbotEl) => {
    const chatbotRect = chatbotEl?.getBoundingClientRect();

    if (chatbotRect?.width) {
        return chatbotRect.width;
    }

    const userUuid = getCookie('lbaic_chatbot_user_uuid') || '';
    const key = 'lbaic.chatbots' + (userUuid ? '.' + userUuid : '');
    const storageData = JSON.parse(localStorage.getItem(key), '{}')?.default;
    const sizeName = storageData?.size || 'md';

    return sizeName in SIZE_WIDTH ? SIZE_WIDTH[sizeName] : SIZE_WIDTH['md'];
};

const updatePositions = () => {
    const contentElement = document.querySelector('.lbaic-settings-content');
    if (!contentElement) {
        return;
    }

    const rect = contentElement.getBoundingClientRect();
    const isLargeScreen = window.innerWidth >= 782;

    // Calculate bottom position: distance from bottom edge of viewport to bottom edge of element
    // This ensures trigger and chatbot have equal bottom positions
    const bottomPosition = Math.max(16, window.innerHeight - rect.bottom);
    document.documentElement.style.setProperty(
        '--content-bottom-offset',
        `${bottomPosition}px`
    );

    // Calculate available space from content end to screen end
    const availableSpaceRight = window.innerWidth - rect.right;
    // Calculate available space from screen start to content start
    const availableSpaceLeft = rect.left;

    // Find chatbot preview containers
    const previewContainer = document.getElementById('lbaic-chatbot-preview');
    if (!previewContainer) {
        return;
    }

    // #lbaic element has class lbaic-right or lbaic-left, and .lbaic-grid is its child
    const chatbotGrid = previewContainer?.querySelector('.lbaic-grid');
    const chatbotWidth = getChatbotWidth(chatbotGrid);
    const rightChatbotElement = previewContainer.querySelector('#lbaic.lbaic-right');
    const leftChatbotElement = previewContainer.querySelector('#lbaic.lbaic-left');

    // Bottom position
    if (isLargeScreen) {
        rightChatbotElement?.style.setProperty('--lbaic-b', `${bottomPosition}px`);
        leftChatbotElement?.style.setProperty('--lbaic-b', `${bottomPosition}px`);
    } else {
        let pos = PARAMETERS.position[leftChatbotElement ? 'left' : 'right'].bottom;
        if (document.querySelector('#chatbot-meta-box #lbaic-single-chatbot')) {
            pos += 10;
        }
        if (document.querySelector('#lbaic-admin-page-settings')) {
            pos -= 8;
        }
        rightChatbotElement?.style.setProperty('--lbaic-b', `${pos}px`);
        leftChatbotElement?.style.setProperty('--lbaic-b', `${pos}px`);
    }

    // Right
    if (rightChatbotElement) {
        // Chatbot trigger
        const chatbotTriggerEl = rightChatbotElement.querySelector('.lbaic-trigger');
        const chatbotTriggerRect = chatbotTriggerEl?.getBoundingClientRect();
        const chatbotTriggerWidth = chatbotTriggerRect?.width || 60;
        let chatbotLayoutRight;
        if (availableSpaceRight >= chatbotTriggerWidth + 25 + 32) {
            chatbotLayoutRight = availableSpaceRight - chatbotTriggerWidth - 25;
        } else {
            if (isLargeScreen) {
                chatbotLayoutRight = 32;
            } else {
                chatbotLayoutRight = PARAMETERS.position.right.right - 8;
            }
        }
        rightChatbotElement.style.setProperty('--lbaic-r', `${chatbotLayoutRight}px`);
        // Chatbot grid
        if (availableSpaceRight >= chatbotWidth + 25 + 32) {
            rightChatbotElement.style.setProperty('--lbaic-grid-r', `${chatbotTriggerWidth - chatbotWidth}px`);
        } else {
            if (isLargeScreen) {
                rightChatbotElement.style.setProperty('--lbaic-grid-r', -chatbotLayoutRight + 32 + 'px');
            } else {
                rightChatbotElement.style.setProperty('--lbaic-grid-r', "");
            }
        }
    }
    // Left
    if (leftChatbotElement) {
        // Chatbot trigger
        const chatbotTriggerEl = leftChatbotElement.querySelector('.lbaic-trigger');
        const chatbotTriggerRect = chatbotTriggerEl?.getBoundingClientRect();
        const chatbotTriggerWidth = chatbotTriggerRect?.width || 60;
        let chatbotLayoutLeft;
        if (availableSpaceLeft >= chatbotTriggerWidth + 25) {
            chatbotLayoutLeft = availableSpaceLeft - chatbotTriggerWidth - 25;
        } else {
            chatbotLayoutLeft = PARAMETERS.position.left.left - 8;
        }
        leftChatbotElement.style.setProperty('--lbaic-l', `${chatbotLayoutLeft}px`);
        // Chatbot grid
        if (chatbotGrid && chatbotWidth > 0) {
            if (availableSpaceLeft >= chatbotWidth + 16) {
                chatbotGrid.style.setProperty('--lbaic-grid-l', `${chatbotTriggerWidth - chatbotWidth}px`);
            } else {
                if (isLargeScreen) {
                    chatbotGrid.style.setProperty('--lbaic-grid-l', (8 - chatbotLayoutLeft) + "px");
                } else {
                    chatbotGrid.style.setProperty('--lbaic-grid-l', "");
                }
            }
        }
    }
};

export default function Content({chatbotPreview, setChatbotPreview, userId, isOnboardingActive}) {
    const navigate = useNavigate();
    const notifications = useContext(NotificationsContext);
    const {navItems, pages} = useSettings();
    const [searchParams, setSearchParams] = useSearchParams();
    const [currentPage, setCurrentPage] = useState({
        menu: '',
        tab: '',
        key: '',
        layoutData: {},
    });
    const [openChatbotPreview, setOpenChatbotPreview] = useState(false);
    const contentRef = useRef(null);
    const [showChatbotPreview, setShowChatbotPreview] = useState(false);

    // Migration states
    const [migrationStatus, setMigrationStatus] = useState(null);
    const [needsMigration, setNeedsMigration] = useState(false);
    const [migrating, setMigrating] = useState(false);
    const [migrationChecked, setMigrationChecked] = useState(false);
    const [migrationLoading, setMigrationLoading] = useState(false);

    useEffect(() => {
        let timeout;
        if (isOnboardingActive) {
            setShowChatbotPreview(false);
        } else {
            // timeout = setTimeout(() => {
                // Show with delay to show have confetti better effect
                setShowChatbotPreview(true);
            // }, 3000);
        }

        return () => {
            if (timeout) {
                clearTimeout(timeout);
            }
        }
    }, [isOnboardingActive]);

    useEffect(() => {
        LimbChatbot.Hooks.addAction(
            'lbaic.settings.go-to-path',
            'lbaic/settings/go-to-path',
            (path) => navigate(path),
        );

        return () => {
            LimbChatbot.Hooks.removeAction(
                'lbaic.settings.go-to-path',
                'lbaic/settings/go-to-path'
            );
        };
    }, [navigate]);

    useEffect(() => {
        const pageData = getCurrentPageState();
        setCurrentPage(pageData);
        // Check page existence
        if (!(pageData.key in pages)) {
            // Get default page data
            const data = getDefaultPageLayoutData(navItems, pageData.menu);
            if (data) {
                // Redirection page route info
                const menu = data.slug;
                const tab = data.tabs?.length ? data.tabs[0].slug || '' : '';
                // Navigate to the right page
                navigate(getNavLinkTo(menu, tab));
            }
        }
        // Check nav submenu items
        checkWpNavSubmenuItems(pageData);
    }, [searchParams]);

    useEffect(() => {
        if (userId) {
            const storageKey = 'lbaic.chatbot.preview.shownFor';
            // Get users' IDs chatbot opened for them
            const userIds = JSON.parse(localStorage.getItem(storageKey) || '[]');
            if (userIds.indexOf(userId) === -1) {
                setOpenChatbotPreview(true);
                // Keep the state
                userIds.push(userId);
                localStorage.setItem(storageKey, JSON.stringify(userIds));
            }
        }
    }, [userId]);

    /**
     * Check migration status
     */
    const checkMigrationStatus = useCallback(async () => {
        setMigrationLoading(true);
        try {
            const response = await GetMigrationStatus(
                LimbChatbot.rest.url,
                LimbChatbot.rest.nonce
            );

            setMigrationStatus(response);

            if (response?.needs_migration === true) {
                setNeedsMigration(true);
            } else {
                setNeedsMigration(false);
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to check migration status.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please try again.", 'limb-chatbot'),
            });
            // On error, assume no migration needed and continue
            setNeedsMigration(false);
        } finally {
            setMigrationChecked(true);
            setMigrationLoading(false);
        }
    }, [notifications]);

    /**
     * Run migration
     */
    const handleMigrate = useCallback(async () => {
        setMigrating(true);
        try {
            const response = await RunMigration(
                LimbChatbot.rest.url,
                LimbChatbot.rest.nonce
            );

            if (response?.success) {
                // Migration successful
                setNeedsMigration(false);
                setMigrationStatus(null);

                handleSuccess(notifications.set, {
                    title: response?.message || __("Migration completed successfully.", 'limb-chatbot'),
                });
            } else {
                throw new Error(response?.message || __("Migration failed.", 'limb-chatbot'));
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Migration failed.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please try again.", 'limb-chatbot'),
            });
        } finally {
            setMigrating(false);
        }
    }, [notifications]);

    // Check migration status on initial load
    useEffect(() => {
        if (!migrationChecked) {
            checkMigrationStatus();
        }
    }, [migrationChecked, checkMigrationStatus]);

    // Calculate and update CSS variables for chatbot and trigger positioning
    // Positions chatbot and trigger relative to .lbaic-settings-content element
    useEffect(() => {
        if (!showChatbotPreview) {
            // Onboarding has own chatbot preview
            return;
        }

        const contentElement = contentRef.current;
        if (!contentElement) {
            return;
        }

        // Also listen to window resize to update viewport-dependent values
        window.addEventListener('resize', updatePositions);

        // Listen to chatbot size change WordPress hook to recalculate positions
        LimbChatbot.Hooks.addAction('lbaic.settings.chatbots.init', 'lbaic/settings/chatbots-initialized', () => {
            window.requestAnimationFrame(updatePositions)
        });

        // Observe ContentBody height changes
        const contentBodyElement = contentElement.querySelector('.lbaic-settings-content-body');
        let resizeObserver = null;

        if (contentBodyElement && window.ResizeObserver) {
            resizeObserver = new ResizeObserver(() => {
                window.requestAnimationFrame(updatePositions);
            });
            resizeObserver.observe(contentBodyElement);
        }

        return () => {
            window.removeEventListener('resize', updatePositions);
            LimbChatbot.Hooks.removeAction('lbaic.settings.chatbots.init', 'lbaic/settings/chatbots-initialized');
            if (resizeObserver) {
                resizeObserver.disconnect();
            }
        };
    }, [showChatbotPreview, currentPage.key]);

    /**
     * Get current page data
     *
     * @return {{layoutData: object, tab: string, menu: string, key: string}}
     */
    const getCurrentPageState = () => {
        const menu = searchParams.get('menu');
        const tab = searchParams.get('tab');
        const key = getNavLinkToParams(menu, tab, true);
        const layoutData = getPageLayoutData(navItems, menu) || {};
        const tabData = tab ? (
            layoutData.tabs?.find((tabItem) => tabItem.slug === tab)
        ) : null;

        return {menu, tab, key, layoutData, tabData};
    }

    /**
     * Check WP nav submenu items
     *
     * @param {object} pageData Page info data
     */
    const checkWpNavSubmenuItems = (pageData) => {
        const subMenuItems = document.querySelectorAll('#toplevel_page_lbaic-dashboard .wp-submenu li');
        const subMenuCurrentItem = document.querySelector('#toplevel_page_lbaic-dashboard .wp-submenu li.current');
        const menu = pageData?.menu;

        switch (menu) {
            case 'chatbot':
                subMenuCurrentItem?.classList.remove('current');
                const firstItem = document.querySelector('#toplevel_page_lbaic-dashboard .wp-submenu li.wp-first-item');
                firstItem.classList.add('current');
                break;
            case 'knowledge':
            case 'leads':
            case 'actions':
            case 'notifications':
                subMenuCurrentItem?.classList.remove('current');
                subMenuItems.forEach((subMenuItem) => {
                    const a = subMenuItem.querySelector('a');
                    if (a) {
                        const url = new URL(a.href);
                        const params = new URLSearchParams(url.search);
                        if (params.get('menu') === menu) {
                            subMenuItem.classList.add('current');
                        }
                    }
                });
                break;
            default:
                break;
        }
    }

    return (
        <>
            <div className="lbaic-settings-content-container lbaic-settings-scroll-y lbaic-settings-scroll-style">
                <div ref={contentRef}
                     className='lbaic-settings-content'
                     style={{
                         '--lbaic-settings-content-header-height': null,
                         '--lbaic-settings-content-header-bg': `url(${contentHeaderBG})`
                     }}>
                    <ContentHeader
                        title={currentPage.tabData?.title || currentPage.layoutData.title || currentPage.layoutData.label}
                        subTitle={currentPage.tabData?.subTitle || currentPage.layoutData.subTitle || ''}
                    />
                    <ContentBody>
                        <ContentBodyIn>
                            {!needsMigration && !migrationLoading && (
                                <CurrentComponent
                                    pageData={currentPage}
                                    setChatbotPreview={setChatbotPreview}
                                    updatePositions={updatePositions}
                                />
                            )}
                        </ContentBodyIn>
                    </ContentBody>
                </div>
            </div>
            {showChatbotPreview && !needsMigration && !migrationLoading && (
                <ChatbotPreviewContext.Provider value={chatbotPreview}>
                    <ChatbotPreview open={openChatbotPreview} userId={userId}/>
                </ChatbotPreviewContext.Provider>
            )}
            {needsMigration && migrationChecked && (
                <Migration
                    migrationStatus={migrationStatus}
                    migrating={migrating}
                    onMigrate={handleMigrate}
                    onClose={migrating ? null : () => {
                    }} // Can't close during migration, empty function otherwise
                />
            )}
        </>
    );
}