import { useState, useEffect } from 'react';
import { PageElementConfig, getPageElementConfigs } from '../services/pageElements';

export const usePageElementConfig = (pageType: string, elementName: string, defaultVariant: string = 'unified') => {
  const [variant, setVariant] = useState<string>(defaultVariant);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let active = true;

    const loadConfig = async () => {
      try {
        const configs = await getPageElementConfigs(pageType);
        if (active) {
          const config = configs.find(c => c.element_name === elementName);
          if (config) {
            setVariant(config.variant);
          }
        }
      } catch (error) {
        console.error(`Failed to load config for ${elementName}:`, error);
      } finally {
        if (active) {
          setLoading(false);
        }
      }
    };

    loadConfig();

    return () => {
      active = false;
    };
  }, [pageType, elementName, defaultVariant]);

  return { variant, loading };
};

export const useAllPageElementConfigs = (pageType: string) => {
  const [configs, setConfigs] = useState<Record<string, string>>({});
  const [visibility, setVisibility] = useState<Record<string, boolean>>({});
  const [styles, setStyles] = useState<Record<string, Record<string, any>>>({});
  const [elementOrder, setElementOrder] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshKey, setRefreshKey] = useState<number>(0);

  useEffect(() => {
    let active = true;

    // Helper function to apply DOM order
    const applyDOMOrder = (order: string[]) => {
      // Check if MyUIbrix viewport wrapper is active
      const viewportWrapper = document.querySelector('.myuibrix-viewport-wrapper');
      const container = viewportWrapper || document.querySelector('.container');
      if (!container) return;
      
      const sections = Array.from(container.querySelectorAll('[data-element]')) as HTMLElement[];
      const elementMap = new Map<string, HTMLElement>();
      sections.forEach(section => {
        const elementName = section.getAttribute('data-element');
        if (elementName) {
          elementMap.set(elementName, section);
        }
      });
      
      order.forEach((elementName) => {
        const element = elementMap.get(elementName);
        if (element && element.parentElement === container) {
          container.appendChild(element);
        }
      });
    };

    const loadConfigs = async () => {
      try {
        const data = await getPageElementConfigs(pageType);
        if (active) {
          const configMap: Record<string, string> = {};
          const visMap: Record<string, boolean> = {};
          
          // Sort by display_order to get correct element order
          const sorted = [...data].sort((a, b) => (a.display_order || 0) - (b.display_order || 0));
          const order = sorted.map(config => config.element_name);
          
          sorted.forEach(config => {
            configMap[config.element_name] = config.variant;
            visMap[config.element_name] = config.visible !== false;
          });
          
          setConfigs(configMap);
          setVisibility(visMap);
          setElementOrder(order);
          
          // Apply initial order to DOM if elements exist
          if (order.length > 0) {
            requestAnimationFrame(() => {
              applyDOMOrder(order);
            });
          }
        }
      } catch (error) {
        console.error('Failed to load page element configs:', error);
      } finally {
        if (active) {
          setLoading(false);
        }
      }
    };

    loadConfigs();

    // Listen for live updates from MyUIbrix editor (ONLY in preview mode)
    const handleMyUIbrixChange = ((event: CustomEvent) => {
      const { elementName, variant, visible, previewMode, timestamp } = event.detail;
      
      // Only apply changes if in preview mode (editing)
      // This prevents production users from seeing draft changes
      if (previewMode) {
        console.log(`[usePageElementConfig] Variant change: ${elementName} -> ${variant}`);
        
        setConfigs(prev => ({
          ...prev,
          [elementName]: variant
        }));
        
        setVisibility(prev => ({
          ...prev,
          [elementName]: visible
        }));
        
        // Force React to re-render by incrementing refresh key
        setRefreshKey(prev => prev + 1);
      }
    }) as EventListener;

    // Listen for reorder events
    const handleMyUIbrixReorder = ((event: CustomEvent) => {
      const { order } = event.detail;
      setElementOrder(order);
      applyDOMOrder(order);
    }) as EventListener;

    // Listen for style changes from VisualStylePanel
    const handleMyUIbrixStyleChange = ((event: CustomEvent) => {
      const { elementName, styles: newStyles, previewMode } = event.detail;
      
      if (previewMode) {
        // Only update state - let React apply the styles through component rendering
        // This prevents conflicts with React's virtual DOM
        setStyles(prev => ({
          ...prev,
          [elementName]: newStyles
        }));
      }
    }) as EventListener;

    window.addEventListener('myuibrix-change', handleMyUIbrixChange);
    window.addEventListener('myuibrix-reorder', handleMyUIbrixReorder);
    window.addEventListener('myuibrix-style-change', handleMyUIbrixStyleChange);

    return () => {
      active = false;
      window.removeEventListener('myuibrix-change', handleMyUIbrixChange);
      window.removeEventListener('myuibrix-reorder', handleMyUIbrixReorder);
      window.removeEventListener('myuibrix-style-change', handleMyUIbrixStyleChange);
    };
  }, [pageType]);

  const getVariant = (elementName: string, defaultVariant: string = 'unified'): string => {
    return configs[elementName] || defaultVariant;
  };

  const isVisible = (elementName: string, defaultVisible: boolean = true): boolean => {
    return visibility[elementName] !== undefined ? visibility[elementName] : defaultVisible;
  };

  const getStyles = (elementName: string): Record<string, any> | undefined => {
    return styles[elementName];
  };

  return { configs, visibility, styles, elementOrder, getVariant, isVisible, getStyles, loading, refreshKey };
};
