import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Outlet, useLocation, useSearchParams, useNavigate } from 'react-router-dom';
import Sidebar from '../components/Sidebar';
import TopBar from '../components/TopBar';
import TrialBanner from '../components/TrialBanner';
import SandboxBanner from '../components/SandboxBanner';
import QuotaWarningBanner from '../components/QuotaWarningBanner';
import QuotaOverageModal, { resetQuotaOverageModalDismissal } from '../components/QuotaOverageModal';
import { Business, User } from '../types';
import MasqueradeBanner from '../components/MasqueradeBanner';
import OnboardingWizard from '../components/OnboardingWizard';
import TicketModal from '../components/TicketModal';
import FloatingHelpButton from '../components/FloatingHelpButton';
import { useStopMasquerade } from '../hooks/useAuth';
import { useNotificationWebSocket } from '../hooks/useNotificationWebSocket';
import { useTicket } from '../hooks/useTickets';
import { MasqueradeStackEntry } from '../api/auth';
import { useScrollToTop } from '../hooks/useScrollToTop';
import { SandboxProvider, useSandbox } from '../contexts/SandboxContext';
import { applyColorPalette, applyBrandColors, defaultColorPalette } from '../utils/colorUtils';

interface BusinessLayoutProps {
  business: Business;
  user: User;
  darkMode: boolean;
  toggleTheme: () => void;
  onSignOut: () => void;
  updateBusiness: (updates: Partial<Business>) => void;
}

/**
 * Wrapper component for SandboxBanner that uses the sandbox context
 */
const SandboxBannerWrapper: React.FC = () => {
  const { isSandbox, toggleSandbox, isToggling } = useSandbox();

  return (
    <SandboxBanner
      isSandbox={isSandbox}
      onSwitchToLive={() => toggleSandbox(false)}
      isSwitching={isToggling}
    />
  );
};

const BusinessLayoutContent: React.FC<BusinessLayoutProps> = ({ business, user, darkMode, toggleTheme, onSignOut, updateBusiness }) => {
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
  const [showOnboarding, setShowOnboarding] = useState(false);
  const [ticketModalId, setTicketModalId] = useState<string | null>(null);
  const mainContentRef = useRef<HTMLElement>(null);
  const location = useLocation();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();

  useScrollToTop(mainContentRef);

  // Fetch ticket data when modal is opened from notification
  const { data: ticketFromNotification } = useTicket(ticketModalId || undefined);

  const handleTicketClick = (ticketId: string) => {
    setTicketModalId(ticketId);
  };

  const closeTicketModal = () => {
    setTicketModalId(null);
  };

  // Set CSS custom properties for brand colors (primary palette + secondary color)
  useEffect(() => {
    applyBrandColors(
      business.primaryColor || '#2563eb',
      business.secondaryColor || business.primaryColor || '#2563eb'
    );

    // Cleanup: reset to defaults when component unmounts
    return () => {
      applyColorPalette(defaultColorPalette);
      document.documentElement.style.setProperty('--color-brand-secondary', '#0ea5e9');
    };
  }, [business.primaryColor, business.secondaryColor]);

  // Check for trial expiration and redirect
  useEffect(() => {
    // Don't check if already on trial-expired page
    if (location.pathname === '/dashboard/trial-expired') {
      return;
    }

    // Redirect to trial-expired page if trial has expired
    if (business.isTrialExpired && business.status === 'Trial') {
      navigate('/dashboard/trial-expired', { replace: true });
    }
  }, [business.isTrialExpired, business.status, location.pathname, navigate]);

  // Masquerade logic - now using the stack system
  const [masqueradeStack, setMasqueradeStack] = useState<MasqueradeStackEntry[]>([]);
  const stopMasqueradeMutation = useStopMasquerade();

  useEffect(() => {
    const stackJson = localStorage.getItem('masquerade_stack');
    if (stackJson) {
      try {
        setMasqueradeStack(JSON.parse(stackJson));
      } catch (e) {
        console.error('Failed to parse masquerade stack data', e);
      }
    }
  }, []);

  const handleStopMasquerade = () => {
    // Reset quota modal dismissal when returning from masquerade
    resetQuotaOverageModalDismissal();
    stopMasqueradeMutation.mutate();
  };

  // Reset quota modal when user changes (masquerade start)
  const prevUserIdRef = useRef<string | undefined>(undefined);
  useEffect(() => {
    if (prevUserIdRef.current !== undefined && prevUserIdRef.current !== user.id) {
      // User changed (masquerade started or changed) - reset modal
      resetQuotaOverageModalDismissal();
    }
    prevUserIdRef.current = user.id;
  }, [user.id]);

  useNotificationWebSocket(); // Activate the notification WebSocket listener

  // Get the previous user from the stack (the one we'll return to)
  const previousUser = masqueradeStack.length > 0
    ? {
        id: masqueradeStack[masqueradeStack.length - 1].user_id,
        username: masqueradeStack[masqueradeStack.length - 1].username,
        name: masqueradeStack[masqueradeStack.length - 1].username,
        role: masqueradeStack[masqueradeStack.length - 1].role,
        email: '',
        is_staff: false,
        is_superuser: false,
      } as User
    : null;

  // Get the original user (first in the stack)
  const originalUser = masqueradeStack.length > 0
    ? {
        id: masqueradeStack[0].user_id,
        username: masqueradeStack[0].username,
        name: masqueradeStack[0].username,
        role: masqueradeStack[0].role,
        email: '',
        is_staff: false,
        is_superuser: false,
      } as User
    : null;

  useEffect(() => {
    mainContentRef.current?.focus();
    setIsMobileMenuOpen(false);
  }, [location.pathname]);

  // Check if returning from Stripe Connect onboarding
  useEffect(() => {
    const isOnboardingReturn = searchParams.get('onboarding') === 'true';

    // Only show onboarding if returning from Stripe Connect
    if (isOnboardingReturn) {
      setShowOnboarding(true);
    }
  }, [searchParams]);

  const handleOnboardingComplete = () => {
    setShowOnboarding(false);
    // Update local state immediately so wizard doesn't re-appear
    updateBusiness({ initialSetupComplete: true });
  };

  const handleOnboardingSkip = () => {
    setShowOnboarding(false);
    // If they skip Stripe setup, disable payments
    updateBusiness({ paymentsEnabled: false });
  };

  return (
    <div className="flex h-full bg-gray-50 dark:bg-gray-900 transition-colors duration-200">
      {/* Floating Help Button */}
      <FloatingHelpButton />

      <div className={`fixed inset-y-0 left-0 z-40 transform ${isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full'} transition-transform duration-300 ease-in-out md:hidden`}>
        <Sidebar business={business} user={user} isCollapsed={false} toggleCollapse={() => { }} />
      </div>
      {isMobileMenuOpen && <div className="fixed inset-0 z-30 bg-black/50 md:hidden" onClick={() => setIsMobileMenuOpen(false)}></div>}

      <div className="hidden md:flex md:flex-shrink-0">
        <Sidebar business={business} user={user} isCollapsed={isCollapsed} toggleCollapse={() => setIsCollapsed(!isCollapsed)} />
      </div>

      <div className="flex flex-col flex-1 min-w-0 overflow-hidden">
        {originalUser && (
          <MasqueradeBanner
            effectiveUser={user}
            originalUser={originalUser}
            previousUser={null}
            onStop={handleStopMasquerade}
          />
        )}
        {/* Quota overage warning banner - show for owners and managers */}
        {user.quota_overages && user.quota_overages.length > 0 && (
          <QuotaWarningBanner overages={user.quota_overages} />
        )}
        {/* Quota overage modal - shows once per session on login/masquerade */}
        {user.quota_overages && user.quota_overages.length > 0 && (
          <QuotaOverageModal overages={user.quota_overages} onDismiss={() => {}} />
        )}
        {/* Sandbox mode banner */}
        <SandboxBannerWrapper />
        {/* Show trial banner if trial is active and payments not yet enabled */}
        {business.isTrialActive && !business.paymentsEnabled && business.plan !== 'Free' && (
          <TrialBanner business={business} />
        )}
        <TopBar
          user={user}
          isDarkMode={darkMode}
          toggleTheme={toggleTheme}
          onMenuClick={() => setIsMobileMenuOpen(true)}
          onTicketClick={handleTicketClick}
        />

        <main ref={mainContentRef} tabIndex={-1} className="flex-1 overflow-auto focus:outline-none">
          {/* Pass all necessary context down to child routes */}
          <Outlet context={{ user, business, updateBusiness }} />
        </main>
      </div>

      {/* Onboarding wizard for paid-tier businesses */}
      {showOnboarding && (
        <OnboardingWizard
          business={business}
          onComplete={handleOnboardingComplete}
          onSkip={handleOnboardingSkip}
        />
      )}

      {/* Ticket modal opened from notification */}
      {ticketModalId && ticketFromNotification && (
        <TicketModal
          ticket={ticketFromNotification}
          onClose={closeTicketModal}
        />
      )}
    </div>
  );
};

/**
 * Business Layout with Sandbox Provider
 */
const BusinessLayout: React.FC<BusinessLayoutProps> = (props) => {
  return (
    <SandboxProvider>
      <BusinessLayoutContent {...props} />
    </SandboxProvider>
  );
};

export default BusinessLayout;