// API服务 - 统一的后端数据接口
// 替换IndexedDB，使用后端SQLite数据库确保数据一致性

import type { SystemConfig, PrizeConfig, Student } from '../database/database';
import type { LotteryRecord } from '../types';

// 动态获取API基础URL，支持不同访问方式
const getApiBaseUrl = () => {
  if (process.env.NODE_ENV === 'production') {
    return '';
  }
  // 开发环境下，使用相对路径，通过Vite代理转发到后端
  const apiUrl = '';
  console.log('API Base URL:', apiUrl || 'relative path (via proxy)');
  return apiUrl;
};

const API_BASE_URL = getApiBaseUrl();

class ApiService {
  private static instance: ApiService;
  
  private constructor() {
    // 单例模式，构造函数私有
  }
  
  public static getInstance(): ApiService {
    if (!ApiService.instance) {
      ApiService.instance = new ApiService();
    }
    return ApiService.instance;
  }
  
  private activeRequests = new Map<string, AbortController>();

  private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
    const url = `/api${endpoint}`;
    console.log(`🌐 API请求: ${url}`);
    
    // 只在请求方法不同时才取消之前的请求，避免取消相同的GET请求
    const requestKey = `${endpoint}_${options.method || 'GET'}`;
    if (this.activeRequests.has(requestKey)) {
      const prevController = this.activeRequests.get(requestKey);
      if (prevController && (options.method && options.method !== 'GET')) {
        prevController.abort();
        console.log('🔄 取消之前的请求:', requestKey);
      }
    }
    
    // 创建新的 AbortController
    const controller = new AbortController();
    this.activeRequests.set(requestKey, controller);
    
    const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
    
    const config: RequestInit = {
      headers: {
        'Content-Type': 'application/json',
        ...options.headers,
      },
      signal: controller.signal,
      ...options,
    };
    
    try {
      // 检查网络连接状态
      if (!navigator.onLine) {
        clearTimeout(timeoutId);
        this.activeRequests.delete(endpoint);
        throw new Error('网络连接已断开，请检查网络设置');
      }
      
      const response = await fetch(url, config);
      clearTimeout(timeoutId);
      this.activeRequests.delete(requestKey);
      
      if (!response.ok) {
        let errorMessage = `HTTP ${response.status}`;
        
        switch (response.status) {
          case 404:
            errorMessage = 'API接口不存在，请检查后端服务器配置';
            break;
          case 500:
            errorMessage = '服务器内部错误，请稍后重试';
            break;
          case 503:
            errorMessage = '服务器暂时不可用，请稍后重试';
            break;
          case 0:
            errorMessage = '无法连接到服务器，请检查后端服务器是否运行';
            break;
          default:
            errorMessage = `请求失败 (${response.status}): ${response.statusText}`;
        }
        
        throw new Error(errorMessage);
      }
      
      const data = await response.json();
      
      if (data && data.error) {
        throw new Error(data.error);
      }
      
      console.log(`✅ API请求成功: ${endpoint}`);
      return data;
    } catch (error) {
      clearTimeout(timeoutId);
      this.activeRequests.delete(requestKey);
      console.error(`❌ API请求失败 ${endpoint}:`, error);
      
      // 处理取消的请求（不抛出错误）
      if (error instanceof Error && error.name === 'AbortError') {
        console.log('🚫 API请求已取消:', endpoint);
        throw new Error('请求已取消');
      }
      
      // 处理网络错误
      if (error instanceof TypeError && (error.message.includes('fetch') || error.message.includes('Failed to fetch'))) {
        throw new Error('无法连接到服务器，请确认后端服务器正在运行');
      }
      
      // 处理ERR_NETWORK错误
      if (error instanceof Error && error.message.includes('ERR_NETWORK')) {
        throw new Error('网络连接错误，请检查网络设置');
      }
      
      // 处理超时错误
      if (error instanceof Error && error.name === 'TimeoutError') {
        throw new Error('请求超时，请检查网络连接或稍后重试');
      }
      
      // 处理CORS错误
      if (error instanceof TypeError && error.message.includes('CORS')) {
        throw new Error('跨域请求被阻止，请检查服务器CORS配置');
      }
      
      // 确保错误对象有正确的结构
      if (error instanceof Error) {
        throw error;
      } else {
        throw new Error(String(error));
      }
    }
  }
  
  // 系统配置相关方法
  public async getSystemConfig(): Promise<SystemConfig | null> {
    const response = await this.request<{ success: boolean; data: SystemConfig | null }>('/system-config');
    return response.data;
  }
  
  public async updateSystemConfig(config: Partial<SystemConfig>): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/system-config', {
      method: 'PUT',
      body: JSON.stringify(config),
    });
    return result.success;
  }
  
  public async verifyAdminPassword(password: string): Promise<boolean> {
    try {
      const config = await this.getSystemConfig();
      return config ? config.admin_password === password : false;
    } catch (error) {
      console.error('验证管理员密码失败:', error);
      return false;
    }
  }
  
  public async changeAdminPassword(newPassword: string): Promise<boolean> {
    return this.updateSystemConfig({ admin_password: newPassword });
  }
  
  public async validateLoginPassword(password: string): Promise<boolean> {
    try {
      const config = await this.getSystemConfig();
      return config ? config.login_password === password : false;
    } catch (error) {
      console.error('验证登录密码失败:', error);
      return false;
    }
  }
  
  public async updateLoginPassword(newPassword: string): Promise<boolean> {
    return this.updateSystemConfig({ login_password: newPassword });
  }
  
  public async validateCurrentAdminPassword(password: string): Promise<boolean> {
    try {
      const config = await this.getSystemConfig();
      return config ? config.admin_password === password : false;
    } catch (error) {
      console.error('验证管理员密码失败:', error);
      return false;
    }
  }
  
  public async updateAdminPassword(newPassword: string): Promise<boolean> {
    return this.updateSystemConfig({ admin_password: newPassword });
  }
  
  // 奖项相关方法
  public async getAllPrizes(): Promise<PrizeConfig[]> {
    const response = await this.request<{ success: boolean; data: PrizeConfig[] }>('/prizes');
    return response.data || [];
  }
  
  public async addPrize(prize: Omit<PrizeConfig, 'id' | 'created_at'>): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/prizes', {
      method: 'POST',
      body: JSON.stringify(prize),
    });
    return result.success;
  }
  
  public async updatePrize(id: string, prize: Partial<PrizeConfig>): Promise<boolean> {
    const result = await this.request<{ success: boolean }>(`/prizes/${id}`, {
      method: 'PUT',
      body: JSON.stringify(prize),
    });
    return result.success;
  }
  
  public async deletePrize(id: string): Promise<boolean> {
    const result = await this.request<{ success: boolean }>(`/prizes/${id}`, {
      method: 'DELETE',
    });
    return result.success;
  }
  
  // 学生相关方法
  public async getStudent(studentId: string): Promise<Student | null> {
    return this.request<Student | null>(`/students/${studentId}`);
  }
  
  public async updateStudentDrawCount(studentId: string, drawCount: number): Promise<boolean> {
    const result = await this.request<{ success: boolean }>(`/students/${studentId}`, {
      method: 'PUT',
      body: JSON.stringify({ draw_count: drawCount }),
    });
    return result.success;
  }

  public async createOrUpdateStudent(studentId: string): Promise<boolean> {
    // 通过更新抽奖次数来创建或更新学生记录
    const student = await this.getStudent(studentId);
    const currentDrawCount = student ? student.draw_count + 1 : 1;
    return this.updateStudentDrawCount(studentId, currentDrawCount);
  }

  public async getStudentRecords(studentId: string): Promise<LotteryRecord[]> {
    // 从抽奖记录中筛选特定学生的记录
    const allRecords = await this.getAllRecords();
    return allRecords.filter(record => record.student_id === studentId);
  }

  public async updatePrizeQuantity(prizeId: string, quantity: number): Promise<boolean> {
    return this.updatePrize(prizeId, { remaining_quantity: quantity });
  }

  public async createLotteryRecord(studentId: string, prizeId: string, prizeName: string, prizeLevel: number): Promise<LotteryRecord> {
    const record = {
      student_id: studentId,
      prize_id: prizeId,
      prize_name: prizeName,
      prize_level: prizeLevel,
      is_synced: 1,
      cache_data: null
    };
    
    const result = await this.request<LotteryRecord>('/records', {
      method: 'POST',
      body: JSON.stringify(record),
    });
    return result;
  }
  
  // 抽奖记录相关方法
  public async getAllRecords(): Promise<LotteryRecord[]> {
    const response = await this.request<{ success: boolean; data: LotteryRecord[] }>('/records');
    return response.data || [];
  }
  
  public async getLotteryRecords(limit?: number): Promise<LotteryRecord[]> {
    const params = limit ? `?limit=${limit}` : '';
    return this.request<LotteryRecord[]>(`/records${params}`);
  }
  
  public async addRecord(record: Omit<LotteryRecord, 'id' | 'draw_time'>): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/records', {
      method: 'POST',
      body: JSON.stringify(record),
    });
    return result.success;
  }
  
  public async clearAllRecords(): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/records', {
      method: 'DELETE',
    });
    return result.success;
  }
  
  public async clearAllLotteryRecords(): Promise<boolean> {
    return this.clearAllRecords();
  }
  
  // 系统重置
  public async resetSystem(): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/reset', {
      method: 'POST',
    });
    return result.success;
  }
  
  public async resetSystemCompletely(): Promise<boolean> {
    return this.resetSystem();
  }
  
  // 密码重置方法
  public async resetAdminPasswordToDefault(): Promise<boolean> {
    return this.updateSystemConfig({ admin_password: '123456' });
  }
  
  public async resetLoginPasswordToDefault(): Promise<boolean> {
    return this.updateSystemConfig({ login_password: '123456' });
  }
  
  // 数据库重置
  public async forceResetDatabase(): Promise<boolean> {
    const result = await this.request<{ success: boolean }>('/force-reset', {
      method: 'POST',
    });
    return result.success;
  }
  
  // 模拟抽奖
  public async simulateLottery(times: number): Promise<any> {
    const result = await this.request<any>('/simulate', {
      method: 'POST',
      body: JSON.stringify({ times }),
    });
    return result;
  }
  
  // 抽奖逻辑
  public async drawPrize(studentId: string): Promise<{ prize: PrizeConfig; record: LotteryRecord } | null> {
    try {
      // 获取学生信息
      const student = await this.getStudent(studentId);
      const config = await this.getSystemConfig();
      
      if (!config) {
        throw new Error('系统配置未找到');
      }
      
      // 检查抽奖次数限制
      const currentDrawCount = student ? student.draw_count : 0;
      if (currentDrawCount >= config.max_draw_times) {
        throw new Error('已达到最大抽奖次数');
      }
      
      // 获取可用奖项
      const prizes = await this.getAllPrizes();
      const availablePrizes = prizes.filter(p => p.is_active && p.remaining_quantity > 0);
      
      if (availablePrizes.length === 0) {
        throw new Error('没有可用的奖项');
      }
      
      // 抽奖算法
      const random = Math.random();
      let cumulativeProbability = 0;
      let selectedPrize: PrizeConfig | null = null;
      
      for (const prize of availablePrizes) {
        cumulativeProbability += prize.probability;
        if (random <= cumulativeProbability) {
          selectedPrize = prize;
          break;
        }
      }
      
      // 如果没有选中任何奖项，选择最后一个（通常是谢谢参与）
      if (!selectedPrize) {
        selectedPrize = availablePrizes[availablePrizes.length - 1];
      }
      
      // 更新奖项剩余数量
      await this.updatePrize(selectedPrize.id, {
        remaining_quantity: selectedPrize.remaining_quantity - 1
      });
      
      // 更新学生抽奖次数
      await this.updateStudentDrawCount(studentId, currentDrawCount + 1);
      
      // 创建抽奖记录
      const record: Omit<LotteryRecord, 'id' | 'draw_time'> = {
        student_id: studentId,
        prize_id: selectedPrize.id,
        prize_name: selectedPrize.prize_name,
        prize_level: selectedPrize.prize_level,
        is_synced: 1,
        cache_data: null
      };
      
      await this.addRecord(record);
      
      // 返回完整的记录对象
      const fullRecord: LotteryRecord = {
        ...record,
        id: this.generateId(),
        draw_time: new Date().toISOString()
      };
      
      return {
        prize: {
          ...selectedPrize,
          remaining_quantity: selectedPrize.remaining_quantity - 1
        },
        record: fullRecord
      };
      
    } catch (error) {
      console.error('抽奖失败:', error);
      throw error;
    }
  }
  
  private generateId(): string {
    return Math.random().toString(36).substr(2, 9) + Date.now().toString(36);
  }
  
  // 清理方法，防止内存泄漏
  public cleanup(): void {
    // 取消所有活跃的请求
    this.activeRequests.forEach((controller, requestKey) => {
      controller.abort();
      console.log('🧹 清理请求:', requestKey);
    });
    this.activeRequests.clear();
  }
  
  // 获取活跃请求数量（用于调试）
  public getActiveRequestsCount(): number {
    return this.activeRequests.size;
  }
}

export default ApiService;
export { PrizeConfig, SystemConfig, LotteryRecord, Student };