/**
 * [PLUGIN-003] 功能模块 React Hook
 * 
 * 提供 React 组件中访问功能注册表的能力:
 * - 检查功能是否启用
 * - 获取功能设置
 * - 条件渲染
 * 
 * @module plugins/useFeature
 * @created 2026-03-21
 */

import { useState, useEffect, useCallback, useMemo } from '@/imports';
import { featureRegistry } from './FeatureRegistry';
import type { FeatureConfig, FeatureState, FeatureSetting } from './FeatureTypes';

export interface UseFeatureResult {
  isEnabled: boolean;
  isLoading: boolean;
  feature?: FeatureConfig;
  state?: FeatureState;
  settings: Record<string, any>;
  enable: () => Promise<boolean>;
  disable: () => Promise<boolean>;
  updateSettings: (settings: Record<string, any>) => void;
}

export function useFeature(featureId: string): UseFeatureResult {
  const [state, setState] = useState<{
    isLoading: boolean;
    feature?: FeatureConfig;
    featureState?: FeatureState;
  }>({
    isLoading: true,
  });

  useEffect(() => {
    const feature = featureRegistry.getFeature(featureId);
    const featureState = featureRegistry.getFeatureState(featureId);

    setState({
      isLoading: false,
      feature,
      featureState,
    });

    const handleFeatureChange = () => {
      setState(prev => ({
        ...prev,
        featureState: featureRegistry.getFeatureState(featureId),
      }));
    };

    featureRegistry.on('feature:enabled', handleFeatureChange);
    featureRegistry.on('feature:disabled', handleFeatureChange);
    featureRegistry.on('feature:settings_changed', handleFeatureChange);

    return () => {
      featureRegistry.off('feature:enabled', handleFeatureChange);
      featureRegistry.off('feature:disabled', handleFeatureChange);
      featureRegistry.off('feature:settings_changed', handleFeatureChange);
    };
  }, [featureId]);

  const enable = useCallback(async () => {
    return featureRegistry.enableFeature(featureId);
  }, [featureId]);

  const disable = useCallback(async () => {
    return featureRegistry.disableFeature(featureId);
  }, [featureId]);

  const updateSettings = useCallback((settings: Record<string, any>) => {
    featureRegistry.updateSettings(featureId, settings);
  }, [featureId]);

  return {
    isEnabled: state.featureState?.enabled ?? false,
    isLoading: state.isLoading,
    feature: state.feature,
    state: state.featureState,
    settings: state.featureState?.settings ?? {},
    enable,
    disable,
    updateSettings,
  };
}

export interface UseFeaturesResult {
  features: FeatureConfig[];
  enabledFeatures: FeatureConfig[];
  isLoading: boolean;
  refresh: () => void;
}

export function useFeatures(category?: string): UseFeaturesResult {
  const [features, setFeatures] = useState<FeatureConfig[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  const refresh = useCallback(() => {
    setIsLoading(true);
    const allFeatures = category
      ? featureRegistry.getFeaturesByCategory(category as any)
      : featureRegistry.getAllFeatures();
    setFeatures(allFeatures);
    setIsLoading(false);
  }, [category]);

  useEffect(() => {
    refresh();

    const handleChange = () => refresh();
    featureRegistry.on('feature:registered', handleChange);
    featureRegistry.on('feature:unregistered', handleChange);
    featureRegistry.on('feature:enabled', handleChange);
    featureRegistry.on('feature:disabled', handleChange);

    return () => {
      featureRegistry.off('feature:registered', handleChange);
      featureRegistry.off('feature:unregistered', handleChange);
      featureRegistry.off('feature:enabled', handleChange);
      featureRegistry.off('feature:disabled', handleChange);
    };
  }, [refresh]);

  const enabledFeatures = useMemo(
    () => features.filter(f => featureRegistry.isFeatureEnabled(f.id)),
    [features]
  );

  return { features, enabledFeatures, isLoading, refresh };
}

export interface FeatureGateProps {
  featureId: string;
  fallback?: React.ReactNode;
  children: React.ReactNode;
  loading?: React.ReactNode;
}

export const FeatureGate: React.FC<FeatureGateProps> = ({
  featureId,
  fallback = null,
  children,
  loading = null,
}) => {
  const { isEnabled, isLoading } = useFeature(featureId);

  if (isLoading) {
    return <>{loading}</>;
  }

  if (!isEnabled) {
    return <>{fallback}</>;
  }

  return <>{children}</>;
};

export interface FeatureSettingsProps {
  featureId: string;
  render: (settings: Record<string, any>, schema: FeatureSetting[]) => React.ReactNode;
}

export const FeatureSettings: React.FC<FeatureSettingsProps> = ({ featureId, render }) => {
  const { feature, settings, updateSettings } = useFeature(featureId);

  if (!feature?.settings) {
    return null;
  }

  return <>{render(settings, feature.settings)}</>;
};
