import axios, {AxiosRequestConfig, AxiosResponse} from 'axios';
import {message} from 'antd';

export interface Response<T = any> {
    code: number;
    message: string;
    data: T;
    success: boolean;
}

export interface RequestOptions extends AxiosRequestConfig {
    retryCount?: number;
    retryDelay?: number;
}

// 默认请求配置
const defaultConfig: Partial<RequestOptions> = {
    retryCount: 3,
    retryDelay: 1000,
    timeout: 30000
};

// 创建请求实例
const request = axios.create({
    baseURL: '',
    timeout: 30000,
    withCredentials: true,
    headers: {
        'Content-Type': 'application/json'
    }
});

const defaultErrorMessage = '操作失败';

// 创建请求配置
const createRequestConfig = (options?: Partial<RequestOptions>): RequestOptions => {
    return {
        ...defaultConfig,
        ...options
    };
};

const responseHandler = (response: AxiosResponse<Response<any>>) => {
    const result = response.data;
    if (result.success && result.code === 200) {
        return result.data;
    } else {
        if (result.message != undefined) {
            message.error(result.message || defaultErrorMessage);
            return Promise.reject(response);
        }
        return Promise.reject(response);
    }
};


const errorHandler = (error: any) => {
    if (!error.response) {
        message.error('网络连接异常，请检查网络');
        return Promise.reject(error);
    }

    if (axios.isCancel(error)) {
        return Promise.reject(error);
    }

    const status = error.response.status;
    let errorMessage = '';
    switch (status) {
        case 401:
            errorMessage = '未授权，请重新登录';
            break;
        case 403:
            errorMessage = '拒绝访问';
            break;
        case 404:
            errorMessage = '请求错误，未找到该资源';
            break;
        case 500:
            errorMessage = '服务异常，请稍后再试';
            break;
        default:
            errorMessage = '服务器异常，请稍后再试！';
    }
    message.error(errorMessage);
    return Promise.reject(error);
};

request.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    (error) => Promise.reject(error)
);

request.interceptors.response.use(responseHandler, errorHandler);

const http = {
    get: <T = any>(url: string, config?: RequestOptions) =>
        request.get<any, T>(url, createRequestConfig(config)),

    post: <T = any>(url: string, data?: any, config?: RequestOptions) =>
        request.post<any, T>(url, data, createRequestConfig(config)),

    put: <T = any>(url: string, data?: any, config?: RequestOptions) =>
        request.put<any, T>(url, data, createRequestConfig(config)),

    delete: <T = any>(url: string, config?: RequestOptions) =>
        request.delete<any, T>(url, createRequestConfig(config)),

    upload: <T = any>(url: string, file: File, config?: RequestOptions) => {
        const formData = new FormData();
        formData.append('file', file);
        return request.post<any, T>(url, formData, createRequestConfig({
            headers: {'Content-Type': 'multipart/form-data'},
            ...config
        }));
    },

    download: (url: string, filename?: string, config?: RequestOptions) =>
        request.get(url, createRequestConfig({
            responseType: 'blob',
            ...config
        })).then(response => {
            const blob = new Blob([response.data]);
            const downloadUrl = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = downloadUrl;
            link.download = filename || '';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(downloadUrl);
        })
};

export default http; 