import React, { useState, useRef, useCallback, useMemo } from 'react';
import {
  View,
  Text,
  StyleSheet,
  Alert,
  ActivityIndicator,
  TouchableOpacity,
  SafeAreaView,
} from 'react-native';
import { WebView } from 'react-native-webview';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { useTheme } from '@/shared/styles/useTheme';
import { useNavigation } from '@react-navigation/native';
import { manageToken } from '../services/integrationAPI';
import { useSelector } from 'react-redux';
import { RootState } from '@/store/store';
import http from '@/services/http';

// Types
interface SalesforceAuthProps {
  onAuthSuccess?: (authData: SalesforceAuthData) => void;
  onAuthError?: (error: string) => void;
  onClose?: () => void;
}

interface SalesforceAuthData {
  accessToken: string;
  refreshToken?: string;
  instanceUrl?: string;
  id?: string;
  issuedAt?: string;
  signature?: string;
  tokenType?: string;
}

interface SalesforceAuthState {
  loading: boolean;
  error: string | null;
  currentUrl: string;
  processing: boolean;
  processingStep: string;
}

// Salesforce OAuth Configuration
const SALESFORCE_CONFIG = {
  // Replace with your actual Salesforce Connected App credentials
  CLIENT_ID: '3MVG9GBhY6wQjl2sueQtv2NXMm3EuWtEvOQoeKRAzYcgs2.AWhkCPFitVFPYyUkiLRRdIww2fpr48_Inokd3F',
  // Backend callback URL that will handle the OAuth callback
  BACKEND_BASE_URL: http.getBaseURL,
  CALLBACK_PATH: '/api/v1/users/oauth/callback',
  // Use login.salesforce.com for production, test.salesforce.com for sandbox
  AUTH_BASE_URL: 'https://login.salesforce.com',
  RESPONSE_TYPE: 'code',
  DISPLAY: 'touch', // Optimized for mobile
};

// Salesforce OAuth scopes - request access to various Salesforce APIs
const SALESFORCE_SCOPES = [
  'api', // Access to REST API
  'refresh_token', // Ability to use refresh token
  'offline_access', // Perform requests at any time
  // 'id', // Access to unique identifier
  'profile', // Access to profile information
  'email', // Access to email address
  'address', // Access to address information
  'phone', // Access to phone number
  // 'openid', // OpenID Connect
].join(' ');

// Build Salesforce OAuth URL with user-specific callback
const buildSalesforceAuthUrl = (userUuid: string): string => {
  const baseUrl = `${SALESFORCE_CONFIG.AUTH_BASE_URL}/services/oauth2/authorize`;
  
  // Build the redirect URI with query parameters that backend expects
  const redirectUri = `${SALESFORCE_CONFIG.BACKEND_BASE_URL}${SALESFORCE_CONFIG.CALLBACK_PATH}?user_uuid=${encodeURIComponent(userUuid)}&service_name=salesforce`;
  
  const params = new URLSearchParams({
    client_id: SALESFORCE_CONFIG.CLIENT_ID,
    redirect_uri: redirectUri,
    response_type: SALESFORCE_CONFIG.RESPONSE_TYPE,
    display: SALESFORCE_CONFIG.DISPLAY,
    scope: SALESFORCE_SCOPES,
    // Add state parameter for security (CSRF protection)
    state: Math.random().toString(36).substring(7),
  });
  
  console.log('[SalesforceAuth] Built OAuth URL:', `${baseUrl}?${params.toString()}`);
  console.log('[SalesforceAuth] Redirect URI:', redirectUri);
  return `${baseUrl}?${params.toString()}`;
};

// Safe query param parser for React Native
const getQueryParamFromUrl = (url: string, key: string): string | null => {
  try {
    const queryIndex = url.indexOf('?');
    if (queryIndex === -1) return null;
    const query = url.substring(queryIndex + 1);
    const pairs = query.split('&');
    for (let i = 0; i < pairs.length; i += 1) {
      const [rawK, rawV] = pairs[i].split('=');
      const k = decodeURIComponent(rawK || '');
      if (k === key) {
        return decodeURIComponent(rawV || '');
      }
    }
    return null;
  } catch (e) {
    return null;
  }
};

// Parse all query params from URL into a plain object
const getAllQueryParamsFromUrl = (url: string): Record<string, any> => {
  const result: Record<string, any> = {};
  try {
    const queryIndex = url.indexOf('?');
    if (queryIndex === -1) return result;
    const query = url.substring(queryIndex + 1);
    const pairs = query.split('&');
    for (let i = 0; i < pairs.length; i += 1) {
      const [rawK, rawV] = pairs[i].split('=');
      const k = decodeURIComponent(rawK || '');
      const v = decodeURIComponent(rawV || '');
      if (!k) continue;
      // Coerce numeric values when appropriate
      const numeric = /^-?\d+$/.test(v) ? Number(v) : v;
      result[k] = numeric;
    }
  } catch (e) {
    // swallow errors, return best-effort result
  }
  return result;
};

// Extract authorization code from URL
const extractAuthCode = (url: string): string | null => {
  return getQueryParamFromUrl(url, 'code');
};

// Check if URL is the backend callback URI
const isBackendCallbackUri = (url: string): boolean => {
  return url.includes(SALESFORCE_CONFIG.CALLBACK_PATH);
};

// Check if backend callback indicates success
const isCallbackSuccess = (url: string): boolean => {
  const status = getQueryParamFromUrl(url, 'status');
  const success = getQueryParamFromUrl(url, 'success');
  return status === 'success' || success === 'true';
};

// Check if backend callback indicates error
const isCallbackError = (url: string): boolean => {
  const status = getQueryParamFromUrl(url, 'status');
  const error = getQueryParamFromUrl(url, 'error');
  return status === 'error' || status === 'failure' || !!error;
};

const SalesforceAuth: React.FC<SalesforceAuthProps> = ({
  onAuthSuccess,
  onAuthError,
  onClose,
}) => {
  const { colors, spacing, fonts, shadows } = useTheme();
  const webViewRef = useRef<WebView>(null);
  const navigation = useNavigation<any>();
  const { user, accessToken } = useSelector((state: RootState) => state.auth);
  
  const [state, setState] = useState<SalesforceAuthState>({
    loading: true,
    error: null,
    currentUrl: buildSalesforceAuthUrl(user?.uuid || ''),
    processing: false,
    processingStep: '',
  });

  // Handle authorization code from callback URL
  const handleAuthorizationCode = useCallback(async (authCode: string) => {
    console.log('[SalesforceAuth] Authorization code captured:', authCode);
    console.log('[SalesforceAuth] Manually hitting callback URL with query params');
    
    // Show processing modal
    setState(prev => ({ 
      ...prev, 
      processing: true, 
      processingStep: 'Connecting to Salesforce and storing credentials...' 
    }));
    
    try {
      // Manually hit the callback URL endpoint with query parameters
      // This mimics what Salesforce would have sent directly to the backend
      const response = await http.get('/api/v1/users/oauth/callback', {
        authorization_code: authCode,
        user_uuid: user?.uuid || '',
        service_name: 'salesforce'
      });
      
      console.log('[SalesforceAuth] Response from callback endpoint:', response);
      
      // Check if response status is success
      if (response?.data && typeof response.data === 'object' && 'status' in response.data && response.data.status === 'success') {
        console.log('[SalesforceAuth] Token exchange successful');
        
        // Update processing step
        setState(prev => ({ 
          ...prev, 
          processingStep: 'Salesforce authentication successful!' 
        }));
        
        // Wait a moment to show success message
        await new Promise<void>(resolve => setTimeout(resolve, 1500));
        
        // Hide processing modal and call success callback
        setState(prev => ({ ...prev, processing: false, processingStep: '' }));
        
        // Call success callback
        onAuthSuccess?.({
          accessToken: authCode,
          tokenType: 'authorization_code',
        });
      } else {
        const errorMessage = response?.data && typeof response.data === 'object' && 'message' in response.data 
          ? String(response.data.message)
          : 'Failed to authenticate with Salesforce';
        console.warn('[SalesforceAuth] Token exchange failed:', errorMessage);
        throw new Error(errorMessage);
      }
    } catch (error) {
      console.error('[SalesforceAuth] Error during token exchange:', error);
      
      // Hide processing modal
      setState(prev => ({ ...prev, processing: false, processingStep: '' }));
      
      // Call error callback
      const errorMessage = error instanceof Error ? error.message : 'Authentication failed';
      onAuthError?.(errorMessage);
      
      // Show error alert
      Alert.alert(
        'Authentication Error',
        errorMessage,
        [
          {
            text: 'Retry',
            onPress: () => {
              setState(prev => ({ 
                ...prev, 
                error: null, 
                currentUrl: buildSalesforceAuthUrl(user?.uuid || '') 
              }));
              webViewRef.current?.reload();
            },
          },
          {
            text: 'Cancel',
            onPress: onClose,
            style: 'cancel',
          },
        ]
      );
    }
  }, [onAuthSuccess, onAuthError, onClose, user?.uuid]);

  // Handle backend callback error
  const handleBackendError = useCallback((url: string) => {
    const errorMessage = getQueryParamFromUrl(url, 'message') || 
                        getQueryParamFromUrl(url, 'error_description') || 
                        'Failed to authenticate with Salesforce';
    
    console.error('[SalesforceAuth] Backend callback error:', errorMessage);
    
    // Hide processing modal
    setState(prev => ({ 
      ...prev, 
      processing: false, 
      processingStep: '',
      error: errorMessage 
    }));
    
    // Call error callback
    onAuthError?.(errorMessage);
    
    // Show error alert
    Alert.alert(
      'Authentication Error',
      errorMessage,
      [
        {
          text: 'Retry',
          onPress: () => {
            setState(prev => ({ 
              ...prev, 
              error: null, 
              currentUrl: buildSalesforceAuthUrl(user?.uuid || '') 
            }));
            webViewRef.current?.reload();
          },
        },
        {
          text: 'Cancel',
          onPress: onClose,
          style: 'cancel',
        },
      ]
    );
  }, [onAuthError, onClose, user?.uuid]);

  // Handle WebView navigation state changes
  const handleNavigationStateChange = useCallback((navState: any) => {
    const { url, loading } = navState;
    console.log('[SalesforceAuth] nav change url:', url, 'loading:', loading);
    
    setState(prev => ({
      ...prev,
      loading,
      currentUrl: url,
    }));

    // Check if this is the backend callback URL (after Salesforce redirects)
    if (isBackendCallbackUri(url)) {
      console.log('[SalesforceAuth] Backend callback detected');
      
      // Extract authorization code from the URL
      const authCode = extractAuthCode(url);
      console.log('[SalesforceAuth] Authorization code in URL:', authCode);
      
      // If we have an authorization code, capture it and send to backend
      if (authCode && !state.processing) {
        console.log('[SalesforceAuth] Capturing authorization code and sending to backend');
        handleAuthorizationCode(authCode);
        return;
      }
      
      // Check for success or error status (if backend already processed and redirected)
      if (isCallbackSuccess(url)) {
        console.log('[SalesforceAuth] Backend callback indicates success (already processed)');
        // Just close the modal - backend already handled everything
        setState(prev => ({ ...prev, processing: false }));
        onAuthSuccess?.({
          accessToken: 'token_exchanged_by_backend',
          tokenType: 'Bearer',
        });
        return;
      }
      
      if (isCallbackError(url)) {
        console.log('[SalesforceAuth] Backend callback indicates error');
        handleBackendError(url);
        return;
      }
      
      // If no code and no status, show processing
      if (!state.processing) {
        setState(prev => ({ 
          ...prev, 
          processing: true, 
          processingStep: 'Processing Salesforce authentication...' 
        }));
      }
      return;
    }

    // Handle Salesforce OAuth errors (before redirect to backend)
    const oauthError = getQueryParamFromUrl(url, 'error');
    if (oauthError) {
      const errorDescription = getQueryParamFromUrl(url, 'error_description') || oauthError;
      console.error('[SalesforceAuth] OAuth error:', errorDescription);
      handleAuthError(errorDescription);
      return;
    }
  }, [state.processing, handleAuthorizationCode, handleBackendError, onAuthSuccess]);

  // Allow WebView to load all URLs (backend callback is HTTP, not custom scheme)
  const handleShouldStartLoadWithRequest = useCallback((request: any) => {
    const { url } = request || {};
    if (!url) return true;
    
    // Log for debugging
    console.log('[SalesforceAuth] onShouldStart load:', url);
    
    // Allow all HTTP/HTTPS URLs (backend callback will be handled in handleNavigationStateChange)
    return true;
  }, []);

  // Handle authentication error
  const handleAuthError = useCallback((error: string) => {
    setState(prev => ({ ...prev, error, loading: false }));
    onAuthError?.(error);
    
    Alert.alert(
      'Salesforce Authentication Error',
      error,
      [
        {
          text: 'Retry',
          onPress: () => {
            setState(prev => ({ 
              ...prev, 
              error: null, 
              currentUrl: buildSalesforceAuthUrl(user?.uuid || '') 
            }));
            webViewRef.current?.reload();
          },
        },
        {
          text: 'Cancel',
          onPress: onClose,
          style: 'cancel',
        },
      ]
    );
  }, [onAuthError, onClose, user?.uuid]);

  // Handle WebView error
  const handleWebViewError = useCallback((syntheticEvent: any) => {
    const { nativeEvent } = syntheticEvent;
    console.error('WebView error:', nativeEvent);
    handleAuthError('Failed to load Salesforce login page. Please check your internet connection.');
  }, [handleAuthError]);

  const handleLoadStart = useCallback((e: any) => {
    console.log('[SalesforceAuth] load start:', e?.nativeEvent?.url);
  }, []);

  const handleLoadEnd = useCallback((e: any) => {
    console.log('[SalesforceAuth] load end:', e?.nativeEvent?.url);
  }, []);

  // Handle close button press
  const handleClose = useCallback(() => {
    onClose?.();
  }, [onClose]);

  // Handle reload
  const handleReload = useCallback(() => {
    setState(prev => ({ 
      ...prev, 
      error: null, 
      currentUrl: buildSalesforceAuthUrl(user?.uuid || '') 
    }));
    webViewRef.current?.reload();
  }, [user?.uuid]);

  return (
    <SafeAreaView style={[styles.container, { backgroundColor: colors.background }]}>
      {/* Header */}
      <View style={[styles.header, { backgroundColor: colors.surface, ...shadows.light }]}>
        <View style={styles.headerContent}>
          <Icon name="cloud" size={24} color="#00A1E0" />
          <Text style={[styles.headerTitle, { color: colors.text, fontFamily: fonts.medium }]}>
            Salesforce Authentication
          </Text>
        </View>
        
        <TouchableOpacity
          style={[styles.closeButton, { backgroundColor: colors.background }]}
          onPress={handleClose}
          activeOpacity={0.7}
        >
          <Icon name="close" size={20} color={colors.text} />
        </TouchableOpacity>
      </View>

      {/* Error State */}
      {state.error && (
        <View style={[styles.errorContainer, { backgroundColor: colors.surface }]}>
          <Icon name="error-outline" size={48} color={colors.error} />
          <Text style={[styles.errorTitle, { color: colors.text, fontFamily: fonts.medium }]}>
            Authentication Failed
          </Text>
          <Text style={[styles.errorMessage, { color: colors.textLight, fontFamily: fonts.regular }]}>
            {state.error}
          </Text>
          <TouchableOpacity
            style={[styles.retryButton, { backgroundColor: '#00A1E0' }]}
            onPress={handleReload}
            activeOpacity={0.8}
          >
            <Text style={[styles.retryButtonText, { color: colors.surface, fontFamily: fonts.medium }]}>
              Try Again
            </Text>
          </TouchableOpacity>
        </View>
      )}

      {/* Processing Modal */}
      {state.processing && (
        <View style={[styles.processingOverlay, { backgroundColor: 'rgba(0, 0, 0, 0.7)' }]}>
          <View style={[styles.processingModal, { backgroundColor: colors.surface }]}>
            <View style={styles.processingIconContainer}>
              <ActivityIndicator size="large" color="#00A1E0" />
            </View>
            <Text style={[styles.processingTitle, { color: colors.text, fontFamily: fonts.bold }]}>
              Setting Up Salesforce
            </Text>
            <Text style={[styles.processingStep, { color: colors.textLight, fontFamily: fonts.regular }]}>
              {state.processingStep}
            </Text>
            <View style={styles.processingDots}>
              <View style={[styles.dot, { backgroundColor: '#00A1E0' }]} />
              <View style={[styles.dot, { backgroundColor: '#00A1E0' }]} />
              <View style={[styles.dot, { backgroundColor: '#00A1E0' }]} />
            </View>
          </View>
        </View>
      )}

      {/* Loading Overlay */}
      {state.loading && !state.error && (
        <View style={[styles.loadingOverlay, { backgroundColor: colors.background }]}>
          <ActivityIndicator size="large" color="#00A1E0" />
          <Text style={[styles.loadingText, { color: colors.textLight, fontFamily: fonts.regular }]}>
            Loading Salesforce Login...
          </Text>
        </View>
      )}

      {/* WebView */}
      {!state.error && !state.processing && (
        <WebView
          ref={webViewRef}
          source={{ uri: state.currentUrl }}
          style={styles.webView}
          onNavigationStateChange={handleNavigationStateChange}
          onLoadStart={handleLoadStart}
          onLoadEnd={handleLoadEnd}
          onError={handleWebViewError}
          onHttpError={handleWebViewError}
          startInLoadingState={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          sharedCookiesEnabled={true}
          thirdPartyCookiesEnabled={true}
          mixedContentMode="compatibility"
          originWhitelist={["*"]}
          allowsInlineMediaPlayback={true}
          mediaPlaybackRequiresUserAction={false}
          onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
          setSupportMultipleWindows={false}
          javaScriptCanOpenWindowsAutomatically={true}
          renderLoading={() => (
            <View style={[styles.webViewLoading, { backgroundColor: colors.background }]}>
              <ActivityIndicator size="large" color="#00A1E0" />
              <Text style={[styles.webViewLoadingText, { color: colors.textLight, fontFamily: fonts.regular }]}>
                Loading...
              </Text>
            </View>
          )}
        />
      )}
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#E2E8F0',
  },
  headerContent: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  headerTitle: {
    fontSize: 18,
    marginLeft: 8,
  },
  closeButton: {
    width: 32,
    height: 32,
    borderRadius: 16,
    justifyContent: 'center',
    alignItems: 'center',
  },
  errorContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 32,
  },
  errorTitle: {
    fontSize: 20,
    marginTop: 16,
    marginBottom: 8,
  },
  errorMessage: {
    fontSize: 14,
    textAlign: 'center',
    lineHeight: 20,
    marginBottom: 24,
  },
  retryButton: {
    paddingHorizontal: 24,
    paddingVertical: 12,
    borderRadius: 8,
  },
  retryButtonText: {
    fontSize: 16,
  },
  loadingOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1000,
  },
  loadingText: {
    fontSize: 16,
    marginTop: 16,
  },
  webView: {
    flex: 1,
  },
  webViewLoading: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
  },
  webViewLoadingText: {
    fontSize: 14,
    marginTop: 8,
  },
  processingOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 2000,
  },
  processingModal: {
    borderRadius: 16,
    padding: 32,
    alignItems: 'center',
    minWidth: 280,
    maxWidth: 320,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.2,
    shadowRadius: 8,
    elevation: 8,
  },
  processingIconContainer: {
    marginBottom: 20,
  },
  processingTitle: {
    fontSize: 20,
    marginBottom: 12,
    textAlign: 'center',
  },
  processingStep: {
    fontSize: 14,
    textAlign: 'center',
    lineHeight: 20,
    marginBottom: 20,
  },
  processingDots: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  dot: {
    width: 8,
    height: 8,
    borderRadius: 4,
    marginHorizontal: 4,
  },
});

export default SalesforceAuth;

