/**
 * 通用网络请求封装 - 使用 fetch
 */

const BASE_URL = import.meta.env.VITE_API_URL || 'http://127.0.0.1:3001';

// 默认超时时间 15 秒
const DEFAULT_TIMEOUT = 30000;

// 错误码定义
const ERR_CODE = {
    SUCCESS: 200,
    UNAUTHORIZED: 401,
    FORBIDDEN: 403,
    NOT_FOUND: 404,
    SERVER_ERROR: 500,
};

function getHeaders(contentType = 'application/json') {
    const headers = {
        'Content-Type': contentType,
    };
    const token = localStorage.getItem('member_token');
    if (token) {
        headers['Authorization'] = `Bearer ${token}`;
    }
    return headers;
}

function handleResponse(response) {
    return response.text().then(text => {
        let data;
        try {
            data = JSON.parse(text);
        } catch (e) {
            // JSON 解析失败，返回原始文本
            return Promise.reject({
                status: response.status,
                message: '数据解析失败',
                data: null
            });
        }

        // 检查 HTTP 状态码
        if (!response.ok) {
            return Promise.reject({
                status: response.status,
                message: data.message || '请求失败',
                data: null
            });
        }

        // 检查业务状态码
        if (data.status !== ERR_CODE.SUCCESS) {
            return Promise.reject(data);
        }

        return data;
    });
}

/**
 * 处理 token 失效
 */
function handleUnauthorized() {
    // 如果 localStorage 中本来就没有 token，说明是未登录状态，不做处理
    if (!localStorage.getItem('member_token')) {
        return;
    }

    // 清除登录状态
    localStorage.removeItem('member_token');
    localStorage.removeItem('member_username');

    // 跳转到登录页
    if (window.location.hash !== '#/Login') {
        window.location.href = '#/Login';
    }
}

/**
 * 统一错误处理
 */
function handleError(err) {
    // token 失效
    if (err.status === ERR_CODE.UNAUTHORIZED || err.status === ERR_CODE.FORBIDDEN) {
        handleUnauthorized();
    }
    return Promise.reject(err);
}

/**
 * 带超时的 fetch
 */
function fetchWithTimeout(url, options, timeout = DEFAULT_TIMEOUT) {
    return new Promise((resolve, reject) => {
        const timer = setTimeout(() => {
            clearTimeout(timer);
            reject({ status: 0, message: '网络超时，请稍后重试', data: null });
        }, timeout);

        fetch(url, options)
            .then(res => {
                clearTimeout(timer);
                resolve(res);
            })
            .catch(err => {
                clearTimeout(timer);
                reject({ status: 0, message: '网络连接失败', data: null });
            });
    });
}

/**
 * 通用请求
 * @param {string} url - 请求路径
 * @param {object} data - 请求数据
 * @param {string} method - 请求方法，默认 POST
 * @param {number} timeout - 超时时间 ms
 * @returns {Promise}
 */
export function request(url, data, method = 'POST', timeout = DEFAULT_TIMEOUT) {
    return fetchWithTimeout(BASE_URL + url, {
        method,
        headers: getHeaders(),
        body: JSON.stringify(data),
    }, timeout).then(handleResponse).catch(handleError);
}

export const get = (url, params, timeout = DEFAULT_TIMEOUT) => {
    let query = '';
    if (params) {
        query = '?' + new URLSearchParams(params).toString();
    }
    return fetchWithTimeout(BASE_URL + url + query, {
        method: 'GET',
        headers: getHeaders(),
    }, timeout).then(handleResponse).catch(handleError);
};

export const post = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'POST', timeout);
export const put = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'PUT', timeout);
export const del = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'DELETE', timeout);

/**
 * POST FormData 请求
 * @param {string} url - 请求路径
 * @param {FormData} formData - FormData 对象
 * @param {number} timeout - 超时时间 ms
 * @returns {Promise}
 */
export function postForm(url, formData, timeout = DEFAULT_TIMEOUT) {
    const headers = {};
    const token = localStorage.getItem('member_token');
    if (token) {
        headers['Authorization'] = `Bearer ${token}`;
    }
    return fetchWithTimeout(BASE_URL + url, {
        method: 'POST',
        headers,
        body: formData,
    }, timeout).then(handleResponse).catch(handleError);
}

/**
 * 上传文件
 * @param {string} url - 请求路径
 * @param {File[]} files - 文件数组
 * @param {number} timeout - 超时时间 ms（默认 30 秒上传较长）
 * @returns {Promise}
 */
export function upload(url, files, timeout = 30000) {
    const formData = new FormData();
    files.forEach(file => {
        formData.append('file', file);
    });

    const headers = {};
    const token = localStorage.getItem('member_token');
    if (token) {
        headers['Authorization'] = `Bearer ${token}`;
    }

    return fetchWithTimeout(BASE_URL + url, {
        method: 'POST',
        headers,
        body: formData,
    }, timeout)
        .then(res => res.text().then(text => {
            try {
                const data = JSON.parse(text);
                if (data.status !== ERR_CODE.SUCCESS) {
                    return Promise.reject(data);
                }
                return data;
            } catch (e) {
                return Promise.reject({ status: 0, message: '数据解析失败', data: null });
            }
        }))
        .catch(handleError);
}

export default { get, post, put, del, upload, postForm, request };