import React, { useState, useRef, useEffect, useCallback } from 'react';
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Image } from 'react-native';
import { WebView, WebViewNavigation } from 'react-native-webview';
import { Ionicons } from '@expo/vector-icons';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useAuth } from '@/contexts/AuthContext';
import { api } from '@/services/api';
import { AppColors, FontSizes, Spacing } from '@/constants/theme';

const DASHBOARD_URL = 'https://react.eluxnetworks.net/dashboard';
// URLs that indicate session expired (login page)
const LOGIN_URL_PATTERNS = ['/login', '/auth', '/signin'];
// Text patterns that indicate session expired (shown in page content)
const SESSION_EXPIRED_PATTERNS = ['session expired', 'session has expired', 'token expired', 'please log in'];

export default function HomeScreen() {
  const { user } = useAuth();
  const webViewRef = useRef<WebView>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [canGoBack, setCanGoBack] = useState(false);
  const [authToken, setAuthToken] = useState<string | null>(null);
  const [userName, setUserName] = useState<string | null>(null);
  const [userId, setUserId] = useState<string | null>(null);
  const [isTokenLoaded, setIsTokenLoaded] = useState(false);
  const [isRefreshingToken, setIsRefreshingToken] = useState(false);

  // Load credentials and check/refresh token if needed
  const loadCredentials = useCallback(async () => {
    try {
      // Check if token is expiring soon and refresh if needed
      const isExpiring = await api.isTokenExpiringSoon();
      if (isExpiring) {
        console.log('Token expiring soon, refreshing...');
        const refreshResult = await api.refreshToken();
        if (!refreshResult.ok) {
          console.log('Token refresh failed, using existing credentials');
        }
      }

      // Get credentials (possibly refreshed)
      const credentials = await api.getWebViewCredentials();
      if (credentials) {
        setAuthToken(credentials.token);
        setUserName(credentials.userName);
        setUserId(credentials.userId);
        console.log('Home: Loaded credentials for WebView:', {
          hasToken: !!credentials.token,
          user: credentials.userName,
          uid: credentials.userId
        });
      }
    } catch (err) {
      console.warn('Failed to load credentials:', err);
    } finally {
      setIsTokenLoaded(true);
    }
  }, []);

  useEffect(() => {
    loadCredentials();

    // Periodically check and refresh token (every 30 minutes)
    const tokenCheckInterval = setInterval(async () => {
      const isExpiring = await api.isTokenExpiringSoon();
      if (isExpiring) {
        console.log('Periodic check: Token expiring, refreshing...');
        const result = await api.refreshToken();
        if (result.ok) {
          const credentials = await api.getWebViewCredentials();
          if (credentials) {
            setAuthToken(credentials.token);
            // Re-inject token into WebView
            const injectScript = `
              (function() {
                var authData = {
                  username: '${credentials.userName}',
                  token: '${credentials.token}',
                  user_id: ${credentials.userId}
                };
                localStorage.setItem('auth2', JSON.stringify(authData));
                console.log('Token auto-refreshed');
              })();
              true;
            `;
            webViewRef.current?.injectJavaScript(injectScript);
          }
        }
      }
    }, 30 * 60 * 1000); // 30 minutes

    return () => clearInterval(tokenCheckInterval);
  }, [loadCredentials]);

  // Handle token refresh when WebView detects session expired
  const handleTokenRefresh = useCallback(async () => {
    if (isRefreshingToken) return;

    setIsRefreshingToken(true);
    console.log('WebView session expired, refreshing token...');

    try {
      const refreshResult = await api.refreshToken();
      if (refreshResult.ok) {
        // Get new credentials
        const credentials = await api.getWebViewCredentials();
        if (credentials) {
          setAuthToken(credentials.token);
          setUserName(credentials.userName);
          setUserId(credentials.userId);

          // Inject new token and reload
          const injectScript = `
            (function() {
              var authData = {
                username: '${credentials.userName}',
                token: '${credentials.token}',
                user_id: ${credentials.userId}
              };
              localStorage.setItem('auth2', JSON.stringify(authData));
              console.log('Auth refreshed:', authData.username);
              window.location.href = '${DASHBOARD_URL}';
            })();
            true;
          `;
          webViewRef.current?.injectJavaScript(injectScript);
        }
      } else {
        console.warn('Token refresh failed');
        setError('Session expired. Please restart the app.');
      }
    } catch (err) {
      console.warn('Error refreshing token:', err);
    } finally {
      setIsRefreshingToken(false);
    }
  }, [isRefreshingToken]);

  // JavaScript to inject auth token into localStorage and monitor for session expiry
  // Web app expects auth2 as JSON: {username, token, user_id}
  const injectedJavaScript = authToken
    ? `
      (function() {
        try {
          // Inject auth data
          var authData = {
            username: '${userName || ''}',
            token: '${authToken}',
            user_id: ${userId || 'null'}
          };
          localStorage.setItem('auth2', JSON.stringify(authData));
          console.log('Auth injected:', authData.username);

          // Monitor page content for session expired messages
          var sessionExpiredPatterns = ${JSON.stringify(SESSION_EXPIRED_PATTERNS)};

          function checkForSessionExpired() {
            var bodyText = (document.body?.innerText || '').toLowerCase();
            for (var i = 0; i < sessionExpiredPatterns.length; i++) {
              if (bodyText.includes(sessionExpiredPatterns[i])) {
                console.log('Session expired detected in page content');
                window.ReactNativeWebView?.postMessage(JSON.stringify({ type: 'SESSION_EXPIRED' }));
                return true;
              }
            }
            return false;
          }

          // Check after page loads and periodically
          setTimeout(checkForSessionExpired, 1000);
          setTimeout(checkForSessionExpired, 3000);

          // Also observe DOM changes for dynamic content
          var observer = new MutationObserver(function() {
            checkForSessionExpired();
          });
          if (document.body) {
            observer.observe(document.body, { childList: true, subtree: true });
          }
        } catch(e) {
          console.warn('Failed to inject token:', e);
        }
      })();
      true;
    `
    : '';

  const handleRefresh = () => {
    setError(null);
    setIsLoading(true);
    webViewRef.current?.reload();
  };

  const handleWebViewBack = () => {
    if (canGoBack) {
      webViewRef.current?.goBack();
    }
  };

  const handleNavigationStateChange = (navState: WebViewNavigation) => {
    setCanGoBack(navState.canGoBack);

    // Check if WebView is trying to navigate to login page (session expired)
    const url = navState.url?.toLowerCase() || '';
    const isLoginPage = LOGIN_URL_PATTERNS.some(pattern => url.includes(pattern));

    if (isLoginPage && !isRefreshingToken) {
      console.log('Detected navigation to login page, refreshing token...');
      handleTokenRefresh();
    }
  };

  // Intercept navigation requests to prevent loading login page
  const handleShouldStartLoadWithRequest = useCallback((request: { url: string }) => {
    const url = request.url?.toLowerCase() || '';
    const isLoginPage = LOGIN_URL_PATTERNS.some(pattern => url.includes(pattern));

    if (isLoginPage) {
      console.log('Blocking navigation to login page, refreshing token instead');
      handleTokenRefresh();
      return false; // Block the navigation
    }

    return true; // Allow all other navigations
  }, [handleTokenRefresh]);

  const handleError = () => {
    setError('Failed to load dashboard. Please check your internet connection.');
    setIsLoading(false);
  };

  // Handle messages from WebView (session expired detection)
  const handleWebViewMessage = useCallback((event: { nativeEvent: { data: string } }) => {
    try {
      const message = JSON.parse(event.nativeEvent.data);
      if (message.type === 'SESSION_EXPIRED') {
        console.log('WebView reported session expired, refreshing token...');
        handleTokenRefresh();
      }
    } catch {
      // Ignore non-JSON messages
    }
  }, [handleTokenRefresh]);

  // Wait for token to load
  if (!isTokenLoaded) {
    return (
      <SafeAreaView style={styles.container} edges={['top']}>
        <View style={styles.header}>
          <View style={styles.headerLeft}>
            <Image
              source={require('@/assets/images/icon.png')}
              style={styles.logo}
              resizeMode="contain"
            />
            <Text style={styles.greeting}>Hello, {user?.user_name || 'User'}</Text>
          </View>
        </View>
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={AppColors.primary} />
          <Text style={styles.loadingText}>Preparing dashboard...</Text>
        </View>
      </SafeAreaView>
    );
  }

  if (error) {
    return (
      <SafeAreaView style={styles.container} edges={['top']}>
        <View style={styles.header}>
          <View style={styles.headerLeft}>
            <Image
              source={require('@/assets/images/icon.png')}
              style={styles.logo}
              resizeMode="contain"
            />
            <Text style={styles.greeting}>Hello, {user?.user_name || 'User'}</Text>
          </View>
          <TouchableOpacity style={styles.refreshButton} onPress={handleRefresh}>
            <Ionicons name="refresh" size={22} color={AppColors.primary} />
          </TouchableOpacity>
        </View>
        <View style={styles.errorContainer}>
          <Ionicons name="cloud-offline-outline" size={64} color={AppColors.textMuted} />
          <Text style={styles.errorTitle}>Connection Error</Text>
          <Text style={styles.errorText}>{error}</Text>
          <TouchableOpacity style={styles.retryButton} onPress={handleRefresh}>
            <Text style={styles.retryButtonText}>Try Again</Text>
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    );
  }

  return (
    <SafeAreaView style={styles.container} edges={['top']}>
      {/* Header */}
      <View style={styles.header}>
        <View style={styles.headerLeft}>
          <Image
            source={require('@/assets/images/icon.png')}
            style={styles.logo}
            resizeMode="contain"
          />
          <Text style={styles.greeting}>Hello, {user?.user_name || 'User'}</Text>
        </View>
        <View style={styles.headerActions}>
          {canGoBack && (
            <TouchableOpacity style={styles.actionButton} onPress={handleWebViewBack}>
              <Ionicons name="chevron-back" size={22} color={AppColors.primary} />
            </TouchableOpacity>
          )}
          <TouchableOpacity style={styles.actionButton} onPress={handleRefresh}>
            <Ionicons name="refresh" size={22} color={AppColors.primary} />
          </TouchableOpacity>
        </View>
      </View>

      {/* WebView Dashboard */}
      <View style={styles.webViewContainer}>
        <WebView
          ref={webViewRef}
          source={{ uri: DASHBOARD_URL }}
          style={styles.webView}
          onLoadStart={() => setIsLoading(true)}
          onLoadEnd={() => setIsLoading(false)}
          onError={handleError}
          onHttpError={handleError}
          onNavigationStateChange={handleNavigationStateChange}
          onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
          onMessage={handleWebViewMessage}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          startInLoadingState={true}
          scalesPageToFit={true}
          allowsBackForwardNavigationGestures={true}
          injectedJavaScriptBeforeContentLoaded={injectedJavaScript}
          injectedJavaScript={injectedJavaScript}
          renderLoading={() => (
            <View style={styles.loadingContainer}>
              <ActivityIndicator size="large" color={AppColors.primary} />
              <Text style={styles.loadingText}>Loading dashboard...</Text>
            </View>
          )}
        />

        {isLoading && (
          <View style={styles.loadingOverlay}>
            <ActivityIndicator size="large" color={AppColors.primary} />
          </View>
        )}
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: AppColors.background,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: Spacing.lg,
    paddingVertical: Spacing.md,
    backgroundColor: AppColors.background,
    borderBottomWidth: 1,
    borderBottomColor: AppColors.border,
  },
  headerLeft: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: Spacing.sm,
  },
  logo: {
    width: 36,
    height: 36,
  },
  greeting: {
    fontSize: FontSizes.sm,
    color: AppColors.textSecondary,
  },
  headerTitle: {
    fontSize: FontSizes.xl,
    fontWeight: '700',
    color: AppColors.textPrimary,
  },
  headerActions: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  actionButton: {
    padding: Spacing.xs,
    marginLeft: Spacing.xs,
  },
  refreshButton: {
    padding: Spacing.xs,
  },
  webViewContainer: {
    flex: 1,
  },
  webView: {
    flex: 1,
  },
  loadingContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: AppColors.background,
  },
  loadingOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(255,255,255,0.8)',
  },
  loadingText: {
    marginTop: Spacing.md,
    fontSize: FontSizes.base,
    color: AppColors.textSecondary,
  },
  errorContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: Spacing.xl,
  },
  errorTitle: {
    fontSize: FontSizes.lg,
    fontWeight: '600',
    color: AppColors.textPrimary,
    marginTop: Spacing.md,
  },
  errorText: {
    fontSize: FontSizes.base,
    color: AppColors.textSecondary,
    textAlign: 'center',
    marginTop: Spacing.xs,
  },
  retryButton: {
    marginTop: Spacing.lg,
    paddingHorizontal: Spacing.xl,
    paddingVertical: Spacing.md,
    backgroundColor: AppColors.primary,
    borderRadius: 8,
  },
  retryButtonText: {
    color: AppColors.white,
    fontSize: FontSizes.base,
    fontWeight: '600',
  },
});
