import { jwtDecode } from 'jwt-decode';

// JWT payload 接口
interface JWTPayload {
  userId: string;
  exp: number;
  iat: number;
}

// 认证服务类
class AuthService {
  private static instance: AuthService;
  private readonly TOKEN_KEY = 'lottery_auth_token';
  private readonly SECRET_KEY = 'lottery_secret_2025'; // 在生产环境中应该使用环境变量

  private constructor() {}

  public static getInstance(): AuthService {
    if (!AuthService.instance) {
      AuthService.instance = new AuthService();
    }
    return AuthService.instance;
  }

  // 简单的JWT生成（客户端实现，仅用于演示）
  private generateToken(userId: string): string {
    const header = {
      alg: 'HS256',
      typ: 'JWT'
    };

    const payload = {
      userId,
      exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), // 24小时过期
      iat: Math.floor(Date.now() / 1000)
    };

    // 简化的JWT实现（生产环境应使用专业库）
    const encodedHeader = btoa(JSON.stringify(header));
    const encodedPayload = btoa(JSON.stringify(payload));
    const signature = btoa(`${encodedHeader}.${encodedPayload}.${this.SECRET_KEY}`);
    
    return `${encodedHeader}.${encodedPayload}.${signature}`;
  }

  // 验证token
  private verifyToken(token: string): JWTPayload | null {
    try {
      const parts = token.split('.');
      if (parts.length !== 3) {
        return null;
      }

      const payload = JSON.parse(atob(parts[1]));
      
      // 检查过期时间
      if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
        console.log('Token已过期');
        return null;
      }

      return payload as JWTPayload;
    } catch (error) {
      console.error('Token验证失败:', error);
      return null;
    }
  }

  // 登录并生成token
  public async login(password: string): Promise<{ success: boolean; token?: string }> {
    try {
      // 调用API服务验证密码
      const apiServiceModule = await import('./apiService');
      const ApiService = apiServiceModule.default;
      const apiService = ApiService.getInstance();
      const isValid = await apiService.validateLoginPassword(password);
      
      if (isValid) {
        const userId = 'admin';
        const token = this.generateToken(userId);
        
        // 存储token到localStorage
        localStorage.setItem(this.TOKEN_KEY, token);
        
        console.log('登录成功，token已生成并存储');
        return { success: true, token };
      }
      
      console.log('登录失败：密码不正确');
      return { success: false };
    } catch (error) {
      console.error('登录验证过程中发生错误:', error);
      return { success: false };
    }
  }

  // 检查是否已登录
  public isAuthenticated(): boolean {
    const token = this.getToken();
    if (!token) {
      return false;
    }

    const payload = this.verifyToken(token);
    return payload !== null;
  }

  // 获取存储的token
  public getToken(): string | null {
    return localStorage.getItem(this.TOKEN_KEY);
  }

  // 获取用户信息
  public getUserInfo(): { userId: string } | null {
    const token = this.getToken();
    if (!token) {
      return null;
    }

    const payload = this.verifyToken(token);
    if (!payload) {
      return null;
    }

    return { userId: payload.userId };
  }

  // 登出
  public logout(): void {
    localStorage.removeItem(this.TOKEN_KEY);
    console.log('已登出，token已清除');
  }

  // 刷新token（延长有效期）
  public refreshToken(): boolean {
    const currentToken = this.getToken();
    if (!currentToken) {
      return false;
    }

    const payload = this.verifyToken(currentToken);
    if (!payload) {
      return false;
    }

    // 如果token还有效，生成新的token
    const newToken = this.generateToken(payload.userId);
    localStorage.setItem(this.TOKEN_KEY, newToken);
    
    console.log('Token已刷新');
    return true;
  }

  // 检查token是否即将过期（1小时内）
  public isTokenExpiringSoon(): boolean {
    const token = this.getToken();
    if (!token) {
      return false;
    }

    const payload = this.verifyToken(token);
    if (!payload) {
      return true; // token无效，视为即将过期
    }

    const oneHourFromNow = Math.floor(Date.now() / 1000) + (60 * 60);
    return payload.exp < oneHourFromNow;
  }

  // 自动刷新token（如果即将过期）
  public autoRefreshToken(): void {
    if (this.isTokenExpiringSoon() && this.isAuthenticated()) {
      this.refreshToken();
    }
  }

  // 处理token过期的回调
  private onTokenExpired?: () => void;
  private tokenMonitorInterval?: NodeJS.Timeout;

  // 设置token过期回调
  public setTokenExpiredCallback(callback: () => void): void {
    this.onTokenExpired = callback;
  }

  // 检查token并处理过期
  public checkTokenAndHandleExpiry(): boolean {
    const token = this.getToken();
    if (!token) {
      this.handleTokenExpired();
      return false;
    }

    const payload = this.verifyToken(token);
    if (!payload) {
      this.handleTokenExpired();
      return false;
    }

    // 如果token即将过期，尝试刷新
    if (this.isTokenExpiringSoon()) {
      const refreshed = this.refreshToken();
      if (!refreshed) {
        this.handleTokenExpired();
        return false;
      }
    }

    return true;
  }

  // 处理token过期
  private handleTokenExpired(): void {
    console.log('Token已过期，清除认证状态');
    this.logout();
    
    if (this.onTokenExpired) {
      this.onTokenExpired();
    }
  }

  // 启动token监控
  public startTokenMonitoring(): void {
    // 清理之前的定时器
    this.stopTokenMonitoring();
    
    // 每分钟检查一次token状态
    this.tokenMonitorInterval = setInterval(() => {
      if (this.getToken()) {
        this.checkTokenAndHandleExpiry();
      }
    }, 60 * 1000); // 1分钟
  }
  
  // 停止token监控
  public stopTokenMonitoring(): void {
    if (this.tokenMonitorInterval) {
      clearInterval(this.tokenMonitorInterval);
      this.tokenMonitorInterval = undefined;
    }
  }

  // 获取token剩余有效时间（秒）
  public getTokenRemainingTime(): number {
    const token = this.getToken();
    if (!token) {
      return 0;
    }

    const payload = this.verifyToken(token);
    if (!payload) {
      return 0;
    }

    const now = Math.floor(Date.now() / 1000);
    return Math.max(0, payload.exp - now);
  }
  
  // 清理方法，防止内存泄漏
  public cleanup(): void {
    this.stopTokenMonitoring();
    this.onTokenExpired = undefined;
    console.log('🧹 AuthService 已清理');
  }
}

export { AuthService };
export default AuthService;