/**
 * ============================================================================
 * COMPLETE HIERARCHICAL TOGGLE SYSTEM
 * ============================================================================
 * 
 * A production-ready toggle management system for 3-level hierarchies
 * App → Module → Feature with comprehensive business rule enforcement
 * 
 * @version 1.0.0
 * @author Your Team
 */

// ============================================================================
// TYPE DEFINITIONS
// ============================================================================

export interface Feature {
  id: number;
  name: string;
  slug: string;
  price_per_tenant: number;
  price_per_user: number;
  selected: boolean; // Visual state - is the switch ON?
  is_required: boolean;
  status: number; // 1 = enabled, 0 = disabled (from config)
  enabled?: boolean; // From pivot table - was this feature enabled in package?
  inPackage?: boolean; // Track if feature is part of package (for saving with status=0 when parent disabled)
}

export interface Module {
  id: number;
  name: string;
  features: Feature[];
  is_required: boolean;
  status: number;
  selected?: boolean; // Visual state - is the module ON?
  inPackage?: boolean; // Track if module is part of package
}

export interface App {
  id: number;
  name: string;
  modules: Module[];
  is_required: boolean;
  status: number;
  enabled?: boolean; // Visual state - is the app ON?
  inPackage?: boolean; // Track if app is part of package
}

// ============================================================================
// UTILITY FUNCTIONS
// ============================================================================

/**
 * Check if a module is enabled (either explicitly or has enabled features)
 */
const isModuleEnabled = (module: Module): boolean => {
  return module.selected === true || module.features.some(f => f.selected);
};

/**
 * Check if an app has any enabled modules
 */
const hasEnabledModules = (app: App): boolean => {
  return app.modules.some(m => isModuleEnabled(m));
};

/**
 * Enable only required features in a module
 */
const enableRequiredFeatures = (module: Module): Module => {
  return {
    ...module,
    features: module.features.map(feature => ({
      ...feature,
      selected: feature.is_required ? true : feature.selected
    }))
  };
};

/**
 * Enable a module (used when toggling module ON)
 * - Sets module.selected = true
 * - If module has required features: enable ONLY the required features
 * - If module has NO required features: enable NO features (user picks manually)
 */
const enableModuleWithFeatures = (module: Module): Module => {
  const hasRequiredFeatures = module.features.some(f => f.is_required);
  
  return {
    ...module,
    selected: true, // Mark module as enabled
    features: module.features.map(feature => ({
      ...feature,
      // Only enable required features automatically
      // Non-required features stay as-is (user picks manually)
      selected: hasRequiredFeatures 
        ? (feature.is_required ? true : feature.selected) 
        : feature.selected  // Keep current state, don't auto-enable
    }))
  };
};

/**
 * Disable a module visually but mark features as still in package
 * Features turn OFF visually but inPackage=true so they save with status=0
 */
const disableModuleKeepInPackage = (module: Module): Module => {
  return {
    ...module,
    selected: false, // Visual: module is OFF
    inPackage: true, // Track: module is still part of package
    features: module.features.map(feature => ({
      ...feature,
      selected: false, // Visual: feature switch is OFF
      // Keep feature in package if it was selected OR already in package
      // This ensures we don't lose tracking when parent is disabled
      inPackage: feature.selected || feature.inPackage || false
    }))
  };
};

/**
 * Disable all features in a module AND remove from package
 * Used when user explicitly unchecks a module (not when parent is disabled)
 */
const disableAllFeatures = (module: Module): Module => {
  return {
    ...module,
    selected: false,
    inPackage: false, // Not in package anymore
    features: module.features.map(feature => ({
      ...feature,
      selected: false,
      inPackage: false // Not in package anymore
    }))
  };
};

/**
 * Enable only required modules in an app
 * For required modules, enable their features appropriately
 * Non-required modules/features stay OFF but remain in package with status=0
 */
const enableRequiredModules = (app: App): App => {
  return {
    ...app,
    modules: app.modules.map(module => {
      if (module.is_required) {
        // Enable required module and its required features
        return enableModuleWithFeatures(module);
      }
      // Non-required modules stay OFF but keep inPackage status
      return module;
    })
  };
};

/**
 * Disable all modules in an app visually but keep them in package
 * All modules and features turn OFF visually but save with status=0
 */
const disableAllModulesKeepInPackage = (app: App): App => {
  return {
    ...app,
    enabled: false,
    inPackage: true,
    modules: app.modules.map(module => ({
      ...module,
      selected: false, // Visual: module is OFF
      // Module stays in package if it was already in package OR has any features in package
      inPackage: module.inPackage || module.features.some(f => f.selected || f.inPackage),
      features: module.features.map(feature => ({
        ...feature,
        selected: false, // Visual: feature switch is OFF
        // Keep feature in package if it was selected OR already in package
        inPackage: feature.selected || feature.inPackage || false
      }))
    }))
  };
};

// ============================================================================
// FEATURE TOGGLE HANDLER
// ============================================================================

/**
 * Toggle a feature and cascade changes upward
 * 
 * Rules:
 * - Cannot disable if is_required = true (UI should block)
 * - Enabling: auto-enables parent module and app, marks as inPackage
 * - Disabling: turns OFF visually but keeps inPackage=true (saves with status=0)
 */
export const toggleFeature = (
  hierarchy: App[],
  featureId: number,
  enable: boolean
): App[] => {
  return hierarchy.map(app => {
    // Find if this feature belongs to this app
    const featureExists = app.modules.some(m => 
      m.features.some(f => f.id === featureId)
    );

    if (!featureExists) return app;

    const updatedApp = {
      ...app,
      modules: app.modules.map(module => {
        const feature = module.features.find(f => f.id === featureId);
        
        if (!feature) return module;

        // IMPORTANT: UI should block disabling required features
        if (!enable && feature.is_required) {
          console.warn('Cannot disable required feature:', feature.name);
          return module;
        }

        // Update the target feature
        const updatedModule = {
          ...module,
          features: module.features.map(f => {
            if (f.id === featureId) {
              return { 
                ...f, 
                selected: enable,
                inPackage: true // Always mark as in package when toggled
              };
            }
            // When enabling a feature, also enable all required features in the module
            if (enable && f.is_required) {
              return { ...f, selected: true, inPackage: true };
            }
            return f;
          })
        };

        // If enabling, mark module as selected and in package
        if (enable) {
          updatedModule.selected = true;
          updatedModule.inPackage = true;
        }
        // If disabling and no features remain selected, mark module as not selected
        // but keep inPackage=true so it saves with status=0
        else if (!updatedModule.features.some(f => f.selected)) {
          updatedModule.selected = false;
          // Keep inPackage true for all features that were in package
        }

        return updatedModule;
      })
    };

    // CASCADE UP: Enabling feature enables app
    if (enable) {
      updatedApp.enabled = true;
      updatedApp.inPackage = true;
    } 
    // CASCADE UP: Disabling feature may disable app visually if no modules remain
    else if (!app.is_required && !hasEnabledModules(updatedApp)) {
      updatedApp.enabled = false;
      // Keep inPackage true
    }

    return updatedApp;
  });
};

// ============================================================================
// MODULE TOGGLE HANDLER
// ============================================================================

/**
 * Toggle a module and cascade changes
 * 
 * Rules:
 * - Cannot disable if is_required = true (UI should block)
 * - Enabling: auto-enables parent app and required features in module
 * - Disabling: turns OFF visually but keeps in package (saves with status=0)
 */
export const toggleModule = (
  hierarchy: App[],
  appName: string,
  moduleName: string,
  enable: boolean
): App[] => {
  return hierarchy.map(app => {
    if (app.name !== appName) return app;

    const updatedApp = {
      ...app,
      modules: app.modules.map(module => {
        if (module.name !== moduleName) return module;

        // IMPORTANT: UI should block disabling required modules
        if (!enable && module.is_required) {
          console.warn('Cannot disable required module:', module.name);
          return module;
        }

        if (enable) {
          // Enable module and its required features
          const enabledModule = enableModuleWithFeatures(module);
          return {
            ...enabledModule,
            inPackage: true
          };
        } else {
          // Disable module visually but keep in package (saves with status=0)
          return disableModuleKeepInPackage(module);
        }
      })
    };

    // CASCADE UP: Enabling module enables app
    if (enable) {
      updatedApp.enabled = true;
      updatedApp.inPackage = true;
    }
    // CASCADE UP: Disabling module may disable app if no modules remain
    else if (!app.is_required && !hasEnabledModules(updatedApp)) {
      updatedApp.enabled = false;
      // Keep app in package though
    }

    return updatedApp;
  });
};

// ============================================================================
// APP TOGGLE HANDLER
// ============================================================================

/**
 * Toggle an app and cascade changes downward
 * 
 * Rules:
 * - Cannot disable if is_required = true (UI should block)
 * - Enabling: auto-enables required modules and their required features
 * - Disabling: disables all modules and features (parent override)
 */
export const toggleApp = (
  hierarchy: App[],
  appName: string,
  enable: boolean
): App[] => {
  return hierarchy.map(app => {
    if (app.name !== appName) return app;

    // IMPORTANT: UI should block disabling required apps
    if (!enable && app.is_required) {
      console.warn('Cannot disable required app:', app.name);
      return app;
    }

    if (enable) {
      // Enable app and required modules with their required features
      const enabledApp = enableRequiredModules(app);
      return {
        ...enabledApp,
        enabled: true,
        inPackage: true
      };
    } else {
      // Disable everything visually but keep in package (saves with status=0)
      return disableAllModulesKeepInPackage(app);
    }
  });
};

// ============================================================================
// VALIDATION HELPERS
// ============================================================================

/**
 * Check if an item can be disabled (not required)
 */
export const canDisable = (item: { is_required: boolean }): boolean => {
  return !item.is_required;
};

/**
 * Check if an item is interactive (status = 1 and parent is enabled)
 */
export const isInteractive = (
  status: number,
  parentEnabled: boolean = true
): boolean => {
  return status === 1 && parentEnabled;
};

/**
 * Get comprehensive item state for UI
 */
export const getItemState = (
  item: { is_required: boolean; status: number; selected: boolean },
  parentEnabled: boolean = true
) => {
  // Items can always be toggled regardless of status
  // Status 0 just indicates it's disabled by default, but user can still toggle it
  const isDisabled = false; // Allow all toggles
  
  // Can toggle if not required OR trying to enable
  const canToggle = canDisable(item);
  
  return {
    isDisabled,
    canToggle,
    isRequired: item.is_required,
    isSelected: item.selected,
    statusDisabled: item.status === 0, // Track original status for visual indication
    tooltip: item.status === 0
      ? 'This item is disabled by default but can be enabled'
      : item.is_required && item.selected
      ? 'Required items cannot be manually disabled'
      : undefined
  };
};

// ============================================================================
// INITIALIZATION HELPER
// ============================================================================

/**
 * Initialize hierarchy with proper enabled states and inPackage tracking
 * Backend now provides:
 * - 'inPackage': boolean - whether item exists in pivot table
 * - 'enabled'/'selected': boolean - pivot status (true if status=1)
 * 
 * IMPORTANT: Visual state cascades down from parent
 * - If app is disabled (enabled=false), all modules and features should show as OFF
 * - If module is disabled (selected=false), all features under it should show as OFF
 */
export const initializeHierarchy = (hierarchy: App[]): App[] => {
  return hierarchy.map(app => {
    // Use inPackage from backend if available, fallback to checking enabled
    const appInPackage = app.inPackage === true;
    // App visual state: use backend value (true only if pivot status=1)
    const isAppEnabled = app.enabled === true;
    
    const processedModules = app.modules.map(module => {
      // Use inPackage from backend if available
      const moduleInPackage = module.inPackage === true;
      
      // Module visual state: 
      // - If app is disabled, module must be OFF visually
      // - Otherwise, use module's own pivot status
      const isModuleEnabled = isAppEnabled && (module.selected === true);
      
      const processedFeatures = module.features.map(feature => {
        // Use inPackage from backend if available
        const featureInPackage = feature.inPackage === true;
        
        // Feature visual state:
        // - If app is disabled OR module is disabled, feature must be OFF visually
        // - Otherwise, use feature's own pivot status
        const isFeatureSelected = isAppEnabled && isModuleEnabled && (feature.enabled === true);
        
        return {
          ...feature,
          selected: isFeatureSelected,
          inPackage: featureInPackage
        };
      });

      return {
        ...module,
        selected: isModuleEnabled,
        inPackage: moduleInPackage,
        features: processedFeatures
      };
    });

    return {
      ...app,
      modules: processedModules,
      enabled: isAppEnabled,
      inPackage: appInPackage
    };
  });
};

// ============================================================================
// REACT INTEGRATION EXAMPLE
// ============================================================================

/**
 * Example: How to integrate with your PackageForm component
 * 
 * Replace your existing state and handlers with these implementations
 */

import { useState } from 'react';
import { Button } from '@admin/components/ui/button';
import { Card } from '@admin/components/ui/card';
import { Switch } from '@admin/components/ui/switch';
import { cn } from '@admin/lib/utils';
import { ChevronDown, ChevronRight, Layers, Zap } from 'lucide-react';

// Pricing type enum matching backend
const PricingType = {
  PER_TENANT: 1,
  PER_USER: 2,
} as const;

// ============================================================================
// PACKAGEFORM COMPONENT - STATE INITIALIZATION
// ============================================================================

export function usePackageFormState(pkg?: any) {
  // Initialize hierarchy with proper states
  const [hierarchy, setHierarchy] = useState<App[]>(() => {
    const initialHierarchy = pkg?.hierarchy || [];
    return initializeHierarchy(initialHierarchy);
  });

  // ============================================================================
  // TOGGLE HANDLERS - Use these in your component
  // ============================================================================

  const handleFeatureChange = (featureId: number, selected: boolean) => {
    setHierarchy(prev => toggleFeature(prev, featureId, selected));
  };

  const handleModuleToggle = (appName: string, moduleName: string, enable: boolean) => {
    setHierarchy(prev => toggleModule(prev, appName, moduleName, enable));
  };

  const handleAppToggle = (appName: string, enable: boolean) => {
    setHierarchy(prev => toggleApp(prev, appName, enable));
  };

  return {
    hierarchy,
    setHierarchy,
    handleFeatureChange,
    handleModuleToggle,
    handleAppToggle,
  };
}

// ============================================================================
// UI COMPONENTS WITH PROPER STATE MANAGEMENT
// ============================================================================

/**
 * FeatureItem Component
 * Displays a single feature with toggle and proper state management
 */
export const FeatureItem = ({
  feature,
  onChange,
  pricingType,
  isAppEnabled = true,
  isModuleEnabled = true,
}: {
  feature: Feature;
  onChange: (id: number, selected: boolean) => void;
  pricingType?: number;
  isAppEnabled?: boolean;
  isModuleEnabled?: boolean;
}) => {
  const price = pricingType === PricingType.PER_TENANT 
    ? feature.price_per_tenant 
    : feature.price_per_user;
  
  // Get comprehensive state
  const state = getItemState(feature, isAppEnabled && isModuleEnabled);

  return (
    <div
      className={cn(
        'flex items-center justify-between rounded-lg border bg-white px-3 py-2.5',
        'transition-all hover:shadow-sm',
        state.isSelected && 'border-emerald-200 bg-emerald-50/30',
        state.isRequired && 'border-amber-200 bg-amber-50/20',
        state.isDisabled && 'opacity-50 cursor-not-allowed',
      )}
      title={state.tooltip}
    >
      <div className="flex flex-1 items-center gap-2.5">
        <Zap 
          className={cn(
            'h-3.5 w-3.5 transition-colors',
            state.isSelected ? 'text-emerald-600' : 'text-gray-300'
          )} 
        />
        <span 
          className={cn(
            'text-xs font-medium transition-colors',
            state.isSelected ? 'text-gray-900' : 'text-gray-500'
          )}
        >
          {feature.name}
          {state.isRequired && (
            <span className="ml-1.5 text-[10px] font-bold text-amber-600">
              (Required)
            </span>
          )}
        </span>
      </div>
      <div className="flex items-center gap-3">
        {price > 0 && (
          <span
            className={cn(
              'rounded-md px-2 py-0.5 font-mono text-xs font-semibold transition-colors',
              state.isSelected 
                ? 'bg-emerald-100 text-emerald-700' 
                : 'bg-gray-100 text-gray-600',
            )}
          >
            ${price.toFixed(2)}
          </span>
        )}
        <Switch
          checked={state.isSelected}
          onCheckedChange={(checked) => {
            // Only allow changes if item can be toggled
            if (state.canToggle || checked) {
              onChange(feature.id, checked);
            }
          }}
          className="scale-75"
          disabled={!state.canToggle && !state.isSelected}
        />
      </div>
    </div>
  );
};

/**
 * ModuleCard Component
 * Displays a module with its features
 */
export const ModuleCard = ({
  module,
  onModuleToggle,
  onFeatureChange,
  pricingType,
  isAppEnabled = true,
}: {
  module: Module;
  onModuleToggle: (moduleName: string, enable: boolean) => void;
  onFeatureChange: (featureId: number, selected: boolean) => void;
  pricingType?: number;
  isAppEnabled?: boolean;
}) => {
  const [isExpanded, setIsExpanded] = useState(true);
  
  const selectedCount = module.features.filter(f => f.selected).length;
  // Module is enabled if explicitly selected OR has any selected features
  const isModuleOn = module.selected === true || selectedCount > 0;
  
  // Get comprehensive state
  const state = getItemState(
    { ...module, selected: isModuleOn },
    isAppEnabled
  );

  const handleModuleToggle = (checked: boolean) => {
    if (state.canToggle || checked) {
      onModuleToggle(module.name, checked);
    }
  };

  return (
    <Card 
      className={cn(
        'overflow-hidden border bg-white transition-all hover:shadow-lg',
        state.isRequired && 'border-amber-300',
        state.isDisabled && 'opacity-50'
      )}
      title={state.tooltip}
    >
      <div className={cn(
        'flex items-center justify-between border-b bg-gray-50/50 p-3',
        state.isRequired && 'bg-amber-50/50'
      )}>
        <div className="flex flex-1 items-center gap-2.5">
          <Layers 
            className={cn(
              'h-4 w-4 transition-colors',
              isModuleOn ? 'text-blue-600' : 'text-gray-300'
            )} 
          />
          <h4 className={cn(
            'text-sm font-semibold transition-colors',
            isModuleOn ? 'text-gray-900' : 'text-gray-500'
          )}>
            {module.name}
            {state.isRequired && (
              <span className="ml-1.5 text-[10px] font-bold text-amber-600">
                (Required)
              </span>
            )}
          </h4>
          <span className="text-[10px] text-gray-500">
            ({selectedCount}/{module.features.length})
          </span>
        </div>
        <div className="flex items-center gap-2">
          <Switch
            checked={isModuleOn}
            onCheckedChange={handleModuleToggle}
            className="scale-75"
            disabled={!state.canToggle && !isModuleOn}
          />
          <Button
            variant="ghost"
            size="sm"
            className="h-7 w-7 p-0 hover:bg-gray-100"
            onClick={() => setIsExpanded(!isExpanded)}
          >
            {isExpanded ? (
              <ChevronDown className="h-4 w-4 text-gray-600" />
            ) : (
              <ChevronRight className="h-4 w-4 text-gray-600" />
            )}
          </Button>
        </div>
      </div>

      {/* Features hidden from UI */}
      {/* {isExpanded && (
        <div className="space-y-2 bg-gray-50/30 p-3">
          {module.features.map((feature) => (
            <FeatureItem
              key={feature.id}
              feature={feature}
              onChange={onFeatureChange}
              pricingType={pricingType}
              isAppEnabled={isAppEnabled}
              isModuleEnabled={isModuleOn}
            />
          ))}
        </div>
      )} */}
    </Card>
  );
};

/**
 * AppSection Component
 * Displays an app with its modules
 */
export const AppSection = ({
  app,
  onAppToggle,
  onModuleToggle,
  onFeatureChange,
  pricingType,
}: {
  app: App;
  onAppToggle: (appName: string, enable: boolean) => void;
  onModuleToggle: (appName: string, moduleName: string, enable: boolean) => void;
  onFeatureChange: (featureId: number, selected: boolean) => void;
  pricingType?: number;
}) => {
  const [isExpanded, setIsExpanded] = useState(true);
  
  const totalFeatures = app.modules.reduce((sum, m) => sum + m.features.length, 0);
  const selectedFeatures = app.modules.reduce(
    (sum, m) => sum + m.features.filter(f => f.selected).length,
    0
  );
  
  const isAppEnabled = app.enabled ?? (selectedFeatures > 0);
  
  // Get comprehensive state
  const state = getItemState(
    { ...app, selected: isAppEnabled },
    true // Apps are top-level, always have "parent enabled"
  );

  const handleAppToggle = (checked: boolean) => {
    if (state.canToggle || checked) {
      onAppToggle(app.name, checked);
    }
  };

  return (
    <div
      className={cn(
        'overflow-hidden rounded-xl border-none bg-white shadow-sm transition-all',
        isAppEnabled ? 'border-indigo-300 shadow-indigo-100' : 'border-gray-200',
        state.isRequired && 'border-amber-300',
        state.isDisabled && 'opacity-50',
      )}
      title={state.tooltip}
    >
      <div
        className={cn(
          'flex items-center justify-between border-b border-gray-200',
          'bg-linear-to-r from-gray-50 to-white px-5 py-4',
          state.isRequired && 'bg-amber-50/50',
        )}
      >
        <div className="flex flex-1 items-center gap-3">
          <div
            className={cn(
              'rounded-lg border bg-white p-2 shadow-sm transition-all',
              isAppEnabled ? 'border-indigo-300' : 'border-gray-200',
            )}
          >
            <Layers 
              className={cn(
                'h-5 w-5 transition-colors',
                isAppEnabled ? 'text-indigo-600' : 'text-gray-300'
              )} 
            />
          </div>
          <div>
            <div className="flex items-center gap-2">
              <h3 className={cn(
                'text-base font-bold transition-colors',
                isAppEnabled ? 'text-gray-900' : 'text-gray-500'
              )}>
                {app.name}
                {state.isRequired && (
                  <span className="ml-1.5 text-[10px] font-bold text-amber-600">
                    (Required)
                  </span>
                )}
              </h3>
            </div>
            <p className="text-xs font-medium text-gray-500">
              {selectedFeatures}/{totalFeatures} features selected
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Switch
            checked={isAppEnabled}
            onCheckedChange={handleAppToggle}
            disabled={!state.canToggle && !isAppEnabled}
          />
          <Button
            variant="ghost"
            size="sm"
            onClick={() => setIsExpanded(!isExpanded)}
            className="hover:bg-gray-100"
          >
            {isExpanded ? (
              <ChevronDown className="h-5 w-5 text-gray-600" />
            ) : (
              <ChevronRight className="h-5 w-5 text-gray-600" />
            )}
          </Button>
        </div>
      </div>

      {isExpanded && (
        <div className="grid gap-4 bg-gray-50/30 p-5 sm:grid-cols-2 lg:grid-cols-3">
          {app.modules.map((module, idx) => (
            <ModuleCard
              key={idx}
              module={module}
              onModuleToggle={(moduleName, enable) =>
                onModuleToggle(app.name, moduleName, enable)
              }
              onFeatureChange={onFeatureChange}
              pricingType={pricingType}
              isAppEnabled={isAppEnabled}
            />
          ))}
        </div>
      )}
    </div>
  );
};

// ============================================================================
// USAGE EXAMPLE IN YOUR PACKAGEFORM
// ============================================================================

/**
 * Example implementation in your PackageForm component:
 * 
 * export default function PackageForm({ package: pkg, isEdit = false }: Props) {
 *   // Use the custom hook
 *   const {
 *     hierarchy,
 *     handleFeatureChange,
 *     handleModuleToggle,
 *     handleAppToggle,
 *   } = usePackageFormState(pkg);
 * 
 *   // ... rest of your form state ...
 * 
 *   return (
 *     <Card>
 *       {hierarchy.map((app, idx) => (
 *         <AppSection
 *           key={idx}
 *           app={app}
 *           onAppToggle={handleAppToggle}
 *           onModuleToggle={handleModuleToggle}
 *           onFeatureChange={handleFeatureChange}
 *           pricingType={formData.pricing_type}
 *         />
 *       ))}
 *     </Card>
 *   );
 * }
 */