import axios, {AxiosRequestConfig, AxiosResponse} from 'axios';
import {toast} from '@/components/ui/use-toast';
import { API_BASE_URL, isDev } from '@/config/env';
import { maintenanceDetector } from '@/services/maintenanceDetector';
import store from '../store';
import { logout } from '../store/userSlice';

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: API_BASE_URL,
    timeout: 30000,
    withCredentials: true,
    headers: {
        'Content-Type': 'application/json'
    }
});

// 开发环境打印请求配置
if (isDev) {
    console.log('📡 API Base URL:', API_BASE_URL || '使用代理 (proxy)');
}

const defaultErrorMessage = '操作失败';

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

const responseHandler = (response: AxiosResponse<Response<any>>) => {
    // 请求成功，记录到维护检测器
    maintenanceDetector.recordSuccess();

    const result = response.data;
    if (result.success && result.code === 200) {
        return result.data;
    } else {
        if (result.message != undefined) {
            toast({
                title: '操作失败',
                description: result.message || defaultErrorMessage,
                variant: 'destructive'
            });
            return Promise.reject(response);
        }
        return Promise.reject(response);
    }
};


const errorHandler = (error: any) => {
    // 检测网络错误（后端完全不可达）
    if (!error.response) {
        // 记录失败到维护检测器
        maintenanceDetector.recordFailure();
        
        // 不显示toast，因为会跳转到维护页面
        return Promise.reject(error);
    }

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

    const status = error.response.status;
    
    // 检测严重的服务器错误（500+），可能是服务器故障或维护
    if (status >= 500) {
        maintenanceDetector.recordFailure();
        // 继续执行下面的错误处理，显示具体的错误信息
    }
    let errorMessage = '';
    switch (status) {
        case 401:
            // 登录已过期，清除所有本地存储并跳转到登录页
            errorMessage = '登录已过期，请重新登录';
            toast({
                title: '登录已过期',
                description: errorMessage,
                variant: 'destructive'
            });
            
            // 使用统一的 logout action 清除所有用户数据
            store.dispatch(logout());
            
            // 延迟跳转，确保提示能显示出来
            setTimeout(() => {
                window.location.href = '/login';
            }, 1000);
            break;
        case 403:
            errorMessage = '拒绝访问';
            toast({
                title: '访问被拒绝',
                description: errorMessage,
                variant: 'destructive'
            });
            break;
        case 404:
            errorMessage = '请求错误，未找到该资源';
            toast({
                title: '请求错误',
                description: errorMessage,
                variant: 'destructive'
            });
            break;
        case 500:
            errorMessage = '服务异常，请稍后再试';
            toast({
                title: '服务器错误',
                description: errorMessage,
                variant: 'destructive'
            });
            break;
        default:
            errorMessage = '服务器异常，请稍后再试！';
            toast({
                title: '请求失败',
                description: errorMessage,
                variant: 'destructive'
            });
    }
    
    return Promise.reject(error);
};

request.interceptors.request.use(
    (config) => {
        // 检查是否处于维护模式
        if (maintenanceDetector.isInMaintenanceMode()) {
            // 如果在维护模式且当前不在维护页面，跳转
            if (window.location.pathname !== '/maintenance') {
                window.location.replace('/maintenance');
            }
            // 取消请求，避免继续发送
            return Promise.reject(new Error('System in maintenance mode'));
        }

        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; 