import Taro from '@tarojs/taro';
import { ApiPath, ErrorCode } from '../constants';
import { User, Game, Room, TurtleSoupQuestion, ActionResult } from '../interfaces';

// API基础URL
const BASE_URL = 'https://api.linefunqueue.com';

// 请求方法枚举
enum Method {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  DELETE = 'DELETE',
}

// 请求配置接口
interface RequestConfig {
  url: string;
  method: Method;
  data?: any;
  header?: Record<string, string>;
}

/**
 * 发送请求的通用方法
 * @param config 请求配置
 * @returns Promise<T>
 */
const request = async <T>(config: RequestConfig): Promise<T> => {
  const token = Taro.getStorageSync('token');
  const header = {
    'Content-Type': 'application/json',
    ...(token ? { 'Authorization': `Bearer ${token}` } : {}),
    ...config.header,
  };

  try {
    const res = await Taro.request({
      url: `${BASE_URL}${config.url}`,
      method: config.method,
      data: config.data,
      header,
    });

    if (res.statusCode >= 200 && res.statusCode < 300) {
      return res.data as T;
    }

    // 处理状态码错误
    let errorCode: ErrorCode;
    switch (res.statusCode) {
      case 401:
        errorCode = ErrorCode.UNAUTHORIZED;
        // 清除token并跳转到登录页
        Taro.removeStorageSync('token');
        Taro.navigateTo({ url: '/pages/login/index' });
        break;
      case 404:
        errorCode = ErrorCode.NOT_FOUND;
        break;
      case 400:
        errorCode = ErrorCode.INVALID_PARAMS;
        break;
      default:
        errorCode = ErrorCode.SERVER_ERROR;
    }

    throw {
      code: errorCode,
      message: res.data?.message || '请求失败',
    };
  } catch (error) {
    if (error instanceof Error) {
      throw {
        code: ErrorCode.NETWORK_ERROR,
        message: error.message || '网络错误',
      };
    }
    throw error;
  }
};

/**
 * 登录并获取用户信息
 * @param code 微信登录凭证
 */
export const login = async (code: string): Promise<{ token: string; user: User }> => {
  return request({
    url: ApiPath.LOGIN,
    method: Method.POST,
    data: { code },
  });
};

/**
 * 获取用户信息
 * @param userId 用户ID
 */
export const getUserInfo = async (userId: string): Promise<User> => {
  return request({
    url: `${ApiPath.USERS}/${userId}`,
    method: Method.GET,
  });
};

/**
 * 更新用户信息
 * @param userId 用户ID
 * @param data 要更新的数据
 */
export const updateUserInfo = async (userId: string, data: Partial<User>): Promise<User> => {
  return request({
    url: `${ApiPath.USERS}/${userId}`,
    method: Method.PUT,
    data,
  });
};

/**
 * 获取游戏列表
 * @param params 查询参数
 */
export const getGames = async (params?: { category?: string; keyword?: string }): Promise<Game[]> => {
  return request({
    url: ApiPath.GAMES,
    method: Method.GET,
    data: params,
  });
};

/**
 * 获取游戏详情
 * @param gameId 游戏ID
 */
export const getGameDetail = async (gameId: string): Promise<Game> => {
  return request({
    url: `${ApiPath.GAMES}/${gameId}`,
    method: Method.GET,
  });
};

/**
 * 创建房间
 * @param data 房间数据
 */
export const createRoom = async (data: { gameId: string; maxPlayers: number; theme?: string; difficulty?: string }): Promise<Room> => {
  return request({
    url: ApiPath.ROOMS,
    method: Method.POST,
    data,
  });
};

/**
 * 加入房间
 * @param roomCode 房间码
 */
export const joinRoom = async (roomCode: string): Promise<Room> => {
  return request({
    url: `${ApiPath.ROOMS}/join`,
    method: Method.POST,
    data: { roomCode },
  });
};

/**
 * 获取房间信息
 * @param roomId 房间ID
 */
export const getRoomInfo = async (roomId: string): Promise<Room> => {
  return request({
    url: `${ApiPath.ROOMS}/${roomId}`,
    method: Method.GET,
  });
};

/**
 * 离开房间
 * @param roomId 房间ID
 */
export const leaveRoom = async (roomId: string): Promise<ActionResult> => {
  return request({
    url: `${ApiPath.ROOMS}/${roomId}/leave`,
    method: Method.POST,
  });
};

/**
 * 开始游戏
 * @param roomId 房间ID
 * @param data 游戏参数
 */
export const startGame = async (roomId: string, data?: any): Promise<ActionResult> => {
  return request({
    url: `${ApiPath.ROOMS}/${roomId}/start`,
    method: Method.POST,
    data,
  });
};

/**
 * 结束游戏
 * @param roomId 房间ID
 */
export const endGame = async (roomId: string): Promise<ActionResult> => {
  return request({
    url: `${ApiPath.ROOMS}/${roomId}/end`,
    method: Method.POST,
  });
};

/**
 * 处理游戏内操作
 * @param roomId 房间ID
 * @param data 操作数据
 */
export const gameAction = async (roomId: string, data: any): Promise<ActionResult> => {
  return request({
    url: `${ApiPath.ROOMS}/${roomId}/action`,
    method: Method.POST,
    data,
  });
};

/**
 * 获取海龟汤问题
 * @param params 查询参数
 */
export const getTurtleSoupQuestions = async (params?: { category?: string; difficulty?: number; isPremium?: boolean }): Promise<TurtleSoupQuestion[]> => {
  return request({
    url: `${ApiPath.GAMES}/turtle-soup/questions`,
    method: Method.GET,
    data: params,
  });
};

/**
 * 获取用户游戏历史
 * @param userId 用户ID
 */
export const getUserGameHistory = async (userId: string): Promise<Room[]> => {
  return request({
    url: `${ApiPath.USERS}/${userId}/history`,
    method: Method.GET,
  });
};

/**
 * 获取用户当前房间
 * @param userId 用户ID
 */
export const getUserCurrentRooms = async (userId: string): Promise<Room[]> => {
  return request({
    url: `${ApiPath.USERS}/${userId}/rooms`,
    method: Method.GET,
  });
};

export interface ApiResponse<T = any> {
  code: number;
  message: string;
  data?: T;
}

/**
 * 登录服务
 */
export const loginService = {
  /**
   * 登录或注册
   */
  login: async (): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'login',
        data: {}
      });
    } catch (error) {
      console.error('登录失败:', error);
      return {
        code: 500,
        message: '登录失败: ' + (error.message || error)
      };
    }
  },
};

/**
 * 房间服务
 */
export const roomService = {
  /**
   * 创建房间
   * @param gameType 游戏类型
   * @param maxPlayers 最大玩家数量
   */
  createRoom: async (gameType: string, maxPlayers: number = 8): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'create',
          gameType,
          maxPlayers
        }
      });
    } catch (error) {
      console.error('创建房间失败:', error);
      return {
        code: 500,
        message: '创建房间失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 加入房间
   * @param roomCode 房间号
   */
  joinRoom: async (roomCode: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'join',
          roomCode
        }
      });
    } catch (error) {
      console.error('加入房间失败:', error);
      return {
        code: 500,
        message: '加入房间失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 获取房间信息
   * @param roomId 房间ID
   * @param roomCode 房间号
   */
  getRoomInfo: async (roomId?: string, roomCode?: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'getRoomInfo',
          roomId,
          roomCode
        }
      });
    } catch (error) {
      console.error('获取房间信息失败:', error);
      return {
        code: 500,
        message: '获取房间信息失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 开始游戏
   * @param roomId 房间ID
   */
  startGame: async (roomId: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'startGame',
          roomId
        }
      });
    } catch (error) {
      console.error('开始游戏失败:', error);
      return {
        code: 500,
        message: '开始游戏失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 更新游戏数据
   * @param roomId 房间ID
   * @param gameData 游戏数据
   */
  updateGameData: async (roomId: string, gameData: any): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'updateGameData',
          roomId,
          gameData
        }
      });
    } catch (error) {
      console.error('更新游戏数据失败:', error);
      return {
        code: 500,
        message: '更新游戏数据失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 结束游戏
   * @param roomId 房间ID
   * @param gameResult 游戏结果
   */
  endGame: async (roomId: string, gameResult: any = {}): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'endGame',
          roomId,
          gameResult
        }
      });
    } catch (error) {
      console.error('结束游戏失败:', error);
      return {
        code: 500,
        message: '结束游戏失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 离开房间
   * @param roomId 房间ID
   */
  leaveRoom: async (roomId: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'room',
        data: {
          action: 'leaveRoom',
          roomId
        }
      });
    } catch (error) {
      console.error('离开房间失败:', error);
      return {
        code: 500,
        message: '离开房间失败: ' + (error.message || error)
      };
    }
  }
};

/**
 * 海龟汤游戏服务
 */
export const turtleSoupService = {
  /**
   * 获取随机题目
   */
  getRandomRiddle: async (): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'getRandomRiddle'
        }
      });
    } catch (error) {
      console.error('获取随机题目失败:', error);
      return {
        code: 500,
        message: '获取随机题目失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 根据ID获取题目
   * @param riddleId 题目ID
   */
  getRiddleById: async (riddleId: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'getRiddleById',
          riddleId
        }
      });
    } catch (error) {
      console.error('获取题目失败:', error);
      return {
        code: 500,
        message: '获取题目失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 初始化游戏数据
   * @param roomId 房间ID
   * @param riddleId 题目ID
   */
  initGameData: async (roomId: string, riddleId: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'initGameData',
          roomId,
          riddleId
        }
      });
    } catch (error) {
      console.error('初始化游戏数据失败:', error);
      return {
        code: 500,
        message: '初始化游戏数据失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 提交问题（玩家向主持人提问）
   * @param roomId 房间ID
   * @param question 问题内容
   */
  submitQuestion: async (roomId: string, question: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'submitQuestion',
          roomId,
          question
        }
      });
    } catch (error) {
      console.error('提交问题失败:', error);
      return {
        code: 500,
        message: '提交问题失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 回答问题（主持人回答玩家的问题）
   * @param roomId 房间ID
   * @param questionId 问题ID
   * @param answer 回答内容
   * @param status 答案状态，'answered'或'rejected'
   */
  answerQuestion: async (roomId: string, questionId: string, answer: string, status: 'answered' | 'rejected'): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'answerQuestion',
          roomId,
          questionId,
          answer,
          status
        }
      });
    } catch (error) {
      console.error('回答问题失败:', error);
      return {
        code: 500,
        message: '回答问题失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 提交线索（主持人提供线索）
   * @param roomId 房间ID
   * @param clue 线索内容
   */
  submitClue: async (roomId: string, clue: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'submitClue',
          roomId,
          clue
        }
      });
    } catch (error) {
      console.error('提交线索失败:', error);
      return {
        code: 500,
        message: '提交线索失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 提交答案（玩家尝试解答）
   * @param roomId 房间ID
   * @param answer 答案内容
   */
  submitAnswer: async (roomId: string, answer: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'submitAnswer',
          roomId,
          answer
        }
      });
    } catch (error) {
      console.error('提交答案失败:', error);
      return {
        code: 500,
        message: '提交答案失败: ' + (error.message || error)
      };
    }
  },

  /**
   * 揭晓答案（主持人揭晓答案）
   * @param roomId 房间ID
   */
  revealAnswer: async (roomId: string): Promise<ApiResponse> => {
    try {
      return await Taro.cloud.callFunction({
        name: 'turtleSoup',
        data: {
          action: 'revealAnswer',
          roomId
        }
      });
    } catch (error) {
      console.error('揭晓答案失败:', error);
      return {
        code: 500,
        message: '揭晓答案失败: ' + (error.message || error)
      };
    }
  }
}; 