/**
 * React Integration fuer @breakpilot/consent-sdk
 *
 * @example
 * ```tsx
 * import { ConsentProvider, useConsent, ConsentBanner } from '@breakpilot/consent-sdk/react';
 *
 * function App() {
 *   return (
 *     <ConsentProvider config={config}>
 *       <ConsentBanner />
 *       <MainContent />
 *     </ConsentProvider>
 *   );
 * }
 * ```
 *
 * Phase 4 refactor: provider stays here; hooks + components live in sibling
 * files. Context definition is in ./context so hooks and provider can share it
 * without circular imports.
 */

import {
  useEffect,
  useState,
  useCallback,
  useMemo,
  type FC,
  type ReactNode,
} from 'react';
import { ConsentManager } from '../core/ConsentManager';
import type {
  ConsentCategories,
  ConsentCategory,
  ConsentConfig,
  ConsentState,
} from '../types';
import { ConsentContext, type ConsentContextValue } from './context';
import { useConsent, useConsentManager } from './hooks';
import {
  ConsentBanner,
  ConsentGate,
  ConsentPlaceholder,
  type ConsentBannerRenderProps,
} from './components';

// =============================================================================
// Provider
// =============================================================================

interface ConsentProviderProps {
  /** SDK-Konfiguration */
  config: ConsentConfig;
  /** Kinder-Komponenten */
  children: ReactNode;
}

/**
 * ConsentProvider - Stellt Consent-Kontext bereit.
 */
export const ConsentProvider: FC<ConsentProviderProps> = ({
  config,
  children,
}) => {
  const [manager, setManager] = useState<ConsentManager | null>(null);
  const [consent, setConsent] = useState<ConsentState | null>(null);
  const [isInitialized, setIsInitialized] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [isBannerVisible, setIsBannerVisible] = useState(false);

  // Manager erstellen und initialisieren
  useEffect(() => {
    const consentManager = new ConsentManager(config);
    setManager(consentManager);

    // Events abonnieren
    const unsubChange = consentManager.on('change', (newConsent) => {
      setConsent(newConsent);
    });

    const unsubBannerShow = consentManager.on('banner_show', () => {
      setIsBannerVisible(true);
    });

    const unsubBannerHide = consentManager.on('banner_hide', () => {
      setIsBannerVisible(false);
    });

    // Initialisieren
    consentManager
      .init()
      .then(() => {
        setConsent(consentManager.getConsent());
        setIsInitialized(true);
        setIsLoading(false);
        setIsBannerVisible(consentManager.isBannerVisible());
      })
      .catch((error) => {
        console.error('Failed to initialize ConsentManager:', error);
        setIsLoading(false);
      });

    // Cleanup
    return () => {
      unsubChange();
      unsubBannerShow();
      unsubBannerHide();
    };
  }, [config]);

  // Callback-Funktionen
  const hasConsent = useCallback(
    (category: ConsentCategory): boolean => {
      return manager?.hasConsent(category) ?? category === 'essential';
    },
    [manager]
  );

  const acceptAll = useCallback(async () => {
    await manager?.acceptAll();
  }, [manager]);

  const rejectAll = useCallback(async () => {
    await manager?.rejectAll();
  }, [manager]);

  const saveSelection = useCallback(
    async (categories: Partial<ConsentCategories>) => {
      await manager?.setConsent(categories);
      manager?.hideBanner();
    },
    [manager]
  );

  const showBanner = useCallback(() => {
    manager?.showBanner();
  }, [manager]);

  const hideBanner = useCallback(() => {
    manager?.hideBanner();
  }, [manager]);

  const showSettings = useCallback(() => {
    manager?.showSettings();
  }, [manager]);

  const needsConsent = useMemo(() => {
    return manager?.needsConsent() ?? true;
  }, [manager, consent]);

  // Context-Wert
  const contextValue = useMemo<ConsentContextValue>(
    () => ({
      manager,
      consent,
      isInitialized,
      isLoading,
      isBannerVisible,
      needsConsent,
      hasConsent,
      acceptAll,
      rejectAll,
      saveSelection,
      showBanner,
      hideBanner,
      showSettings,
    }),
    [
      manager,
      consent,
      isInitialized,
      isLoading,
      isBannerVisible,
      needsConsent,
      hasConsent,
      acceptAll,
      rejectAll,
      saveSelection,
      showBanner,
      hideBanner,
      showSettings,
    ]
  );

  return (
    <ConsentContext.Provider value={contextValue}>
      {children}
    </ConsentContext.Provider>
  );
};

// =============================================================================
// Re-exports for the public @breakpilot/consent-sdk/react entrypoint
// =============================================================================

export { useConsent, useConsentManager };
export { ConsentBanner, ConsentGate, ConsentPlaceholder };
export { ConsentContext };
export type { ConsentContextValue, ConsentBannerRenderProps };
