import axios from 'axios';
import { api } from './auth';

// const API_BASE_URL = 'http://team2.10813352.xyz:8088'; // 替换为你的后端API基础URL

export const getAllUsers = async () => {
  try {
    const response = await api.get(`/user/allUser`, {
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });
    
    console.log("API Response:", response.data); // 打印完整响应
    
    if (response.data && response.data.code === 200) {
      // 修正这里：response.data.data.data 才是用户数组
      const data = response.data.data.data;
      return Array.isArray(data) ? data : [data];
    } else {
      throw new Error(response.data?.message || "未知错误");
    }
  } catch (error) {
    console.error('获取用户列表失败:', error);
    throw error;
  }
};

export const searchUsers = async (key) => {
  try {
    const response = await api.get(`/user/searchUser`, {
      params: { key },
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });

    if (response.data?.code === 200) {
      // 提取正确的用户数组：response.data.data.data
      const users = response.data.data.data;
      return Array.isArray(users) ? users : [users];
    } else {
      throw new Error(response.data?.message || "搜索失败");
    }
  } catch (error) {
    console.error('搜索用户失败:', error);
    throw error;
  }
};

// 修改用户权限
export const updateUserAuthority = async (username, authority) => {
  try {
    const response = await api.put(`/user/changeAuthority`, 
      { 
        changeUsername: username, 
        authority: authority 
      },
      {
        headers: {
          Authorization: localStorage.getItem('token')
        }
      }
    );
    return response.data;
  } catch (error) {
    console.error('修改用户权限失败:', error);
    throw error;
  }
};


// // 获取所有折扣
// export const getAllDiscounts = async () => {
//   try {
//     const response = await axios.get(`${API_BASE_URL}/discount/all`, {
//       headers: {
//         Authorization: localStorage.getItem('token')
//       }
//     });
    
//     if (response.data && response.data.code === 200) {
//       // 确保返回的是数组格式
//       const data = response.data.data.data || response.data.data;
//       return Array.isArray(data) ? data : [data];
//     } else {
//       throw new Error(response.data?.message || "获取折扣信息失败");
//     }
//   } catch (error) {
//     console.error('获取折扣列表失败:', error);
//     throw error;
//   }
// };

// // 获取当前折扣
// export const getCurrentDiscount = async () => {
//   try {
//     const response = await axios.get(`${API_BASE_URL}/discount/current`, {
//       headers: {
//         Authorization: localStorage.getItem('token')
//       }
//     });
    
//     if (response.data && response.data.code === 200) {
//       return response.data.data.data || response.data.data;
//     } else {
//       throw new Error(response.data?.message || "获取当前折扣失败");
//     }
//   } catch (error) {
//     console.error('获取当前折扣失败:', error);
//     throw error;
//   }
// };
// 修改 getAllDiscounts 和 getCurrentDiscount 方法
export const getAllDiscounts = async () => {
  try {
    const response = await api.get(`/discount/all`, {
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });
    
    if (response.data && response.data.code === 200) {
      // 更健壮的数据提取方式
      return response.data.data?.data || response.data.data || [];
    } else {
      throw new Error(response.data?.message || "获取折扣信息失败");
    }
  } catch (error) {
    console.error('获取折扣列表失败:', error);
    throw error;
  }
};

export const getCurrentDiscount = async () => {
  try {
    const response = await api.get(`/discount/current`, {
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });
    
    if (response.data && response.data.code === 200) {
      // 更健壮的数据提取方式
      return response.data.data?.data || response.data.data || null;
    } else if (response.data?.message === "目前没有进行中的折扣") {
      return null;
    } else {
      throw new Error(response.data?.message || "获取当前折扣失败");
    }
  } catch (error) {
    console.error('获取当前折扣失败:', error);
    throw error;
  }
};

// 添加折扣
export const addDiscount = async (discountData) => {
  try {
    const response = await api.post(`/discount/add`, discountData, {
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });
    
    if (response.data && response.data.code === 200) {
      return response.data.data.data || response.data.data;
    } else {
      throw new Error(response.data?.message || "添加折扣失败");
    }
  } catch (error) {
    console.error('添加折扣失败:', error);
    throw error;
  }
};

// 删除折扣
export const deleteDiscount = async (id) => {
  try {
    const response = await api.delete(`/discount/delete/${id}`, {
      headers: {
        Authorization: localStorage.getItem('token')
      }
    });
    
    if (response.data && response.data.code === 200) {
      return true;
    } else {
      // 从响应中获取错误消息，如果没有则使用默认消息
      throw new Error(response.data?.message || "删除折扣失败");
    }
  } catch (error) {
    // 如果是axios错误且有响应数据，使用服务器返回的消息
    if (error.response && error.response.data) {
      throw new Error(error.response.data.message || "删除折扣失败");
    }
    // 否则使用axios错误消息或默认消息
    throw new Error(error.message || "删除折扣失败");
  }
};