/**
 * Vue composables: useConsent + provideConsent.
 *
 * Phase 4: extracted from vue/index.ts.
 */

import {
  computed,
  inject,
  onMounted,
  onUnmounted,
  provide,
  readonly,
  ref,
  type Ref,
} from 'vue';
import { ConsentManager } from '../core/ConsentManager';
import type {
  ConsentCategories,
  ConsentCategory,
  ConsentConfig,
  ConsentState,
} from '../types';
import { CONSENT_KEY, type ConsentContext } from './context';

/**
 * Haupt-Composable fuer Consent-Zugriff.
 */
export function useConsent(): ConsentContext {
  const context = inject(CONSENT_KEY);
  if (!context) {
    throw new Error(
      'useConsent() must be used within a component that has called provideConsent() or is wrapped in ConsentProvider'
    );
  }
  return context;
}

/**
 * Consent-Provider einrichten (in App.vue aufrufen).
 */
export function provideConsent(config: ConsentConfig): ConsentContext {
  const manager = ref<ConsentManager | null>(null);
  const consent = ref<ConsentState | null>(null);
  const isInitialized = ref(false);
  const isLoading = ref(true);
  const isBannerVisible = ref(false);

  const needsConsent = computed(() => {
    return manager.value?.needsConsent() ?? true;
  });

  onMounted(async () => {
    const consentManager = new ConsentManager(config);
    manager.value = consentManager;

    const unsubChange = consentManager.on('change', (newConsent) => {
      consent.value = newConsent;
    });
    const unsubBannerShow = consentManager.on('banner_show', () => {
      isBannerVisible.value = true;
    });
    const unsubBannerHide = consentManager.on('banner_hide', () => {
      isBannerVisible.value = false;
    });

    try {
      await consentManager.init();
      consent.value = consentManager.getConsent();
      isInitialized.value = true;
      isBannerVisible.value = consentManager.isBannerVisible();
    } catch (error) {
      console.error('Failed to initialize ConsentManager:', error);
    } finally {
      isLoading.value = false;
    }

    onUnmounted(() => {
      unsubChange();
      unsubBannerShow();
      unsubBannerHide();
    });
  });

  const hasConsent = (category: ConsentCategory): boolean => {
    return manager.value?.hasConsent(category) ?? category === 'essential';
  };

  const acceptAll = async (): Promise<void> => {
    await manager.value?.acceptAll();
  };

  const rejectAll = async (): Promise<void> => {
    await manager.value?.rejectAll();
  };

  const saveSelection = async (
    categories: Partial<ConsentCategories>
  ): Promise<void> => {
    await manager.value?.setConsent(categories);
    manager.value?.hideBanner();
  };

  const showBanner = (): void => {
    manager.value?.showBanner();
  };

  const hideBanner = (): void => {
    manager.value?.hideBanner();
  };

  const showSettings = (): void => {
    manager.value?.showSettings();
  };

  const context: ConsentContext = {
    manager: readonly(manager) as Ref<ConsentManager | null>,
    consent: readonly(consent) as Ref<ConsentState | null>,
    isInitialized: readonly(isInitialized),
    isLoading: readonly(isLoading),
    isBannerVisible: readonly(isBannerVisible),
    needsConsent,
    hasConsent,
    acceptAll,
    rejectAll,
    saveSelection,
    showBanner,
    hideBanner,
    showSettings,
  };

  provide(CONSENT_KEY, context);

  return context;
}
