import { useState, useEffect, lazy, Suspense, useCallback, useMemo, useRef, useTransition } from 'react'
import MainLayout from './MainLayout'
import type { DashboardData, SidebarData, Notice } from './types'

import { LoadingSkeleton } from './components/ui/LoadingSkeleton'
import { SafeComponent } from './components/ui/SafeComponent'
import { TooltipProvider } from "@/components/ui/tooltip"

// Lazy load components for code splitting
const Dashboard = lazy(() => import('./Dashboard'))
const ActivityLogs = lazy(() => import('./ActivityLogs'))
const SystemInfo = lazy(() => import('./SystemInfo'))
const Connector = lazy(() => import('./Connector'))
const NotificationsBuilder = lazy(() => import('./NotificationsBuilder'))
const EmailTemplates = lazy(() => import('./EmailTemplates'))
const Campaigns = lazy(() => import('./Campaigns'))
const ChatWidget = lazy(() => import('./ChatWidget'))
const PhoneFieldSettings = lazy(() => import('./PhoneFieldSettings'))
const GoogleRecaptchaSettings = lazy(() => import('./GoogleRecaptchaSettings'))
const AuthenticationPagesSettings = lazy(() => import('./AuthenticationPagesSettings'))
const CheckoutVerificationSettings = lazy(() => import('./CheckoutVerificationSettings'))
const RegistrationFormSettings = lazy(() => import('./RegistrationFormSettings'))
const PasswordlessLoginSettings = lazy(() => import('./PasswordlessLoginSettings'))
const AbandonedCartSettings = lazy(() => import('./AbandonedCartSettings'))
const AbandonedCartSessions = lazy(() => import('./AbandonedCartSessions'))
const Senders = lazy(() => import('./Senders'))
const WhatsAppWebSender = lazy(() => import('./WhatsAppWebSender'))
const MetaAPISender = lazy(() => import('./MetaAPISender'))
const FirebaseSender = lazy(() => import('./FirebaseSender'))
const SMTPSender = lazy(() => import('./SMTPSender'))
const BlockManager = lazy(() => import('./BlockManager'))
const SetupWizard = lazy(() => import('./SetupWizard'))

export function App() {
  const [ready, setReady] = useState(false)
  const [currentSection, setCurrentSection] = useState<string>('dashboard')
  const [fetchedData, setFetchedData] = useState<Record<string, unknown>>({})
  const [isDataLoading, setIsDataLoading] = useState(!window.wawpDashboardData)
  const [isPending, startTransition] = useTransition();
  const isFetchingRef = useRef<Record<string, boolean>>({});

  const rawData = window.wawpDashboardData;

  const enrichedData = useMemo(() => {
    if (!rawData) return null;
    const ajaxUrl = rawData.ajaxUrl || rawData.global?.ajaxUrl || window.ajaxurl;

    const merged = {
      ...rawData,
      ...fetchedData,
      sidebarData: {
        ...(rawData?.sidebarData || {}),
        ...(fetchedData?.sidebarData || {}),
        enabledSections: {
          ...((rawData as DashboardData)?.sidebarData?.enabledSections || {}),
          ...((fetchedData as DashboardData)?.sidebarData?.enabledSections || {})
        },
        enabledSenders: {
          ...((rawData as DashboardData)?.sidebarData?.enabledSenders || {}),
          ...((fetchedData as DashboardData)?.sidebarData?.enabledSenders || {})
        }
      },
      i18n: {
        ...(rawData?.i18n || {}),
        ...(fetchedData?.i18n || {})
      },
      global: {
        ...(rawData.global || {}),
        ...(fetchedData.global || {}),
        ajaxUrl,
        section: currentSection
      }
    } as DashboardData;

    return merged;
  }, [rawData, currentSection, fetchedData]);

  // Sync window.wawpDashboardData for non-React components or hooks reading from global window
  useEffect(() => {
    if (enrichedData) {
      window.wawpDashboardData = enrichedData;
    }
  }, [enrichedData]);

  const fetchSectionData = useCallback(async (sectionWithParams: string, force = false) => {
    if (!sectionWithParams) return;
    const [section] = sectionWithParams.split('&');
    if (isFetchingRef.current[sectionWithParams] && !force) return;

    const sectionToDataKey: Record<string, string> = {
      'whatsapp-web-sender': 'instancesData',
      'meta-api-sender': 'metaApiSenderData',
      'firebase-sender': 'firebaseSenderData',
      'smtp-sender': 'smtpSenderData',
      'block-manager': 'blockManagerData',
      'notifications': 'notificationsData',
      'chat_widget': 'chatWidgetData',
      'country-code': 'phoneFieldData',
      'abandoned_carts_settings': 'abandonedCartsSettings',
      'google_recaptcha': 'recaptchaData',
      'authentication-pages': 'authPages',
      'otp_messages': 'authPages',
      'registration-form': 'registrationForm',
      'passwordless-login': 'passwordlessLoginSettings',
      'checkout-verification': 'checkoutVerificationSettings',
      'activity_hub': 'logsData',
      'system_info': 'systemInfo',
      'campaigns': 'campaignsData',
      'campaigns_new': 'campaignsData',
      'email_templates': 'emailTemplatesData',
      'senders': 'sendersData',
      'account': 'connector',
      'abandoned_carts': 'abandonedCartSessions'
    };

    const key = sectionToDataKey[section];
    const hasInitialData = (section === 'dashboard' && enrichedData?.stats) || (key && enrichedData?.[key]);

    // Global Hub Logic: If we already have data and it's not a forced refresh, don't fetch.
    if (!force && hasInitialData) {
      setIsDataLoading(false);
      return;
    }

    isFetchingRef.current[sectionWithParams] = true;
    Promise.resolve().then(() => {
      setIsDataLoading(true);
    });

    try {
      const gData = window.wawpDashboardData;
      const restBaseUrl = gData?.global?.restUrl;
      const wpRestNonce = gData?.global?.wpRestNonce;

      let success = false;
      const cacheBuster = `_=${Date.now()}`;

      if (restBaseUrl) {
        try {
          const separator = restBaseUrl.includes('?') ? '&' : '?';
          const restUrl = `${restBaseUrl}/${section}${separator}${cacheBuster}`;
          const response = await fetch(restUrl, {
            method: 'GET',
            headers: {
              'X-WP-Nonce': wpRestNonce || '',
              'Cache-Control': 'no-cache, no-store, must-revalidate',
              'Pragma': 'no-cache',
              'Expires': '0'
            },
            credentials: 'same-origin'
          });
          if (response.ok) {
            const result = await response.json();
            setFetchedData(prev => {
              const next = { ...prev, ...result };
              if (result.sidebarData && prev.sidebarData) {
                const prevSidebar = prev.sidebarData as SidebarData;
                const resultSidebar = result.sidebarData as SidebarData;
                next.sidebarData = {
                  ...prevSidebar,
                  ...resultSidebar,
                  enabledSections: {
                    ...(prevSidebar.enabledSections || {}),
                    ...(resultSidebar.enabledSections || {})
                  },
                  enabledSenders: {
                    ...(prevSidebar.enabledSenders || {}),
                    ...(resultSidebar.enabledSenders || {})
                  }
                };
              }
              const currentRawNotices = (rawData as DashboardData).notices;
              const prevNotices = Array.isArray(prev.notices) ? prev.notices : (Array.isArray(currentRawNotices) ? currentRawNotices : []);

              if (result.notices && Array.isArray(result.notices)) {
                const combinedNotices = [...prevNotices];
                result.notices.forEach((newNotice: Notice) => {
                  if (!combinedNotices.some(n => n.type === newNotice.type && n.url === newNotice.url)) {
                    combinedNotices.push(newNotice);
                  }
                });
                next.notices = combinedNotices;
              } else if (!result.notices && prevNotices.length > 0) {
                next.notices = prevNotices;
              }

              // Update global window object to keep it in sync for non-React code or deep components
              if (window.wawpDashboardData) {
                window.wawpDashboardData = {
                  ...window.wawpDashboardData,
                  ...next
                } as DashboardData;
              }

              return next;
            });
            success = true;
          }
        } catch (restErr) {
          console.warn(`[WAWP] REST Fetch failed for ${section}`, restErr);
        }
      }

      if (!success) {
        throw new Error(`Failed to fetch section data for ${section}`);
      }
    } catch (err) {
      console.error(`[WAWP] Critical fetch error for ${section}`, err);
      isFetchingRef.current[section] = false;
    } finally {
      setIsDataLoading(false);
    }
  }, [enrichedData, rawData]);

  useEffect(() => {
    const checkReady = () => {
      const data = window.wawpDashboardData;
      if (data) {
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('token')) {
          urlParams.delete('token');
          const cleanUrl = window.location.pathname + (urlParams.toString() ? '?' + urlParams.toString() : '');
          window.history.replaceState({}, '', cleanUrl);
        }

        const sectionFromUrl = urlParams.get('wawp_section');
        const initialSection = sectionFromUrl || data.global?.section || (data as DashboardData).currentSection || 'dashboard';
        setCurrentSection(initialSection);
        setReady(true);
      } else {
        setTimeout(checkReady, 100);
      }
    };
    checkReady();
  }, []);

  useEffect(() => {
    if (ready && currentSection) {
      const timer = setTimeout(() => {
        fetchSectionData(currentSection);
      }, 0);
      return () => clearTimeout(timer);
    }
  }, [currentSection, ready, fetchSectionData]);

  useEffect(() => {
    if (ready && currentSection) {
      const urlParams = new URLSearchParams(window.location.search);
      const highlight = urlParams.get('highlight_setting');
      if (highlight) {
        const timer = setTimeout(() => {
          let element = (document.getElementById(highlight) ||
            document.querySelector(`[name="${highlight}"]`) ||
            document.querySelector(`[data-setting-key="${highlight}"]`)) as HTMLElement | null;

          if (!element) {
            const inputs = document.querySelectorAll('input, textarea, select');
            for (const input of Array.from(inputs)) {
              const name = input.getAttribute('name') || '';
              const id = input.getAttribute('id') || '';
              if (name.includes(highlight) || id.includes(highlight) || name.replace(/_/g, '-').includes(highlight)) {
                element = (input.closest('.p-4') || input.closest('.space-y-4') || input.closest('div') || input) as HTMLElement;
                break;
              }
            }
          }

          if (!element) {
            const elements = document.querySelectorAll('label, span, h4, h5, div, p');
            const targetWords = highlight.replace(/-/g, ' ').toLowerCase();
            for (const el of Array.from(elements)) {
              const text = el.textContent?.toLowerCase() || '';
              if (text.includes(targetWords) && el.children.length === 0) {
                element = (el.closest('.p-4') || el.closest('.space-y-4') || el.closest('.space-y-6') || el) as HTMLElement;
                break;
              }
            }
          }

          if (element) {
            const wrapper = (element.closest('.p-4') || element.closest('.space-y-4') || element) as HTMLElement;
            wrapper.classList.add('animate-highlight-glow');
            wrapper.scrollIntoView({ behavior: 'smooth', block: 'center' });

            setTimeout(() => {
              wrapper.classList.remove('animate-highlight-glow');
              const cleanParams = new URLSearchParams(window.location.search);
              cleanParams.delete('highlight_setting');
              const cleanUrl = window.location.pathname + (cleanParams.toString() ? '?' + cleanParams.toString() : '');
              window.history.replaceState({}, '', cleanUrl);
            }, 3000);
          }
        }, 600);
        return () => clearTimeout(timer);
      }
    }
  }, [currentSection, ready]);

  const handleNavigation = useCallback((e: Event | CustomEvent<string>) => {
    const section = (e as CustomEvent<string>).detail;
    if (section) {
      // Allow re-navigation if it's a creation link or if it has parameters
      if (section === currentSection && !section.includes('&') && !section.includes('_new')) return;

      // Data Hub: We no longer delete the data when navigating. 
      // This allows for instant back-and-forth transitions.

      isFetchingRef.current[section] = false;
      startTransition(() => {
        setCurrentSection(section);
      });
      const url = new URL(window.location.href);
      // Clean up common parameters before setting new ones
      ['action', 'id', 'highlight_setting'].forEach(p => url.searchParams.delete(p));

      if (section.includes('&')) {
        const [baseSection, ...rest] = section.split('&');
        url.searchParams.set('wawp_section', baseSection);
        rest.forEach(pair => {
          const [k, v] = pair.split('=');
          if (k && v) url.searchParams.set(k, v);
        });
      } else {
        url.searchParams.set('wawp_section', section);
      }

      window.history.pushState({}, '', url.toString());
    }
  }, [currentSection]);

  useEffect(() => {
    const handlePopState = () => {
      const params = new URLSearchParams(window.location.search);
      const section = params.get('wawp_section') || 'dashboard';
      startTransition(() => {
        setCurrentSection(section);
      });
    };

    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      if (window.wawpIsDirty) {
        e.preventDefault();
        e.returnValue = '';
      }
    };

    const handleRefresh = (e: Event | CustomEvent<string | { section: string }>) => {
      const detail = (e as CustomEvent).detail;
      const section = (typeof detail === 'object' ? (detail as { section: string })?.section : detail) || currentSection;
      if (!section) return;
      isFetchingRef.current[section] = false;
      fetchSectionData(section, true);
    };

    const handleSendersUpdate = (e: Event | CustomEvent<Record<string, number>>) => {
      const detail = (e as CustomEvent).detail;
      if (detail) {
        setFetchedData(prev => {
          const currentSidebar = (prev.sidebarData || (rawData as DashboardData).sidebarData) as SidebarData;
          return {
            ...prev,
            sidebarData: {
              ...currentSidebar,
              enabledSenders: {
                ...(currentSidebar.enabledSenders || {}),
                ...detail
              }
            }
          };
        });
      }
    };

    const handleSectionsUpdate = (e: Event | CustomEvent<Record<string, unknown>>) => {
      const detail = (e as CustomEvent).detail;
      if (detail) {
        setFetchedData(prev => {
          const currentSidebar = (prev.sidebarData || (rawData as DashboardData).sidebarData) as SidebarData;
          return {
            ...prev,
            sidebarData: {
              ...currentSidebar,
              enabledSections: {
                ...(currentSidebar.enabledSections || {}),
                ...detail
              }
            }
          };
        });
      }
    };

    window.addEventListener('beforeunload', handleBeforeUnload);
    window.addEventListener('wawp-navigate', handleNavigation);
    window.addEventListener('wawp-refresh-data', handleRefresh);
    window.addEventListener('wawp-senders-updated', handleSendersUpdate);
    window.addEventListener('wawp-sections-updated', handleSectionsUpdate);
    window.addEventListener('popstate', handlePopState);

    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
      window.removeEventListener('wawp-navigate', handleNavigation);
      window.removeEventListener('wawp-refresh-data', handleRefresh);
      window.removeEventListener('wawp-senders-updated', handleSendersUpdate);
      window.removeEventListener('wawp-sections-updated', handleSectionsUpdate);
      window.removeEventListener('popstate', handlePopState);
    };
  }, [handleNavigation, currentSection, fetchSectionData, rawData]);

  if (!ready || !enrichedData) return null;

  const renderContent = () => {


    const sectionToDataKey: Record<string, string> = {
      'whatsapp-web-sender': 'instancesData',
      'meta-api-sender': 'metaApiSenderData',
      'firebase-sender': 'firebaseSenderData',
      'smtp-sender': 'smtpSenderData',
      'block-manager': 'blockManagerData',
      'notifications': 'notificationsData',
      'chat_widget': 'chatWidgetData',
      'country-code': 'phoneFieldData',
      'abandoned_carts_settings': 'abandonedCartsSettings',
      'google_recaptcha': 'recaptchaData',
      'authentication-pages': 'authPages',
      'registration-form': 'registrationForm',
      'passwordless-login': 'passwordlessLoginSettings',
      'abandoned_carts': 'abandonedCartSessions',
      'activity_hub': 'logsData',
      'system_info': 'systemInfo',
      'campaigns': 'campaignsData',
      'campaigns_new': 'campaignsData',
      'email_templates': 'emailTemplatesData',
      'senders': 'sendersData',
      'account': 'connector'
    };

    const key = sectionToDataKey[currentSection];
    if (isDataLoading && key && !enrichedData[key]) {
      return <LoadingSkeleton />;
    }

    const isLogSection = ['activity_hub'].includes(currentSection);

    const componentsMap: Record<string, React.ComponentType<{ data: DashboardData }>> = {
      'dashboard': Dashboard,
      'system_info': SystemInfo,
      'account': Connector,
      'notifications': NotificationsBuilder,
      'email_templates': EmailTemplates,
      'campaigns': Campaigns,
      'campaigns_new': Campaigns,
      'chat_widget': ChatWidget,
      'country-code': PhoneFieldSettings,
      'google_recaptcha': GoogleRecaptchaSettings,
      'authentication-pages': AuthenticationPagesSettings,
      'checkout-verification': CheckoutVerificationSettings,
      'registration-form': RegistrationFormSettings,
      'passwordless-login': PasswordlessLoginSettings,
      'otp_messages': AuthenticationPagesSettings,
      'abandoned_carts_settings': AbandonedCartSettings,
      'abandoned_carts': AbandonedCartSessions,
      'senders': Senders,
      'whatsapp-web-sender': WhatsAppWebSender,
      'meta-api-sender': MetaAPISender,
      'firebase-sender': FirebaseSender,
      'smtp-sender': SMTPSender,
      'block-manager': BlockManager,
      'activity_hub': ActivityLogs
    };

    const [baseSection] = currentSection.split('&');
    const TargetComponent = componentsMap[currentSection] || componentsMap[baseSection] || (isLogSection ? ActivityLogs : Dashboard);



    return (
      <SafeComponent data={enrichedData}>
        <TargetComponent data={enrichedData} />
      </SafeComponent>
    );
  }

  return (
    <TooltipProvider>
      <MainLayout data={enrichedData}>
        {isPending && <div className="fixed top-0 left-0 w-full h-1 bg-emerald-500/30 z-[9999] animate-pulse" />}
        <Suspense fallback={<LoadingSkeleton />}>
          {renderContent()}
        </Suspense>
        <Suspense fallback={null}>
          <SetupWizard data={enrichedData} />
        </Suspense>
      </MainLayout>
    </TooltipProvider>
  )
}
