import { useState, useEffect, useRef, useCallback } from 'react';
import { useAuth } from '../../contexts/AuthContext';
import { useTranslation } from '../../contexts/LanguageContext';
import { useSidebar } from '../../contexts/SidebarContext';
import { useModules, TOGGLEABLE_MODULES } from '../../contexts/ModulesContext';
import type { ModuleId } from '../../contexts/ModulesContext';
import Feature1Tab from '../../components/admin/Feature1Tab';
import { SwipeTabs } from '../../components/SwipeTabs';
import '../../styles/AdminPanel.css';

type TabId = 'config' | 'dashboard' | 'feature1' | 'feature2' | 'feature3' | 'search' | 'notifications';

export default function Features() {
    const { user: currentUser } = useAuth();
    const { t } = useTranslation();
    const { toggleMobileMenu } = useSidebar();
    const { moduleStates, moduleOrder, setModuleEnabled, setModulePosition, setModuleOrder, saveModulesToBackend, saveModuleOrder, hasInitialized, isLoading } = useModules();
    const [activeTab, setActiveTab] = useState<TabId>('config');
    const hasUserMadeChanges = useRef(false);
    const saveRef = useRef(saveModulesToBackend);
    const [draggedItem, setDraggedItem] = useState<string | null>(null);
    const [localOrder, setLocalOrder] = useState<string[]>([]);
    const [localPositions, setLocalPositions] = useState<Record<string, 'top' | 'bottom'>>({});
    const [hasOrderChanges, setHasOrderChanges] = useState(false);
    const tabsContainerRef = useRef<HTMLDivElement>(null);
    const isUserEditing = useRef(false); // Track if user is actively editing
    const initialOrderRef = useRef<string[]>([]);
    const initialPositionsRef = useRef<Record<string, 'top' | 'bottom'>>({});

    const buildFullOrder = useCallback((order: string[]) => {
        const fullOrder = [...order];
        TOGGLEABLE_MODULES.forEach((module, defaultIndex) => {
            if (!fullOrder.includes(module.id)) {
                const insertAt = Math.min(defaultIndex, fullOrder.length);
                fullOrder.splice(insertAt, 0, module.id);
            }
        });
        return fullOrder;
    }, []);

    const normalizePositions = useCallback((positions: Record<string, 'top' | 'bottom'>) => {
        const normalized: Record<string, 'top' | 'bottom'> = {};
        TOGGLEABLE_MODULES.forEach(module => {
            normalized[module.id] = positions[module.id] || module.defaultPosition;
        });
        return normalized;
    }, []);

    const buildPositionsFromStates = useCallback(() => {
        const positions: Record<string, 'top' | 'bottom'> = {};
        TOGGLEABLE_MODULES.forEach(module => {
            const state = moduleStates[module.id];
            positions[module.id] = state?.position || module.defaultPosition;
        });
        return positions;
    }, [moduleStates]);

    const beginOrderEdit = useCallback(() => {
        if (!isUserEditing.current) {
            const snapshotOrder = localOrder.length ? [...localOrder] : buildFullOrder(moduleOrder);
            const snapshotPositions = Object.keys(localPositions).length
                ? { ...normalizePositions(localPositions) }
                : buildPositionsFromStates();
            initialOrderRef.current = snapshotOrder;
            initialPositionsRef.current = snapshotPositions;
            isUserEditing.current = true;
        }
    }, [buildFullOrder, buildPositionsFromStates, localOrder, localPositions, moduleOrder, normalizePositions]);

    // Sync local order with context order (only when moduleOrder changes, not moduleStates)
    useEffect(() => {
        if (moduleOrder.length > 0 && !isUserEditing.current) {
            const fullOrder = buildFullOrder(moduleOrder);
            setLocalOrder(fullOrder);
            initialOrderRef.current = [...fullOrder];
            setHasOrderChanges(false);
        }
    }, [moduleOrder, buildFullOrder]);

    // Sync positions from moduleStates only on initial load or when not editing
    useEffect(() => {
        if (!isUserEditing.current) {
            const positions = buildPositionsFromStates();
            setLocalPositions(positions);
            initialPositionsRef.current = { ...positions };
        }
    }, [buildPositionsFromStates]);

    // Scroll active tab to center of container
    const scrollActiveTabIntoView = useCallback((tabId: string) => {
        if (tabsContainerRef.current) {
            const container = tabsContainerRef.current;
            const activeButton = container.querySelector(`[data-tab-id="${tabId}"]`) as HTMLElement;
            if (activeButton) {
                const containerWidth = container.clientWidth;
                const buttonLeft = activeButton.offsetLeft;
                const buttonWidth = activeButton.offsetWidth;
                // Calculate scroll position to center the button
                const scrollLeft = buttonLeft - (containerWidth / 2) + (buttonWidth / 2);
                container.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });
            }
        }
    }, []);

    // Handle tab change with scroll
    const handleTabChange = useCallback((tabId: TabId) => {
        setActiveTab(tabId);
        setTimeout(() => scrollActiveTabIntoView(tabId), 50);
    }, [scrollActiveTabIntoView]);
    // Keep saveRef updated with latest function
    useEffect(() => {
        saveRef.current = saveModulesToBackend;
    }, [saveModulesToBackend]);

    if (!currentUser?.is_superuser) {
        return null;
    }

    const handleModuleToggle = async (moduleId: ModuleId, type: 'admin' | 'user', enabled: boolean) => {
        hasUserMadeChanges.current = true;
        setModuleEnabled(moduleId, type, enabled);
    };

    // Save changes when moduleStates change, but debounce to avoid too many requests
    // Only save if: 1) Backend data has been loaded, and 2) User has made changes
    useEffect(() => {
        if (!hasInitialized || !hasUserMadeChanges.current) {
            return;
        }
        const timeoutId = setTimeout(() => {
            saveRef.current().catch(console.error);
        }, 300);
        return () => clearTimeout(timeoutId);
    }, [moduleStates, hasInitialized]);

    // Save on unmount if there are pending changes (empty deps = only on unmount)
    useEffect(() => {
        return () => {
            if (hasUserMadeChanges.current) {
                saveRef.current().catch(console.error);
            }
        };
    }, []);

    const renderModuleToggle = (moduleId: ModuleId) => {
        const state = moduleStates[moduleId];
        const adminEnabled = state?.admin ?? true;
        const userEnabled = state?.user ?? true;

        return (
            <div className="theme-tab-content content-narrow">
                <div className="theme-section">
                    <div className="section-header">
                        <h3 className="section-title">{t.featuresPage?.visibility || 'Visibilità'}</h3>
                    </div>
                    <div className="feature-config-options">
                        <div className={`feature-status-badge ${adminEnabled ? 'active' : ''}`}>
                            {adminEnabled ? t.admin.active : t.admin.inactive}
                        </div>
                        <div className="toggle-group">
                            <span className="toggle-label">{t.admin.adminRole}</span>
                            <label className="toggle-modern">
                                <input
                                    type="checkbox"
                                    checked={adminEnabled}
                                    onChange={(e) => handleModuleToggle(moduleId, 'admin', e.target.checked)}
                                />
                                <span className="toggle-slider-modern"></span>
                            </label>
                        </div>
                        <div className="toggle-group">
                            <span className="toggle-label">{t.admin.userRole}</span>
                            <label className={`toggle-modern ${!adminEnabled ? 'disabled' : ''}`}>
                                <input
                                    type="checkbox"
                                    checked={userEnabled}
                                    disabled={!adminEnabled}
                                    onChange={(e) => handleModuleToggle(moduleId, 'user', e.target.checked)}
                                />
                                <span className="toggle-slider-modern"></span>
                            </label>
                        </div>
                    </div>
                </div>
            </div>
        );
    };

    // Drag and drop handlers for ordering
    const handleDragStart = (e: React.DragEvent, moduleId: string) => {
        beginOrderEdit();
        setDraggedItem(moduleId);
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/plain', moduleId);
    };

    const handleDragEnd = () => {
        setDraggedItem(null);
    };

    const handleDragOver = (e: React.DragEvent) => {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'move';
    };

    const handleDrop = (e: React.DragEvent, targetModuleId: string, targetSection: 'top' | 'bottom') => {
        e.preventDefault();
        e.stopPropagation();
        if (!draggedItem) return;

        const draggedPosition = localPositions[draggedItem] || 'top';

        const isSameItem = draggedItem === targetModuleId;
        const positionChanged = draggedPosition !== targetSection;

        if (isSameItem && !positionChanged) return;

        beginOrderEdit();
        if (positionChanged) {
            // Update local positions immediately for UI responsiveness
            setLocalPositions(prev => ({ ...prev, [draggedItem]: targetSection }));
        }
        if (isSameItem) {
            setHasOrderChanges(true);
            return;
        }

        // Reorder within the list
        const newOrder = [...localOrder];
        const draggedIndex = newOrder.indexOf(draggedItem);
        const targetIndex = newOrder.indexOf(targetModuleId);

        if (draggedIndex === -1 || targetIndex === -1) return;

        newOrder.splice(draggedIndex, 1);
        newOrder.splice(targetIndex, 0, draggedItem);

        setLocalOrder(newOrder);
        setHasOrderChanges(true);
    };

    const handleSectionDrop = (e: React.DragEvent, section: 'top' | 'bottom') => {
        e.preventDefault();
        if (!draggedItem) return;

        const draggedPosition = localPositions[draggedItem] || 'top';

        // Change position if moving to different section
        if (draggedPosition !== section) {
            beginOrderEdit();
            // Update local positions immediately for UI responsiveness
            setLocalPositions(prev => ({ ...prev, [draggedItem]: section }));
            setHasOrderChanges(true);
        }
    };

    const handleApplyOrder = async () => {
        try {
            const positionUpdates: Array<{ id: ModuleId; position: 'top' | 'bottom' }> = [];
            TOGGLEABLE_MODULES.forEach(module => {
                const desiredPosition = localPositions[module.id] || module.defaultPosition;
                const currentPosition = moduleStates[module.id]?.position || module.defaultPosition;
                if (desiredPosition !== currentPosition) {
                    positionUpdates.push({ id: module.id, position: desiredPosition });
                }
            });

            if (positionUpdates.length > 0) {
                hasUserMadeChanges.current = true;
                positionUpdates.forEach(({ id, position }) => {
                    setModulePosition(id, position);
                });
            }

            setModuleOrder(localOrder);
            await saveModuleOrder(localOrder);
        } catch (error) {
            console.error('Failed to save order:', error);
        } finally {
            setDraggedItem(null); // Reset drag state
            initialOrderRef.current = buildFullOrder(localOrder);
            initialPositionsRef.current = normalizePositions(localPositions);
            isUserEditing.current = false;
            setHasOrderChanges(false);
        }
    };

    const handleCancelOrder = () => {
        setDraggedItem(null); // Reset drag state
        isUserEditing.current = false; // Done editing
        // Restore to currently applied state from context
        const restoredOrder = buildFullOrder(moduleOrder);
        const restoredPositions = buildPositionsFromStates();
        setLocalOrder(restoredOrder);
        setLocalPositions(restoredPositions);
        initialOrderRef.current = restoredOrder;
        initialPositionsRef.current = restoredPositions;
        setHasOrderChanges(false);
    };

    const getModuleInfo = (moduleId: string) => {
        const module = TOGGLEABLE_MODULES.find(m => m.id === moduleId);
        return module || { id: moduleId, icon: 'extension', defaultEnabled: true };
    };

    // Split modules by position for the config tab (using localPositions for immediate UI updates)
    // Local order for cards (changes during drag)
    const topOrderModules = localOrder.filter(id => {
        const position = localPositions[id];
        return !position || position === 'top';
    });

    const bottomOrderModules = localOrder.filter(id => {
        const position = localPositions[id];
        return position === 'bottom';
    });

    // Applied order for tabs (only changes after Apply)
    const appliedOrder = buildFullOrder(moduleOrder);
    const appliedPositions = buildPositionsFromStates();
    const topAppliedModules = appliedOrder.filter(id => {
        const position = appliedPositions[id];
        return !position || position === 'top';
    });
    const bottomAppliedModules = appliedOrder.filter(id => {
        const position = appliedPositions[id];
        return position === 'bottom';
    });

    const tabIds = ['config', ...topAppliedModules, ...bottomAppliedModules] as TabId[];

    const renderConfigTab = () => {
        return (
            <div className="theme-tab-content content-narrow">
                <div className="theme-section">
                    <div className="section-header">
                        <h3 className="section-title">{t.featuresPage?.topSection || 'Sezione Principale'}</h3>
                    </div>
                    <div
                        className="order-cards"
                        data-swipe-ignore="true"
                        onDragOver={handleDragOver}
                        onDrop={(e) => handleSectionDrop(e, 'top')}
                    >
                        {topOrderModules.map((moduleId) => {
                            const moduleInfo = getModuleInfo(moduleId);
                            const moduleName = t.sidebar[moduleId as keyof typeof t.sidebar] || moduleId;
                            return (
                                <div
                                    key={moduleId}
                                    className={`order-card ${draggedItem === moduleId ? 'dragging' : ''}`}
                                    draggable
                                    onDragStart={(e) => handleDragStart(e, moduleId)}
                                    onDragEnd={handleDragEnd}
                                    onDragOver={handleDragOver}
                                    onDrop={(e) => handleDrop(e, moduleId, 'top')}
                                >
                                    <div className="order-card-preview">
                                        <span className="material-symbols-outlined">{moduleInfo.icon}</span>
                                    </div>
                                    <div className="order-card-info">
                                        <span className="order-card-name">{moduleName}</span>
                                    </div>
                                    <div className="order-card-handle">
                                        <span className="material-symbols-outlined">drag_indicator</span>
                                    </div>
                                </div>
                            );
                        })}
                        {topOrderModules.length === 0 && (
                            <div className="order-empty">{t.featuresPage?.noModulesTop || 'Nessun modulo in questa sezione'}</div>
                        )}
                    </div>
                </div>

                <div className="theme-section">
                    <div className="section-header">
                        <h3 className="section-title">{t.featuresPage?.bottomSection || 'Sezione Inferiore'}</h3>
                    </div>
                    <div
                        className="order-cards"
                        data-swipe-ignore="true"
                        onDragOver={handleDragOver}
                        onDrop={(e) => handleSectionDrop(e, 'bottom')}
                    >
                        {bottomOrderModules.map((moduleId) => {
                            const moduleInfo = getModuleInfo(moduleId);
                            const moduleName = t.sidebar[moduleId as keyof typeof t.sidebar] || moduleId;
                            return (
                                <div
                                    key={moduleId}
                                    className={`order-card ${draggedItem === moduleId ? 'dragging' : ''}`}
                                    draggable
                                    onDragStart={(e) => handleDragStart(e, moduleId)}
                                    onDragEnd={handleDragEnd}
                                    onDragOver={handleDragOver}
                                    onDrop={(e) => handleDrop(e, moduleId, 'bottom')}
                                >
                                    <div className="order-card-preview">
                                        <span className="material-symbols-outlined">{moduleInfo.icon}</span>
                                    </div>
                                    <div className="order-card-info">
                                        <span className="order-card-name">{moduleName}</span>
                                    </div>
                                    <div className="order-card-handle">
                                        <span className="material-symbols-outlined">drag_indicator</span>
                                    </div>
                                </div>
                            );
                        })}
                        {bottomOrderModules.length === 0 && (
                            <div className="order-empty">{t.featuresPage?.noModulesBottom || 'Nessun modulo in questa sezione'}</div>
                        )}
                    </div>
                </div>

                {hasOrderChanges && (
                    <div className="order-actions">
                        <button className="btn-secondary" onClick={handleCancelOrder}>
                            <span className="material-symbols-outlined">close</span>
                            {t.featuresPage?.cancelOrder || 'Annulla'}
                        </button>
                        <button className="btn-primary" onClick={handleApplyOrder}>
                            <span className="material-symbols-outlined">check</span>
                            {t.featuresPage?.applyOrder || 'Applica'}
                        </button>
                    </div>
                )}
            </div>
        );
    };

    const renderTabContent = (tabId: TabId) => {
        if (!hasInitialized || isLoading) {
            return <div className="loading">Loading...</div>;
        }
        switch (tabId) {
            case 'config':
                return renderConfigTab();
            case 'dashboard':
                return (
                    <>
                        {renderModuleToggle('dashboard')}
                        <div className="tab-content-placeholder">
                            <div className="placeholder-icon">
                                <span className="material-symbols-outlined">dashboard</span>
                            </div>
                            <h3>{t.sidebar.dashboard}</h3>
                            <p>{t.features.comingSoon}</p>
                        </div>
                    </>
                );
            case 'feature1':
                return (
                    <>
                        {renderModuleToggle('feature1')}
                        <Feature1Tab />
                    </>
                );
            case 'feature2':
                return (
                    <>
                        {renderModuleToggle('feature2')}
                        <div className="tab-content-placeholder">
                            <div className="placeholder-icon">
                                <span className="material-symbols-outlined">download</span>
                            </div>
                            <h3>{t.features.feature2}</h3>
                            <p>{t.features.comingSoon}</p>
                        </div>
                    </>
                );
            case 'feature3':
                return (
                    <>
                        {renderModuleToggle('feature3')}
                        <div className="tab-content-placeholder">
                            <div className="placeholder-icon">
                                <span className="material-symbols-outlined">cast</span>
                            </div>
                            <h3>{t.features.feature3}</h3>
                            <p>{t.features.comingSoon}</p>
                        </div>
                    </>
                );
            case 'search':
                return (
                    <>
                        {renderModuleToggle('search')}
                        <div className="tab-content-placeholder">
                            <div className="placeholder-icon">
                                <span className="material-symbols-outlined">search</span>
                            </div>
                            <h3>{t.sidebar.search}</h3>
                            <p>{t.features.comingSoon}</p>
                        </div>
                    </>
                );
            case 'notifications':
                return (
                    <>
                        {renderModuleToggle('notifications')}
                        <div className="tab-content-placeholder">
                            <div className="placeholder-icon">
                                <span className="material-symbols-outlined">notifications</span>
                            </div>
                            <h3>{t.sidebar.notifications}</h3>
                            <p>{t.features.comingSoon}</p>
                        </div>
                    </>
                );
            default:
                return null;
        }
    };

    return (
        <main className="main-content admin-panel-root">
            <div className="page-tabs-container">
                <div className="page-tabs-slider" ref={tabsContainerRef}>
                    <button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
                        <span className="material-symbols-outlined">menu</span>
                    </button>
                    <div className="page-title-section">
                        <span className="page-title-text">{t.featuresPage.title}</span>
                    </div>
                    <div className="page-tabs-divider"></div>
                    <button
                        data-tab-id="config"
                        className={`page-tab-btn ${activeTab === 'config' ? 'active' : ''}`}
                        onClick={() => handleTabChange('config')}
                    >
                        <span className="material-symbols-outlined">tune</span>
                        <span>{t.featuresPage?.configTab || 'Configurazione'}</span>
                    </button>
                    {[...topAppliedModules, ...bottomAppliedModules].map((moduleId) => {
                        const moduleInfo = getModuleInfo(moduleId);
                        const moduleName = t.sidebar[moduleId as keyof typeof t.sidebar] || moduleId;
                        return (
                            <button
                                key={moduleId}
                                data-tab-id={moduleId}
                                className={`page-tab-btn ${activeTab === moduleId ? 'active' : ''}`}
                                onClick={() => handleTabChange(moduleId as TabId)}
                            >
                                <span className="material-symbols-outlined">{moduleInfo.icon}</span>
                                <span>{moduleName}</span>
                            </button>
                        );
                    })}
                </div>
            </div>

            <SwipeTabs
                className="admin-tab-swipe"
                tabs={tabIds}
                activeTab={activeTab}
                onTabChange={handleTabChange}
                renderPanel={renderTabContent}
                panelClassName="admin-tab-content swipe-panel-content"
            />
        </main>
    );
}
