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
type ServiceKey = 'zohoProjects' | 'zohoCRM' | 'zohoBooks' | 'zohoPeople';

interface ZohoAuthProps {
  serviceKey?: ServiceKey;
  onAuthSuccess?: (authData: ZohoAuthData) => void;
  onAuthError?: (error: string) => void;
  onClose?: () => void;
}

interface ZohoAuthData {
  accessToken: string;
  refreshToken?: string;
  expiresIn?: number;
  scope?: string;
  tokenType?: string;
}

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

// Zoho OAuth Configuration
const ZOHO_CONFIG = {
  // Replace with your actual Zoho OAuth app credentials
  CLIENT_ID: '1000.PY0FB5ABLLFK2WIBDCNCGKQ0EUIJMY',
  REDIRECT_URI: 'centralizedreportingsystem://oauth/callback', // Must match Zoho console exactly
  ACCOUNTS_BASE_URL: 'https://accounts.zoho.com', // Change to region if needed (e.g., .eu, .in)
  RESPONSE_TYPE: 'code',
  ACCESS_TYPE: 'offline',
  PROMPT: 'consent',
};

// Unified scope: request all needed product scopes in one consent, so the issued token works
// across Projects, CRM, Books, and People. Tailor scopes to your app's needs and compliance.
const getScopeForService = (_serviceKey?: ServiceKey): string => {
  return [
    //zoho portals
    'ZohoProjects.portals.READ',
    // Zoho Projects
    'ZohoProjects.projects.READ',
    'ZohoProjects.tasklists.READ',
    // Zoho Projects Tasks
    'ZohoProjects.tasks.READ',
    // Zoho Projects Issues
    'ZohoProjects.bugs.READ',
    // Zoho Projects Milestones
    'ZohoProjects.milestones.READ',
    // Zoho Projects Timesheets
    'ZohoProjects.timesheets.READ',
    // Zoho CRM (adjust modules per your needs)
    'ZohoCRM.users.READ',
    'ZohoCRM.modules.READ',
    //settings
    'ZohoCRM.settings.READ',
    //crm bulk read scope
    'ZohoCRM.bulk.READ',
    //notification access
    'ZohoCRM.notifications.ALL',
    // Zoho Books (use granular scopes if preferred instead of FullAccess)
    'ZohoBooks.FullAccess.READ',
    // Zoho People
    'ZohoPeople.employee.READ',
    'ZohoPeople.attendance.READ',
    'ZohoPeople.leave.READ',
    'ZohoPeople.performance.READ',
    'ZohoPeople.forms.READ',
    //can read the user info
    'aaaserver.profile.READ'
  ].join(',');
};

// Build Zoho OAuth URL
const buildZohoAuthUrl = (scope: string): string => {
  const baseUrl = `${ZOHO_CONFIG.ACCOUNTS_BASE_URL}/oauth/v2/auth`;
  const params = new URLSearchParams({
    client_id: ZOHO_CONFIG.CLIENT_ID,
    redirect_uri: ZOHO_CONFIG.REDIRECT_URI,
    scope,
    response_type: ZOHO_CONFIG.RESPONSE_TYPE,
    access_type: ZOHO_CONFIG.ACCESS_TYPE,
    prompt: ZOHO_CONFIG.PROMPT,
  });
  
  return `${baseUrl}?${params.toString()}`;
};

// Safe query param parser for React Native (avoids relying on DOM URL types)
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 redirect URI
const isRedirectUri = (url: string): boolean => {
  return url.startsWith(ZOHO_CONFIG.REDIRECT_URI);
};

const ZohoAuth: React.FC<ZohoAuthProps> = ({
  serviceKey,
  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 currentScope = useMemo(() => getScopeForService(serviceKey), [serviceKey]);
  
  const [state, setState] = useState<ZohoAuthState>({
    loading: true,
    error: null,
    currentUrl: buildZohoAuthUrl(currentScope),
    processing: false,
    processingStep: '',
  });

  // Backend exchange mode: only log and return the authorization code to the caller
  const handleAuthorizationCode = useCallback(async (authCode: string) => {
    console.log('[ZohoAuth] Authorization code received:', authCode);
    console.log('[ZohoAuth] Send this code to your backend to exchange for tokens.',user);
    
    // Show processing modal
    setState(prev => ({ 
      ...prev, 
      processing: true, 
      processingStep: 'Storing credentials and preparing data setup...' 
    }));
    
    try {
      const response = await manageToken.manageToken({ 
        authorization_code: authCode, 
        id: user?.uuid || '', 
        service_name: 'zoho', 
        access_token: accessToken || '' 
      });
      
      console.log('[ZohoAuth] Response from manageToken:', response);
      
      // Check if response status is success
      if (response?.data && typeof response.data === 'object' && 'status' in response.data && response.data.status === 'success') {
        console.log('[ZohoAuth] Token exchange successful, scheduling bulk read job...');
        
        // Update processing step
        setState(prev => ({ 
          ...prev, 
          processingStep: 'Initializing data import and bulk read job...' 
        }));
        
        try {
          // Schedule bulk read job
          const bulkReadResponse = await http.post('/api/v1/integrations/zoho/bulk-read/schedule?provider=zoho', {}, {
            headers: {
              'Authorization': `Bearer ${accessToken}`,
            },
          });
          
          console.log('[ZohoAuth] Bulk read job scheduled:', bulkReadResponse.data);
          
          // Update processing step
          setState(prev => ({ 
            ...prev, 
            processingStep: 'Data import process initiated successfully!' 
          }));
          
          // Wait a moment to show success message
          await new Promise<void>(resolve => setTimeout(resolve, 1500));
        } catch (bulkReadError) {
          console.warn('[ZohoAuth] Failed to schedule bulk read job:', bulkReadError);
          // Don't fail the auth process if bulk read scheduling fails
        }
      } else {
        const errorMessage = response?.data && typeof response.data === 'object' && 'message' in response.data 
          ? response.data.message 
          : 'Unknown error';
        console.warn('[ZohoAuth] Token exchange failed:', errorMessage);
      }
      
      // Hide processing modal and call success callback
      setState(prev => ({ ...prev, processing: false, processingStep: '' }));
      
      // Return the code via onAuthSuccess using the existing shape
      onAuthSuccess?.({
        accessToken: authCode, // This is the AUTHORIZATION CODE, not an access token
        tokenType: 'authorization_code',
        scope: currentScope,
        expiresIn: undefined,
        refreshToken: undefined,
      });
    } catch (error) {
      console.error('[ZohoAuth] Error during token exchange:', error);
      
      // Hide processing modal and call success callback
      setState(prev => ({ ...prev, processing: false, processingStep: '' }));
      
      // Still call onAuthSuccess with the auth code even if bulk read fails
      onAuthSuccess?.({
        accessToken: authCode,
        tokenType: 'authorization_code',
        scope: currentScope,
        expiresIn: undefined,
        refreshToken: undefined,
      });
    }
  }, [onAuthSuccess, currentScope, user?.uuid, accessToken]);

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

    // First: intercept redirect URI to capture code
    if (isRedirectUri(url) && authCode) {
      console.log('[ZohoAuth] redirect detected in nav change. Code captured.');
      handleAuthorizationCode(authCode);
      return;
    }

    // Navigate to tabs based on keywords in URL
    const lowerUrl = (url ?? '').toLowerCase();
    if (lowerUrl.includes('dashboard')) {
      // Close auth view if provided and navigate to Dashboard tab
      const params = getAllQueryParamsFromUrl(url || '');
      onClose?.();
      // Pass any available params to the Dashboard tab (component can consume via route.params)
      navigation.navigate('Dashboard' as never, params as never);
      return;
    }
    // if (lowerUrl.includes('profile')) {
    //   // Close auth view if provided and navigate to Profile tab
    //   const params = getAllQueryParamsFromUrl(url || '');
    //   // Prefer `userId` param when present and numeric
    //   if (typeof params.userId === 'string' && /^-?\d+$/.test(params.userId)) {
    //     params.userId = Number(params.userId);
    //   }
    //   onClose?.();
    //   // Route into Profile stack's default screen with params
    //   navigation.navigate('Profile' as never, { screen: 'Profile', params } as never);
    //   return;
    // }

    // Fallback: if redirect URI without code or with error
    if (isRedirectUri(url) && !loading) {
      const err = getQueryParamFromUrl(url, 'error');
      if (err) {
        const errorDescription = getQueryParamFromUrl(url, 'error_description') || err;
        handleAuthError(errorDescription);
      }
    }
  }, []);

  // Intercept before WebView tries to handle custom scheme
  const handleShouldStartLoadWithRequest = useCallback((request: any) => {
    const { url } = request || {};
    if (!url) return true;
    if (isRedirectUri(url)) {
      const code = extractAuthCode(url);
      console.log('[ZohoAuth] onShouldStart intercept url:', url, 'code:', code);
      if (code) {
        handleAuthorizationCode(code);
        return false; // prevent navigation to custom scheme
      }
    }
    return true;
  }, [handleAuthorizationCode]);

  // Handle successful authentication
  const handleAuthSuccess = useCallback(async (authCode: string) => {
    try {
      setState(prev => ({ ...prev, loading: true }));
      
      // Here you would typically exchange the authorization code for access token
      // This should be done on your backend server for security
      const authData: ZohoAuthData = {
        accessToken: authCode, // In real implementation, this would be the actual access token
        tokenType: 'Bearer',
        expiresIn: 3600,
        scope: currentScope,
      };

      onAuthSuccess?.(authData);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Authentication failed';
      handleAuthError(errorMessage);
    }
  }, [onAuthSuccess, currentScope]);

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

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

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

  const handleLoadEnd = useCallback((e: any) => {
    console.log('[ZohoAuth] 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: buildZohoAuthUrl(currentScope) }));
    webViewRef.current?.reload();
  }, [currentScope]);

  return (
    <SafeAreaView style={[styles.container, { backgroundColor: colors.background }]}>
      {/* Header */}
      <View style={[styles.header, { backgroundColor: colors.surface, ...shadows.light }]}>
        <View style={styles.headerContent}>
          <Icon name="account-circle" size={24} color={colors.primary} />
          <Text style={[styles.headerTitle, { color: colors.text, fontFamily: fonts.medium }]}>
            Zoho 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: colors.primary }]}
            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={colors.primary} />
            </View>
            <Text style={[styles.processingTitle, { color: colors.text, fontFamily: fonts.bold }]}>
              Setting Up Integration
            </Text>
            <Text style={[styles.processingStep, { color: colors.textLight, fontFamily: fonts.regular }]}>
              {state.processingStep}
            </Text>
            <View style={styles.processingDots}>
              <View style={[styles.dot, { backgroundColor: colors.primary }]} />
              <View style={[styles.dot, { backgroundColor: colors.primary }]} />
              <View style={[styles.dot, { backgroundColor: colors.primary }]} />
            </View>
          </View>
        </View>
      )}

      {/* Loading Overlay */}
      {state.loading && !state.error && (
        <View style={[styles.loadingOverlay, { backgroundColor: colors.background }]}>
          <ActivityIndicator size="large" color={colors.primary} />
          <Text style={[styles.loadingText, { color: colors.textLight, fontFamily: fonts.regular }]}>
            Loading Zoho 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={colors.primary} />
              <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 ZohoAuth;
