import axios from 'axios';


 class authAPI {

    // static getUserById(userId) {
    //     // 例如 GET http://localhost:8080/123
    //     return axios.get(`/${userId}`);
    // }


    // static updateUser(userId, data) {
    //     // 例如 PUT http://localhost:8080/123  Body: { username: 'xxx', ... }
    //     return axios.put(`/${userId}`, data);
    // }
    //
    //
    // static deleteUser(userId:string) {
    //     // 例如 DELETE http://localhost:8080/123
    //     return axios.delete(`/${userId}`);
    // }


    static sendVerificationCode(email: string) {
        // Body: { email: 'xxx@yyy.com'}
        return axios.post('/api/sendVerification', { email });
    }


    static sendResetCode(email: string) {
        // Body: { email: 'xxx@yyy.com' }
        return axios.post('/api/sendResetCode', { email });
    }

    //
    // static resetPassword({ email, code, newPassword }) {
    //     // Body: { email, code, newPassword }
    //     return axios.post('/resetPassword', { email, code, newPassword });
    // }
    //
    //
    // static register({ username, email, verificationCode, password }) {
    //     // Body: { username, email, verificationCode, password, identificationNumber? }
    //     const body = {
    //         username,
    //         email,
    //         verificationCode,
    //         password,
    //     };
    //     return axios.post('/register', body);
    // }
    //
    // /**
    //  * 刷新 JWT Token（POST /refreshToken）
    //  * @param {string} oldToken 旧的 JWT（放在 header: token）
    //  * @returns {Promise<AxiosResponse>}
    //  */
    // static refreshToken(oldToken : string) {
    //     // 因为后端是从 header 中读取旧 token，这里直接把 token 放进 headers
    //     return axios.post(
    //         '/refreshToken',
    //         {}, // 请求体空
    //         {
    //             headers: {
    //                 token: oldToken,
    //             },
    //         }
    //     );
    // }
    //
    //
    // static login({ email, password } : {email: string, password:string}) {
    //     // Body: { email, password }
    //     return axios.post('/login', { email, password });
    // }

}

export default authAPI;

