/**
 * Nakama认证服务
 * 处理用户登录、注册、会话管理等功能
 */

import { Client, Session } from '@heroiclabs/nakama-js';

export interface LoginCredentials {
  email?: string;
  username?: string;
  password: string;
}

export interface RegisterCredentials {
  email: string;
  username: string;
  password: string;
  displayName?: string;
}

export interface UserProfile {
  id: string;
  username: string;
  displayName: string;
  email?: string;
  avatarUrl?: string;
  createTime: string;
  updateTime: string;
}

export interface AuthState {
  isAuthenticated: boolean;
  user: UserProfile | null;
  session: Session | null;
  loading: boolean;
  error: string | null;
}

class NakamaAuthService {
  private client: Client;
  private session: Session | null = null;
  private readonly SERVER_KEY = 'defaultkey'; // 替换为实际的服务器密钥
  private readonly HOST = '43.143.58.201'; // 替换为实际的Nakama服务器地址
  private readonly PORT = '7350'; // 替换为实际的端口
  private readonly USE_SSL = false; // 根据实际情况设置

  constructor() {
    this.client = new Client(this.SERVER_KEY, this.HOST, this.PORT, this.USE_SSL);
    this.loadStoredSession();
  }

  /**
   * 从本地存储加载会话
   */
  private loadStoredSession(): void {
    try {
      const storedSession = localStorage.getItem('nakama_session');
      if (storedSession) {
        const sessionData = JSON.parse(storedSession);
        this.session = Session.restore(
          sessionData.token,
          sessionData.refresh_token,
          sessionData.username,
          sessionData.user_id,
          sessionData.created,
          sessionData.expires_at,
          sessionData.vars
        );
        
        // 检查会话是否过期
        if (this.session.isexpired(Date.now() / 1000)) {
          this.refreshSession();
        }
      }
    } catch (error) {
      console.error('Failed to load stored session:', error);
      this.clearStoredSession();
    }
  }

  /**
   * 保存会话到本地存储
   */
  private saveSession(session: Session): void {
    try {
      const sessionData = {
        token: session.token,
        refresh_token: session.refresh_token,
        username: session.username,
        user_id: session.user_id,
        created: session.created,
        expires_at: session.expires_at,
        vars: session.vars
      };
      localStorage.setItem('nakama_session', JSON.stringify(sessionData));
      this.session = session;
    } catch (error) {
      console.error('Failed to save session:', error);
    }
  }

  /**
   * 清除本地存储的会话
   */
  private clearStoredSession(): void {
    localStorage.removeItem('nakama_session');
    this.session = null;
  }

  /**
   * 刷新会话
   */
  private async refreshSession(): Promise<void> {
    if (!this.session?.refresh_token) {
      throw new Error('No refresh token available');
    }

    try {
      const newSession = await this.client.sessionRefresh(this.session);
      this.saveSession(newSession);
    } catch (error) {
      console.error('Failed to refresh session:', error);
      this.clearStoredSession();
      throw error;
    }
  }

  /**
   * 用户登录
   */
  async login(credentials: LoginCredentials): Promise<UserProfile> {
    try {
      let session: Session;

      if (credentials.email) {
        // 邮箱登录
        session = await this.client.authenticateEmail(credentials.email, credentials.password);
      } else if (credentials.username) {
        // 用户名登录
        session = await this.client.authenticateUsername(credentials.username, credentials.password);
      } else {
        throw new Error('Email or username is required');
      }

      this.saveSession(session);

      // 获取用户信息
      const account = await this.client.getAccount(session);
      
      return {
        id: account.user?.id || '',
        username: account.user?.username || '',
        displayName: account.user?.display_name || account.user?.username || '',
        email: account.email,
        avatarUrl: account.user?.avatar_url,
        createTime: account.user?.create_time || '',
        updateTime: account.user?.update_time || ''
      };
    } catch (error) {
      console.error('Login failed:', error);
      throw new Error(this.getErrorMessage(error));
    }
  }

  /**
   * 用户注册
   */
  async register(credentials: RegisterCredentials): Promise<UserProfile> {
    try {
      const session = await this.client.authenticateEmail(
        credentials.email,
        credentials.password,
        true, // create account if not exists
        credentials.username,
        credentials.displayName
      );

      this.saveSession(session);

      // 获取用户信息
      const account = await this.client.getAccount(session);
      
      return {
        id: account.user?.id || '',
        username: account.user?.username || '',
        displayName: account.user?.display_name || credentials.displayName || credentials.username,
        email: account.email,
        avatarUrl: account.user?.avatar_url,
        createTime: account.user?.create_time || '',
        updateTime: account.user?.update_time || ''
      };
    } catch (error) {
      console.error('Registration failed:', error);
      throw new Error(this.getErrorMessage(error));
    }
  }

  /**
   * 用户登出
   */
  async logout(): Promise<void> {
    try {
      if (this.session) {
        await this.client.sessionLogout(this.session);
      }
    } catch (error) {
      console.error('Logout error:', error);
    } finally {
      this.clearStoredSession();
    }
  }

  /**
   * 获取当前用户信息
   */
  async getCurrentUser(): Promise<UserProfile | null> {
    if (!this.session) {
      return null;
    }

    try {
      // 检查会话是否过期
      if (this.session.isexpired(Date.now() / 1000)) {
        await this.refreshSession();
      }

      const account = await this.client.getAccount(this.session);
      
      return {
        id: account.user?.id || '',
        username: account.user?.username || '',
        displayName: account.user?.display_name || account.user?.username || '',
        email: account.email,
        avatarUrl: account.user?.avatar_url,
        createTime: account.user?.create_time || '',
        updateTime: account.user?.update_time || ''
      };
    } catch (error) {
      console.error('Failed to get current user:', error);
      this.clearStoredSession();
      return null;
    }
  }

  /**
   * 检查是否已登录
   */
  isAuthenticated(): boolean {
    return this.session !== null && !this.session.isexpired(Date.now() / 1000);
  }

  /**
   * 获取当前会话
   */
  getSession(): Session | null {
    return this.session;
  }

  /**
   * 更新用户资料
   */
  async updateProfile(updates: Partial<Pick<UserProfile, 'displayName' | 'avatarUrl'>>): Promise<void> {
    if (!this.session) {
      throw new Error('Not authenticated');
    }

    try {
      await this.client.updateAccount(this.session, {
        display_name: updates.displayName,
        avatar_url: updates.avatarUrl
      });
    } catch (error) {
      console.error('Failed to update profile:', error);
      throw new Error(this.getErrorMessage(error));
    }
  }

  /**
   * 修改密码
   */
  async changePassword(currentPassword: string, newPassword: string): Promise<void> {
    if (!this.session) {
      throw new Error('Not authenticated');
    }

    try {
      // 首先验证当前密码
      const account = await this.client.getAccount(this.session);
      if (account.email) {
        await this.client.authenticateEmail(account.email, currentPassword);
      }

      // 更新密码（这里需要根据Nakama的实际API调整）
      // Nakama可能需要通过其他方式更新密码
      console.warn('Password change not implemented - requires server-side function');
      throw new Error('Password change requires server-side implementation');
    } catch (error) {
      console.error('Failed to change password:', error);
      throw new Error(this.getErrorMessage(error));
    }
  }

  /**
   * 获取错误消息
   */
  private getErrorMessage(error: any): string {
    if (error?.message) {
      return error.message;
    }
    
    // 根据Nakama错误码返回友好的错误消息
    switch (error?.code) {
      case 3: // INVALID_ARGUMENT
        return '输入参数无效';
      case 5: // NOT_FOUND
        return '用户不存在';
      case 6: // ALREADY_EXISTS
        return '用户已存在';
      case 16: // UNAUTHENTICATED
        return '用户名或密码错误';
      default:
        return '操作失败，请稍后重试';
    }
  }
}

// 导出单例实例
export const nakamaAuth = new NakamaAuthService();
export default nakamaAuth;
