import React, { useState } from 'react';
import { Image, StyleSheet, Alert } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';
import * as AuthSession from 'expo-auth-session';
import * as QueryParams from 'expo-auth-session/build/QueryParams';
import { supabase } from '@/lib/supabase';
import { ThemedView, ThemedButton, ThemedText } from '@/components/theme';
import { Colors } from '@/constants/Colors';
import type { updateUser } from '@/constants/Types';

WebBrowser.maybeCompleteAuthSession();

// Configuration for Azure AD
const tenantId = process.env.EXPO_PUBLIC_AZURE_TENANT_ID;
const clientId = process.env.EXPO_PUBLIC_AZURE_CLIENT_ID;

// Create MSAL auth request
const redirectUri = Linking.createURL('auth/callback');
const discovery = {
  authorizationEndpoint: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`,
  tokenEndpoint: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
};

const AzureSignIn = () => {
  const [loading, setLoading] = useState(false);

  const signInWithAzure = async () => {
    try {
      setLoading(true);

      // Create the MSAL auth request
      const request = new AuthSession.AuthRequest({
        clientId: clientId!,
        scopes: ['openid', 'profile', 'email', 'offline_access', 'User.Read'],
        redirectUri,
        usePKCE: true,
        responseType: AuthSession.ResponseType.Code,
      });

      // Generate the auth URL with PKCE
      const authUrl = await request.makeAuthUrlAsync(discovery);
      console.log('Generated auth URL:', authUrl);

      // Open the auth URL in a browser
      const result = await WebBrowser.openAuthSessionAsync(authUrl, redirectUri, {
        showInRecents: true,
      });

      console.log('Auth session result type:', result.type);

      if (result.type === 'success' && result.url) {
        // Parse the URL to get the authorization code
        const { params, errorCode } = QueryParams.getQueryParams(result.url);

        if (errorCode || params.error) {
          const errorMessage = params.error_description || params.error || errorCode;
          throw new Error(`Error during authentication: ${errorMessage}`);
        }

        if (!params.code) {
          throw new Error('No authorization code received');
        }

        console.log('Authorization code received');

        // Exchange the code for tokens
        const tokenResult = await AuthSession.exchangeCodeAsync(
          {
            clientId: clientId!,
            code: params.code,
            redirectUri,
            extraParams: {
              code_verifier: request.codeVerifier || '',
            },
          },
          discovery,
        );

        console.log('Token exchange successful');

        if (!tokenResult.idToken) {
          throw new Error('No ID token received');
        }

        // Now use the ID token to sign in with Supabase
        const { data, error } = await supabase.auth.signInWithIdToken({
          provider: 'azure',
          token: tokenResult.idToken,
        });

        // Check if profies table already has info (User is signing in, not signing up)
        const { data: profileData, error: profileError } = await supabase
          .from('profiles')
          .select('*')
          .eq('id', data.user?.id)
          .single();

        if (profileData.email === '' || !profileData.email && data.session?.user.email) {
          const updateData: updateUser = {
            email: data.session?.user.email ?? '',
          };
          const { error: updateAuthError } = await supabase.auth.updateUser({
            data: updateData,
          });
          if (updateAuthError)
            Alert.alert('Error updating auth info:', updateAuthError.message);
          const { error: updateProfileError } = await supabase
          .from('profiles')
          .upsert({
            id: data.session?.user.id ?? '',
            email: data.session?.user.email ?? '',
            provider: 'azure',
            updated_at: new Date(),
          });
          if (updateProfileError)
            Alert.alert('Error updating profile:', updateProfileError.message);
        }

        if (error) {
          console.error('Supabase sign-in error:', error);
          throw error;
        }

        console.log('Successfully signed in with Azure via Supabase');
        return data;
      } else {
        console.log('Authentication was canceled or failed');
      }
    } catch (error: any) {
      console.error('Error signing in with Azure:', error);
      Alert.alert('Sign In Error', error.message || 'An error occurred during sign in');
    } finally {
      setLoading(false);
    }
  };

  return (
    <ThemedButton disabled={loading} onPress={signInWithAzure}>
      <Image source={require('@/assets/images/Microsoft_Logo.png')} style={styles.microsoftLogo} />
      <ThemedText
        type='custom'
        fontWeight='semibold'
        fontSize={26}
        lightColor={Colors.dark.text}
        darkColor={Colors.light.text}
      >
        {loading ? 'Signing in...' : 'Sign in with Microsoft'}
      </ThemedText>
    </ThemedButton>
  );
};

export default AzureSignIn;

const styles = StyleSheet.create({
  microsoftLogo: {
    height: 30,
    width: 30,
    marginRight: 10,
  },
});
