import { useEffect } from 'react';
import { useIsAuthenticated, useAuthStore } from './auth.store';
import { useTenantActions, useAvailableTenants, useCurrentTenant, useParentTenant } from './tenant.store';
import { useIsDemoMode, useDemoSessionId, useDemoAccountType } from '../hooks/useAccessControl';
import { useSubscription } from '../api/hooks/subscription';
import { SUBSCRIPTION_TIERS, SubscriptionTier } from '../api/types/subscription';

/**
 * Defines the appropriate subscription tier based on demo account type
 */
const getDemoTierForAccountType = (accountType: string | null): SubscriptionTier => {
  switch (accountType) {
    case 'enterprise':
      return SUBSCRIPTION_TIERS.ENTERPRISE;
    case 'professional':
    default:
      return SUBSCRIPTION_TIERS.PROFESSIONAL;
  }
};

/**
 * Gets tenant data from localStorage (set by DemoPage from backend response)
 * Returns null if not available - caller must handle this case
 */
const getTenantDataFromStorage = (): Record<string, any> | null => {
  const storedTenantData = localStorage.getItem('demo_tenant_data');
  if (storedTenantData) {
    try {
      return JSON.parse(storedTenantData);
    } catch (e) {
      console.error('Failed to parse stored tenant data:', e);
    }
  }
  return null;
};

/**
 * Hook to automatically initialize tenant data when user is authenticated or in demo mode
 * This should be used at the app level to ensure tenant data is loaded
 */
export const useTenantInitializer = () => {
  const isAuthenticated = useIsAuthenticated();
  const isDemoMode = useIsDemoMode();
  const demoSessionId = useDemoSessionId();
  const demoAccountType = useDemoAccountType();
  const availableTenants = useAvailableTenants();
  const currentTenant = useCurrentTenant();
  const parentTenant = useParentTenant(); // Track if we're viewing a child tenant
  const { loadUserTenants, loadChildTenants, setCurrentTenant, setAvailableTenants } = useTenantActions();
  const { subscriptionInfo } = useSubscription();
  // Use reactive hook for user to ensure re-run when auth store rehydrates
  const authUser = useAuthStore((state) => state.user);

  // Load tenants for authenticated users (but not demo users - they have special initialization below)
  useEffect(() => {
    if (isAuthenticated && !availableTenants && !isDemoMode) {
      loadUserTenants();
    }
  }, [isAuthenticated, availableTenants, loadUserTenants, isDemoMode]);

  // Load child tenants for enterprise users
  useEffect(() => {
    if (
      isAuthenticated &&
      !isDemoMode &&
      currentTenant &&
      availableTenants &&
      subscriptionInfo?.plan === 'enterprise'
    ) {
      // Only load if we haven't loaded child tenants yet
      // Check if availableTenants only contains the parent (length === 1)
      const hasOnlyParent = availableTenants.length === 1 && availableTenants[0].id === currentTenant.id;

      if (hasOnlyParent) {
        loadChildTenants();
      }
    }
  }, [isAuthenticated, isDemoMode, currentTenant, availableTenants, subscriptionInfo, loadChildTenants]);

  // Set up mock tenant for demo mode with appropriate subscription tier
  useEffect(() => {
    if (isDemoMode && demoSessionId) {
      const virtualTenantId = localStorage.getItem('virtual_tenant_id');
      const storedTier = localStorage.getItem('subscription_tier');

      // Guard: If no virtual_tenant_id is available, skip tenant setup
      if (!virtualTenantId) {
        return;
      }

      // Check if current tenant is the demo tenant and is properly set
      const isValidDemoTenant = currentTenant &&
        typeof currentTenant === 'object' &&
        currentTenant.id === virtualTenantId;

      // Get tenant data from localStorage (set by DemoPage from backend)
      const tenantData = getTenantDataFromStorage();
      // Use reactive authUser from hook instead of getState() to ensure re-run when user is available
      const userId = authUser?.id;

      // Guard: If no tenant data or user is available, skip tenant setup
      // This means the demo session wasn't properly initialized or auth store hasn't rehydrated yet
      if (!tenantData || !userId) {
        console.log('[useTenantInitializer] Waiting for tenant data or user - tenantData:', !!tenantData, 'userId:', userId);
        return;
      }

      // Determine the appropriate subscription tier
      const subscriptionTier = storedTier as SubscriptionTier || tenantData.subscription_tier || getDemoTierForAccountType(demoAccountType);

      // Create a complete tenant object using data from backend response
      const mockTenant = {
        id: tenantData.id || virtualTenantId,
        name: tenantData.name,
        subdomain: tenantData.subdomain,
        business_type: tenantData.business_type,
        business_model: tenantData.business_model,
        description: tenantData.description,
        address: 'Demo Address',
        city: 'Madrid',
        postal_code: '28001',
        phone: null,
        is_active: tenantData.is_active,
        subscription_plan: subscriptionTier,
        subscription_tier: subscriptionTier,
        tenant_type: tenantData.tenant_type,
        ml_model_trained: false,
        last_training_date: null,
        owner_id: userId,
        created_at: new Date().toISOString(),
      };

      // Only set current tenant if not already valid AND we're not viewing a child tenant
      // CRITICAL: If parentTenant exists, it means we're viewing a child tenant from the Premises page
      // and we should NOT overwrite the current tenant
      if (!isValidDemoTenant && !parentTenant) {
        // Set the demo tenant as current
        setCurrentTenant(mockTenant);

        // Set tenant ID in API client
        import('../api/client').then(({ apiClient }) => {
          apiClient.setTenantId(virtualTenantId);
        });
      }

      // For professional demos, just set the single mock tenant as available (if not already set)
      if (demoAccountType !== 'enterprise') {
        if (!availableTenants || availableTenants.length === 0) {
          setAvailableTenants([mockTenant as any]);
        }
        return;
      }

      // For enterprise demos, ALWAYS ensure child tenants are loaded
      // Check if we need to load child tenants:
      // - availableTenants is empty/null, OR
      // - availableTenants only has the parent (length === 1)
      const needsChildTenants = !availableTenants || availableTenants.length <= 1;

      if (needsChildTenants) {
        console.log('[useTenantInitializer] Enterprise demo - loading child tenants for parent:', virtualTenantId);

        import('../api/services/tenant').then(({ TenantService }) => {
          const tenantService = new TenantService();
          // Use getChildTenants with the parent tenant ID (virtualTenantId)
          // This calls GET /tenants/{tenant_id}/children
          tenantService.getChildTenants(virtualTenantId)
            .then(childTenants => {
              console.log('[useTenantInitializer] Enterprise demo - loaded child tenants:', childTenants?.length, childTenants);
              // Combine parent tenant with children for the tenant switcher
              const allTenants = [mockTenant as any, ...childTenants];
              setAvailableTenants(allTenants);
            })
            .catch((error) => {
              console.error('[useTenantInitializer] Enterprise demo - failed to load child tenants:', error);
              // Fallback: at least set the parent mock tenant as available so TenantSwitcher renders
              if (!availableTenants || availableTenants.length === 0) {
                setAvailableTenants([mockTenant as any]);
              }
            });
        });
      }
    }
  }, [isDemoMode, demoSessionId, demoAccountType, currentTenant, availableTenants, parentTenant, setCurrentTenant, setAvailableTenants, authUser]);
};