// src/api/client.ts
import axios, { AxiosError } from 'axios'; // Import AxiosError
import { Platform } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import AsyncStorage from '@react-native-async-storage/async-storage';


const API_BASE_URL = process.env.EXPO_PUBLIC_API_URL || 'http://192.168.255.221:8000/api'; // Use your machine's IP
// const API_BASE_URL = process.env.EXPO_PUBLIC_API_URL || 'http://192.168.1.9:8000/api'; // Use your machine's IP
// const API_BASE_URL = process.env.EXPO_PUBLIC_API_URL || 'http://localhost:8000/api'; // Use your machine's IP
const TOKEN_KEY = 'maia_access_token';

console.log("Using API Base URL:", API_BASE_URL);

// Helper functions for storage (assuming they are defined above or imported)
// const getToken = async (): Promise<string | null> => { ... };
// const deleteToken = async () => { ... };


const apiClient = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    'Content-Type': 'application/json',
  },
  timeout: 10000,
  ...(Platform.OS === 'web' ? { withCredentials: true } : {}),
});

// --- Request Interceptor remains the same ---
apiClient.interceptors.request.use(
  async (config) => {
    // Using AsyncStorage for web token retrieval here too for consistency
    const token = Platform.OS === 'web'
        ? await AsyncStorage.getItem(TOKEN_KEY)
        : await SecureStore.getItemAsync(TOKEN_KEY).catch(() => null); // Handle potential SecureStore error

    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    console.log('[API Client] Starting Request', config.method?.toUpperCase(), config.url);
    return config;
  },
  (error) => {
    console.error('[API Client] Request Setup Error:', error);
    return Promise.reject(error);
  }
);


// --- Modified Response Interceptor ---
apiClient.interceptors.response.use(
  (response) => {
    // Success case
    return response;
  },
  async (error: AxiosError) => { // Explicitly type error as AxiosError
    const originalRequest = error.config;

    // Check if the error has a response object AND an original request config
    if (error.response && originalRequest) { // <-- Added check for originalRequest
      // Server responded with an error status code (4xx, 5xx)
      console.error('[API Client] Response Error Status:', error.response.status);
      console.error('[API Client] Response Error Data:', error.response.data);

      // Handle 401 specifically
      if (error.response.status === 401) {
        console.warn('[API Client] Unauthorized (401). Token might be expired or invalid.');

        if (originalRequest.url === '/auth/refresh') {
            console.error('[API Client] Refresh token attempt failed with 401. Not retrying.');
            // Clear token and reject without retry
            if (Platform.OS === 'web') {
                await AsyncStorage.removeItem(TOKEN_KEY);
            } else {
                await SecureStore.deleteItemAsync(TOKEN_KEY).catch(() => {}); // Ignore delete error
            }
            delete apiClient.defaults.headers.common['Authorization'];
            return Promise.reject(error); // Reject immediately
        }

        // Proceed with refresh logic only if it wasn't the refresh endpoint that failed
        // and if originalRequest exists (already checked above)
        if (!originalRequest._retry) { // Now TS knows _retry exists due to declaration file
          originalRequest._retry = true;

          try {
            console.log('[API Client] Attempting token refresh...');
            const refreshResponse = await apiClient.post('/auth/refresh', {}, {
              headers: {
                'Content-Type': 'application/json',
              },
            });

            if (refreshResponse.status === 200) { 
              const newToken = refreshResponse.data?.access_token;

              if (newToken) {
                console.log('[API Client] Token refreshed successfully.');
                // Save the new token
                if (Platform.OS === 'web') {
                  await AsyncStorage.setItem(TOKEN_KEY, newToken);
                } else {
                  await SecureStore.setItemAsync(TOKEN_KEY, newToken);
                }

                // Update the Authorization header for future requests
                apiClient.defaults.headers.common['Authorization'] = `Bearer ${newToken}`;
                // Safely update original request headers
                if (originalRequest.headers) {
                    originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
                }

                // Retry the original request (originalRequest is guaranteed to exist here)
                return apiClient(originalRequest);
              } else {
                console.error('[API Client] Invalid token structure received during refresh:', refreshResponse.data);
                throw new Error('Invalid token received from server.');
              }
            }
          } catch (refreshError: any) {
            console.error('[API Client] Token refresh failed:', refreshError);
          }
        }

        // Clear potentially invalid token due to 401
        console.log('[API Client] Clearing potentially invalid token due to 401.');
         if (Platform.OS === 'web') {
            await AsyncStorage.removeItem(TOKEN_KEY);
         } else {
            await SecureStore.deleteItemAsync(TOKEN_KEY).catch(() => {}); // Ignore delete error
         }
        delete apiClient.defaults.headers.common['Authorization'];

        // How to trigger logout? Propagating error is simplest for now.
      }
    } else if (error.request) {
      // The request was made but no response was received
      // (e.g., network error, CORS block preventing response reading, server timeout)
      console.error('[API Client] Network Error or No Response:', error.message);
      // Log the request object for debugging if needed
      // console.error('[API Client] Error Request Object:', error.request);
       // If CORS is suspected, this is often where the error ends up.
       if (error.message.toLowerCase().includes('network error') && Platform.OS === 'web') {
           console.warn('[API Client] Hint: A "Network Error" on web often masks a CORS issue. Check browser console & backend CORS config.');
       }

    } else {
      // Something happened in setting up the request that triggered an Error
      console.error('[API Client] Request Setup Error (Interceptor):', error.message);
    }

    // Log the config that failed (optional, can be verbose)
    // console.error("[API Client] Failing Request Config:", error.config);

    // Always reject the promise to propagate the error
    return Promise.reject(error);
  }
);

export default apiClient;