﻿/**
 * BilibiliServer API SDK
 * 用于其他项目调用本项目的接口
 */

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios';

// API 响应类型定义
export interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  error?: string;
  message?: string;
  pagination?: {
    total: number;
    limit: number;
    offset: number;
    hasMore: boolean;
  };
}

// SDK 配置选项
export interface SdkConfig {
  baseURL: string;
  adminSecret?: string;
  timeout?: number;
  onError?: (error: ApiError) => void;
  onRequest?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
  onResponse?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;
}

// 自定义错误类
export class ApiError extends Error {
  constructor(
    message: string,
    public statusCode?: number,
    public response?: any,
    public originalError?: AxiosError
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

// 参数校验工具
export class Validator {
  static required(value: any, fieldName: string): void {
    if (value === undefined || value === null || value === '') {
      throw new ApiError(`${fieldName} 是必填参数`);
    }
  }

  static isNumber(value: any, fieldName: string): void {
    if (value !== undefined && value !== null && isNaN(Number(value))) {
      throw new ApiError(`${fieldName} 必须是数字`);
    }
  }

  static isString(value: any, fieldName: string): void {
    if (value !== undefined && value !== null && typeof value !== 'string') {
      throw new ApiError(`${fieldName} 必须是字符串`);
    }
  }

  static minLength(value: string, length: number, fieldName: string): void {
    if (value && value.length < length) {
      throw new ApiError(`${fieldName} 最少需要 ${length} 个字符`);
    }
  }

  static maxLength(value: string, length: number, fieldName: string): void {
    if (value && value.length > length) {
      throw new ApiError(`${fieldName} 最多 ${length} 个字符`);
    }
  }

  static isInRange(value: number, min: number, max: number, fieldName: string): void {
    if (value !== undefined && value !== null && (value < min || value > max)) {
      throw new ApiError(`${fieldName} 必须在 ${min} 到 ${max} 之间`);
    }
  }

  static isEmail(value: string, fieldName: string): void {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (value && !emailRegex.test(value)) {
      throw new ApiError(`${fieldName} 格式不正确`);
    }
  }

  static isUrl(value: string, fieldName: string): void {
    try {
      if (value) new URL(value);
    } catch {
      throw new ApiError(`${fieldName} 必须是有效的 URL`);
    }
  }
}

// 主要 SDK 类
export class BilibiliServerSDK {
  private client: AxiosInstance;
  private config: SdkConfig;

  // 用户相关 API
  public users: UserAPI;
  public products: ProductAPI;
  public items: ItemAPI;
  public orders: OrderAPI;
  public checkins: CheckInAPI;
  public points: PointsAPI;
  public gifts: GiftAPI;
  public rooms: RoomAPI;
  public admin: AdminAPI;

  constructor(config: SdkConfig) {
    this.config = {
      timeout: 30000,
      ...config,
    };

    this.client = axios.create({
      baseURL: this.config.baseURL,
      timeout: this.config.timeout,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    // 请求拦截器
    this.client.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 添加 adminSecret 到请求参数（如果是 GET 请求）
        if (this.config.adminSecret) {
          if (config.method?.toLowerCase() === 'get') {
            config.params = { ...config.params, adminSecret: this.config.adminSecret };
          }
        }
        
        // 调用自定义请求拦截
        if (this.config.onRequest) {
          return this.config.onRequest(config);
        }
        return config;
      },
      (error) => Promise.reject(error)
    );

    // 响应拦截器
    this.client.interceptors.response.use(
      (response) => {
        if (this.config.onResponse) {
          return this.config.onResponse(response);
        }
        return response;
      },
      (error: AxiosError) => {
        const apiError = this.handleError(error);
        if (this.config.onError) {
          this.config.onError(apiError);
        }
        return Promise.reject(apiError);
      }
    );

    // 初始化各模块 API
    this.users = new UserAPI(this.client, this.config);
    this.products = new ProductAPI(this.client, this.config);
    this.items = new ItemAPI(this.client, this.config);
    this.orders = new OrderAPI(this.client, this.config);
    this.checkins = new CheckInAPI(this.client, this.config);
    this.points = new PointsAPI(this.client, this.config);
    this.gifts = new GiftAPI(this.client, this.config);
    this.rooms = new RoomAPI(this.client, this.config);
    this.admin = new AdminAPI(this.client, this.config);
  }

  private handleError(error: AxiosError): ApiError {
    if (error.response) {
      const data = error.response.data as any;
      return new ApiError(
        data?.error || data?.message || '请求失败',
        error.response.status,
        data,
        error
      );
    }
    if (error.request) {
      return new ApiError('网络错误，请检查连接', undefined, undefined, error);
    }
    return new ApiError(error.message, undefined, undefined, error);
  }

  // 设置认证 Token
  setToken(token: string): void {
    this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
  }

  // 清除认证 Token
  clearToken(): void {
    delete this.client.defaults.headers.common['Authorization'];
  }
}

// 基础 API 类
abstract class BaseAPI {
  constructor(protected client: AxiosInstance, protected config: SdkConfig) {}

  protected getAdminSecret(): string | undefined {
    return this.config.adminSecret;
  }

  protected async get<T>(url: string, params?: any): Promise<ApiResponse<T>> {
    const response = await this.client.get(url, { params });
    return response.data;
  }

  protected async post<T>(url: string, data?: any): Promise<ApiResponse<T>> {
    const body = this.config.adminSecret ? { ...data, adminSecret: this.config.adminSecret } : data;
    const response = await this.client.post(url, body);
    return response.data;
  }

  protected async put<T>(url: string, data?: any): Promise<ApiResponse<T>> {
    const body = this.config.adminSecret ? { ...data, adminSecret: this.config.adminSecret } : data;
    const response = await this.client.put(url, body);
    return response.data;
  }

  protected async deleteRequest<T>(url: string): Promise<ApiResponse<T>> {
    const response = await this.client.delete(url, {
      params: this.config.adminSecret ? { adminSecret: this.config.adminSecret } : undefined,
    });
    return response.data;
  }
}

// 用户 API
class UserAPI extends BaseAPI {
  // 获取用户列表
  async list(options?: { limit?: number; offset?: number; search?: string }): Promise<ApiResponse> {
    if (options?.limit) Validator.isInRange(options.limit, 1, 1000, 'limit');
    if (options?.offset) Validator.isNumber(options.offset, 'offset');
    
    return this.get('/api/users', options);
  }

  // 获取单个用户详情
  async getById(userId: number): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.isNumber(userId, 'userId');
    
    return this.get(`/api/users/${userId}`);
  }

  // 创建用户
  async create(data: {
    uid: string;
    username: string;
    avatar?: string;
    level?: number;
  }): Promise<ApiResponse> {
    Validator.required(data.uid, 'uid');
    Validator.required(data.username, 'username');
    Validator.minLength(data.username, 1, 'username');
    Validator.maxLength(data.username, 100, 'username');
    
    return this.post('/api/users', data);
  }

  // 更新用户
  async update(userId: number, data: {
    username?: string;
    avatar?: string;
    level?: number;
    totalPoints?: number;
  }): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.isNumber(userId, 'userId');
    
    return this.put(`/api/users/${userId}`, data);
  }

  // 删除用户
  async delete(userId: number): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.isNumber(userId, 'userId');
    
    return this.deleteRequest(`/api/users/${userId}`);
  }

  // 获取用户统计
  async getStats(userId: number): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.isNumber(userId, 'userId');
    
    return this.get(`/api/users/${userId}/stats`);
  }
}

// 商品 API
class ProductAPI extends BaseAPI {
  // 获取商品列表
  async list(): Promise<ApiResponse> {
    return this.get('/api/shop/products');
  }

  // 获取单个商品
  async getById(productId: number): Promise<ApiResponse> {
    Validator.required(productId, 'productId');
    Validator.isNumber(productId, 'productId');
    
    return this.get(`/api/shop/products/${productId}`);
  }

  // 创建商品
  async create(data: {
    productId: string;
    name: string;
    description?: string;
    price: number;
    stock?: number | null;
    isOnSale?: boolean;
  }): Promise<ApiResponse> {
    Validator.required(data.productId, 'productId');
    Validator.required(data.name, 'name');
    Validator.required(data.price, 'price');
    Validator.isNumber(data.price, 'price');
    Validator.isInRange(data.price, 0, Infinity, 'price');
    
    return this.post('/api/shop/products', data);
  }

  // 更新商品
  async update(productId: number, data: {
    name?: string;
    description?: string;
    price?: number;
    stock?: number | null;
    isOnSale?: boolean;
  }): Promise<ApiResponse> {
    Validator.required(productId, 'productId');
    Validator.isNumber(productId, 'productId');
    
    return this.put(`/api/shop/products/${productId}`, data);
  }

  // 删除商品
  async delete(productId: number): Promise<ApiResponse> {
    Validator.required(productId, 'productId');
    Validator.isNumber(productId, 'productId');
    
    return this.deleteRequest(`/api/shop/products/${productId}`);
  }
}

// 道具 API
class ItemAPI extends BaseAPI {
  // 获取道具列表
  async list(options?: { type?: string; isOnSale?: boolean }): Promise<ApiResponse> {
    return this.get('/api/items', options);
  }

  // 创建道具
  async create(data: {
    itemId: string;
    name: string;
    type: 'VOUCHER' | 'BADGE' | 'SPECIAL';
    description?: string;
    iconUrl?: string;
    price?: number;
    stock?: number | null;
    config?: string;
    isOnSale?: boolean;
  }): Promise<ApiResponse> {
    Validator.required(data.itemId, 'itemId');
    Validator.required(data.name, 'name');
    Validator.required(data.type, 'type');
    
    const validTypes = ['VOUCHER', 'BADGE', 'SPECIAL'];
    if (!validTypes.includes(data.type)) {
      throw new ApiError(`type 必须是以下之一: ${validTypes.join(', ')}`);
    }
    
    return this.post('/api/items', data);
  }

  // 更新道具
  async update(itemId: number, data: {
    name?: string;
    type?: 'VOUCHER' | 'BADGE' | 'SPECIAL';
    description?: string;
    iconUrl?: string;
    price?: number;
    stock?: number | null;
    config?: string;
    isOnSale?: boolean;
  }): Promise<ApiResponse> {
    Validator.required(itemId, 'itemId');
    Validator.isNumber(itemId, 'itemId');
    
    return this.put(`/api/items/${itemId}`, data);
  }

  // 删除道具
  async delete(itemId: number): Promise<ApiResponse> {
    Validator.required(itemId, 'itemId');
    Validator.isNumber(itemId, 'itemId');
    
    return this.deleteRequest(`/api/items/${itemId}`);
  }
}

// 订单 API
class OrderAPI extends BaseAPI {
  // 获取订单列表
  async list(options?: { userId?: number; limit?: number; offset?: number }): Promise<ApiResponse> {
    if (options?.limit) Validator.isInRange(options.limit, 1, 1000, 'limit');
    if (options?.offset) Validator.isNumber(options.offset, 'offset');
    if (options?.userId) Validator.isNumber(options.userId, 'userId');
    
    return this.get('/api/shop/orders', options);
  }

  // 创建订单（购买）
  async create(data: {
    userId: number;
    productId: number;
    quantity?: number;
  }): Promise<ApiResponse> {
    Validator.required(data.userId, 'userId');
    Validator.required(data.productId, 'productId');
    Validator.isNumber(data.userId, 'userId');
    Validator.isNumber(data.productId, 'productId');
    
    if (data.quantity !== undefined) {
      Validator.isNumber(data.quantity, 'quantity');
      Validator.isInRange(data.quantity, 1, 1000, 'quantity');
    }
    
    return this.post('/api/shop/orders', data);
  }

  // 删除订单
  async delete(orderId: number): Promise<ApiResponse> {
    Validator.required(orderId, 'orderId');
    Validator.isNumber(orderId, 'orderId');
    
    return this.deleteRequest(`/api/shop/orders/${orderId}`);
  }
}

// 签到 API
class CheckInAPI extends BaseAPI {
  // 触发签到统计
  async trigger(date?: string): Promise<ApiResponse> {
    return this.post('/api/checkin', {
      date: date || new Date().toISOString().split('T')[0],
      secret: this.getAdminSecret(),
    });
  }

  // 执行签到
  async checkIn(userId: number): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.isNumber(userId, 'userId');
    
    return this.post('/api/checkin/do', { userId });
  }

  // 补签
  async makeUp(userId: number, date: string): Promise<ApiResponse> {
    Validator.required(userId, 'userId');
    Validator.required(date, 'date');
    Validator.isNumber(userId, 'userId');
    
    return this.post('/api/checkin/makeup', { userId, date });
  }
}

// 积分 API
class PointsAPI extends BaseAPI {
  // 调整用户积分
  async adjust(data: {
    userId: number;
    points: number;
    description: string;
  }): Promise<ApiResponse> {
    Validator.required(data.userId, 'userId');
    Validator.required(data.points, 'points');
    Validator.required(data.description, 'description');
    Validator.isNumber(data.userId, 'userId');
    Validator.isNumber(data.points, 'points');
    Validator.minLength(data.description, 1, 'description');
    
    return this.post('/api/points', data);
  }

  // 获取积分记录
  async getRecords(options?: { userId?: number; limit?: number; offset?: number }): Promise<ApiResponse> {
    return this.get('/api/points/records', options);
  }
}

// 礼物 API
class GiftAPI extends BaseAPI {
  // 获取礼物记录
  async list(options?: { userId?: number; roomId?: number; limit?: number; offset?: number }): Promise<ApiResponse> {
    if (options?.limit) Validator.isInRange(options.limit, 1, 1000, 'limit');
    
    return this.get('/api/gifts', options);
  }

  // 获取礼物类型列表
  async getTypes(): Promise<ApiResponse> {
    return this.get('/api/gifts/types');
  }
}

// 直播间 API
class RoomAPI extends BaseAPI {
  // 获取直播间列表
  async list(): Promise<ApiResponse> {
    return this.get('/api/rooms');
  }

  // 获取直播间统计
  async getStats(roomId: number): Promise<ApiResponse> {
    Validator.required(roomId, 'roomId');
    Validator.isNumber(roomId, 'roomId');
    
    return this.get(`/api/stats/rooms/${roomId}`);
  }
}

// 管理员 API
class AdminAPI extends BaseAPI {
  // 管理员登录
  async login(username: string, password: string): Promise<ApiResponse> {
    Validator.required(username, 'username');
    Validator.required(password, 'password');
    
    return this.post('/api/auth/admin/login', { username, password });
  }

  // 获取当前管理员信息
  async getMe(): Promise<ApiResponse> {
    return this.get('/api/auth/admin/me');
  }
}

// 默认导出
export default BilibiliServerSDK;

// 命名导出
export { BilibiliServerSDK as SDK };
