import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
import { initializePaddle, Paddle } from '@paddle/paddle-js';

type PaddleEventCallback = (event: any) => void;

interface PaddleContextType {
  paddle: Paddle | null;
  isLoading: boolean;
  registerEventCallback: (cb: PaddleEventCallback | null) => void;
}

const PaddleContext = createContext<PaddleContextType>({
  paddle: null,
  isLoading: true,
  registerEventCallback: () => {},
});

export const usePaddle = () => useContext(PaddleContext);

// Singleton guard so StrictMode double-mount doesn't double-init
let paddleSingleton: Paddle | null = null;
let paddleInitializing = false;

export const PaddleProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [paddle, setPaddle] = useState<Paddle | null>(paddleSingleton);
  const [isLoading, setIsLoading] = useState(!paddleSingleton);
  // Store the current callback in a ref so we can call it from the global eventCallback
  const callbackRef = useRef<PaddleEventCallback | null>(null);

  const registerEventCallback = (cb: PaddleEventCallback | null) => {
    console.log('[PaddleProvider] registerEventCallback called, cb is', cb ? 'set' : 'null');
    callbackRef.current = cb;
  };

  useEffect(() => {
    const setupMockPaddle = () => {
      const mockPaddle = {
        Checkout: {
          open: (options: any) => {
            console.log('[MockPaddle] Checkout.open called with options:', options);
            setTimeout(() => {
              const proceed = confirm(`[Mode Simulation] Souhaitez-vous simuler le succès de l'abonnement ?\n\nCliquez sur OK pour simuler le paiement réussi, ou sur Annuler pour simuler l'annulation.`);
              if (proceed) {
                const successEvent = {
                  name: 'checkout.completed',
                  data: {
                    id: 'sim_checkout_' + Math.random().toString(36).substring(7),
                    items: options.items,
                  }
                };
                console.log('[MockPaddle] Dispatching mock checkout.completed');
                if (callbackRef.current) {
                  callbackRef.current(successEvent);
                }
              } else {
                const cancelEvent = {
                  name: 'checkout.closed',
                  data: {}
                };
                console.log('[MockPaddle] Dispatching mock checkout.closed');
                if (callbackRef.current) {
                  callbackRef.current(cancelEvent);
                }
              }
            }, 500);
          }
        },
        Environment: {
          set: () => {}
        },
        Initialize: () => {},
        Update: () => {}
      } as unknown as Paddle;

      paddleSingleton = mockPaddle;
      setPaddle(mockPaddle);
      paddleInitializing = false;
    };

    const init = async () => {
      const clientToken = process.env.NEXT_PUBLIC_PADDLE_CLIENT_TOKEN || '';

      if (!clientToken) {
        console.warn('[PaddleProvider] No Paddle client token specified. Falling back to checkout simulator.');
        setupMockPaddle();
        setIsLoading(false);
        return;
      }

      try {
        console.log('[PaddleProvider] Initializing Paddle...');
        const paddleInstance = await initializePaddle({
          environment: (process.env.NEXT_PUBLIC_PADDLE_ENVIRONMENT as 'sandbox' | 'production') || 'sandbox',
          token: clientToken,
          eventCallback: function(event) {
            console.log('[PaddleProvider] Paddle event received:', event.name, event.data);
            if (callbackRef.current) {
              callbackRef.current(event);
            } else {
              console.warn('[PaddleProvider] No event callback registered, event ignored:', event.name);
            }
          }
        });

        if (paddleInstance) {
          paddleSingleton = paddleInstance;
          setPaddle(paddleInstance);
          console.log('[PaddleProvider] Paddle initialized successfully');
        }
      } catch (error) {
        console.warn('[PaddleProvider] Failed to load or initialize Paddle. Falling back to checkout simulator. Error:', error);
        setupMockPaddle();
      } finally {
        setIsLoading(false);
      }
    };

    init();
  }, []);

  return (
    <PaddleContext.Provider value={{ paddle, isLoading, registerEventCallback }}>
      {children}
    </PaddleContext.Provider>
  );
};
