import React, { createContext, useContext, useEffect, useState } from 'react';
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import config from '../config';
import apiClient from '@services/api';
import { useAuth } from '@hooks/reduxHooks';

// Create the context
const StripeContext = createContext();

export const StripeProvider = ({ children }) => {
  const [stripePromise, setStripePromise] = useState(null);
  const [clientSecret, setClientSecret] = useState('');
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const { isAuthenticated } = useAuth();

  // Load or reload Stripe configuration when authentication state changes
  useEffect(() => {
    // Reset state when auth changes
    setIsLoading(true);
    setError(null);
    
    // Try to load Stripe public key from environment
    let publicKey = import.meta.env.VITE_STRIPE_PUBLIC_KEY;
    
    // If not found, fetch from API
    if (isAuthenticated) {
      // Fetch Stripe public key from backend
      apiClient.get('/payment/config')
        .then(response => {
          if (response.data.stripePublicKey) {
            loadStripeInstance(response.data.stripePublicKey);
          } else {
            setError('Stripe public key not found');
            setIsLoading(false);
          }
        })
        .catch(err => {
          console.error('Error fetching Stripe config:', err);
          setError('Failed to load payment configuration');
          setIsLoading(false);
        });
    } else if(publicKey){
      loadStripeInstance(publicKey);
    }
  }, [isAuthenticated]); // Add isAuthenticated as a dependency to reload on auth changes

  const loadStripeInstance = (publicKey) => {
    try {
      const stripe = loadStripe(publicKey);
      setStripePromise(stripe);
      setIsLoading(false);
    } catch (err) {
      console.error('Error loading Stripe:', err);
      setError('Failed to initialize payment system');
      setIsLoading(false);
    }
  };

  // Create a checkout session
  const createCheckoutSession = async (cartItems, orderId, shippingAddress, userId, shippingDetails = null) => {
    try {
      const response = await apiClient.post('/payment/create-checkout-session', {
        cartItems,
        orderId,
        shippingAddress,
        userId,
        shippingDetails
      });
      
      return response.data;
    } catch (err) {
      console.error('Error creating checkout session:', err);
      throw new Error(err.response?.data?.message || 'Failed to create checkout session');
    }
  };

  // Check session status
  const checkSessionStatus = async (sessionId) => {
    try {
      const response = await apiClient.get(`/payment/session-status/${sessionId}`);
      return response.data;
    } catch (err) {
      console.error('Error checking session status:', err);
      throw new Error(err.response?.data?.message || 'Failed to check payment status');
    }
  };

  // Complete the order after successful payment
  const completeOrder = async (orderId, sessionId, userId) => {
    try {
      const response = await apiClient.post('/cart/complete-checkout', {
        orderId,
        sessionId,
        userId
      });
      return response.data;
    } catch (err) {
      console.error('Error completing order:', err);
      throw new Error(err.response?.data?.message || 'Failed to complete order');
    }
  };

  const value = {
    stripePromise,
    clientSecret,
    isLoading,
    error,
    createCheckoutSession,
    checkSessionStatus,
    completeOrder,
    reloadConfig: () => {
      setIsLoading(true);
      setError(null);
      if (isAuthenticated){
        apiClient.get('/payment/config')
          .then(response => {
            if (response.data.stripePublicKey) {
              loadStripeInstance(response.data.stripePublicKey);
            } else {
              setError('Stripe public key not found');
              setIsLoading(false);
            }
          })
          .catch(err => {
            console.error('Error fetching Stripe config:', err);
            setError('Failed to load payment configuration');
            setIsLoading(false);
          });
      }
    }
  };

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

export const useStripe = () => {
  const context = useContext(StripeContext);
  if (!context) {
    throw new Error('useStripe must be used within a StripeProvider');
  }
  return context;
};

// Wrapper component for Elements
export const StripeElementsProvider = ({ children, clientSecret }) => {
  const { stripePromise } = useStripe();
  
  const options = {
    clientSecret,
    appearance: {
      theme: 'stripe',
      variables: {
        colorPrimary: '#6200ea',
        colorBackground: '#ffffff',
        colorText: '#30313d',
        colorDanger: '#df1b41',
        fontFamily: 'Roboto, sans-serif',
        spacingUnit: '4px',
        borderRadius: '4px'
      }
    }
  };

  if (!clientSecret) {
    return children;
  }

  return (
    <Elements stripe={stripePromise} options={options}>
      {children}
    </Elements>
  );
};