import { setCredentials } from '@/features/auth/authSlice';
import * as SecureStore from 'expo-secure-store';
import { Platform } from 'react-native';
import Toast from 'react-native-toast-message';
import { useAuth } from '../contexts/auth-context';
import { store } from '../store';
import { User } from '../types/user';

// 定义错误码常量
const ERROR_CODES = {
    UNAUTHORIZED: 1004010001,
} as const;

export interface ApiResponse<T> {
    code: number;
    data: T | null;
    message: string | null;
}

export interface PagedResult<T> {
    items: T[];
    has_more: boolean;
}
// 获取.env文件中的变量

export const API_ENDPOINT = "http://192.168.31.115:18080/api"

// 更新 access_token 的逻辑 - 用于React组件中
export const useAuthToken = async<T>(message: string | null) => {
    try {
        const { login } = useAuth();
        const response = await fetch(`${API_ENDPOINT}/v1/iam/access-token-refresh`);
        const apiResponse: ApiResponse<T> = await response.json();

        // 如果接口报错，页面弹出来错误信息
        if (apiResponse.code != 0) {
            if (Platform.OS === 'web') {
                Toast.show({
                    type: 'error',
                    text1: apiResponse.message || 'Request failed'
                });
            }
            throw new Error(message || 'Unknown error');
        } else {
            const userData = apiResponse.data as User;
            // 接口未报错，通过auth-context文件的login函数来更新access token 
            login(userData, userData.access_token || "");
        }
        return apiResponse;
    } catch (error) {
        console.error(`Error fetching data from /iam/access-token-refresh:`, error);
        throw error;
    }
}

// 使用Redux存储token的刷新token函数
export const refreshAuthToken = async<T>(message: string | null): Promise<User> => {
    try {
        let cookie = "";
        let userId = "";
        if (Platform.OS === 'web') {
            cookie = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user') || "")?.refresh_token || "" : "";
            userId = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user') || "")?.user_id || "" : "";
        } else {
            await SecureStore.getItemAsync('user').then((user: User) => {
                cookie = user?.refresh_token || "";
                userId = user?.user_id || "";
            })
        }

        // 退出刷新会重新填充数据
        let response;

        response = await fetch(`${API_ENDPOINT}/v1/iam/access-token-refresh`, {
            method: "POST",
            body: JSON.stringify({
                "refresh_token": cookie,
                "user_id": userId
            }),
            headers: {
                'Content-Type': 'application/json',
            }
        });

        const apiResponse: ApiResponse<T> = await response.json();
        if (apiResponse.code != 0) {
            throw new Error(message || 'Unknown error');
        }

        const userData = apiResponse.data as User;

        if (userData && userData.access_token) {
            // 使用Redux更新token
            store.dispatch(setCredentials({
                user: userData,
                token: userData.access_token
            }));
        }

        return userData;
    } catch (error) {
        // console.error(`Error refreshing token:`, error);
        throw error;
    }
}

// 处理 API 错误
const handleApiError = (error: unknown, needToast = true, defaultMessage = 'Unknown error') => {
    const message = error instanceof Error ? error.message : defaultMessage;
    if (needToast) {
        // console.log(message);
    }
    throw new Error(message);
};

// 处理必须携带 token 的接口
export const fetchApi = async <T>(
    path: string,
    options: RequestInit = {},
    needToast = true,
    needToken = true,
): Promise<T> => {
    const makeRequest = async (isRetry = false): Promise<ApiResponse<T>> => {
        try {
            let token = "";
            if (Platform.OS === 'web') {
                token = localStorage.getItem('token') || "";
            } else {
                token = await SecureStore.getItemAsync('token') || "";
            }
            const headers = new Headers(options.headers);

            // 添加必要的 headers
            if (options.method !== 'GET' && !headers.has('Content-Type')) {
                headers.set('Content-Type', 'application/json');
            }

            if (token != null && needToken) {
                headers.set('Authorization', `Bearer ${token}`);
            }

            const url = `${API_ENDPOINT}/v1${path}`;
            const response = await fetch(url, {
                ...options,
                headers,
            });

            const apiResponse: ApiResponse<T> = await response.json();

            // 处理未授权错误（需要刷新 token）
            if (apiResponse.code === ERROR_CODES.UNAUTHORIZED && !isRetry) {
                await refreshAuthToken(apiResponse.message);
                return makeRequest(true); // 重试请求
            }

            // 处理其他错误
            if (apiResponse.code !== 0) {
                // 如果是web端则显示提示
                if (Platform.OS === 'web') {
                    Toast.show({
                        type: 'error',
                        text1: apiResponse.message || 'Request failed'
                    });
                }
                throw new Error(apiResponse.message || 'Request failed');
            }

            return apiResponse;
        } catch (error) {
            if (error instanceof Error) {
                throw error;
            }
            throw new Error('An unknown error occurred');
        }
    };

    try {
        const response = await makeRequest();
        return response.data || ({} as T);
    } catch (error) {
        return handleApiError(error, needToast);
    }
};