/**
 * Zulip用户注册服务
 *
 * 功能描述：
 * - 查询和验证Zulip用户信息
 * - 检查用户是否存在
 * - 获取用户详细信息
 * - 管理用户API Key（如果有权限）
 *
 * 职责分离：
 * - 用户创建层：处理新用户的账号创建
 * - 信息验证层：验证用户提供的注册信息
 * - API Key管理层：处理用户API Key的获取和管理
 *
 * 主要方法：
 * - checkUserExists(): 检查用户是否存在
 * - getUserInfo(): 获取用户详细信息
 * - validateUserCredentials(): 验证用户凭据
 * - getUserApiKey(): 获取用户API Key（需要管理员权限）
 *
 * 使用场景：
 * - 用户登录时验证用户存在性
 * - 获取用户基本信息
 * - 验证用户账户状态
 *
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 修正Core层业务流程描述，将"注册流程"改为"账号创建" (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 修正Core层业务概念描述，将"用户权限"改为"账户状态" (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 修正注释规范和修改记录格式 (修改者: moyin)
 * - 2026-01-10: 功能完善 - 添加用户注册和API Key管理功能 (修改者: moyin)
 * - 2026-01-07: 代码规范优化 - 更新import路径和注释规范 (修改者: moyin)
 *
 * @author moyin
 * @version 1.1.3
 * @since 2025-01-06
 * @lastModified 2026-01-12
 */

import { Injectable, Logger, Inject } from '@nestjs/common';
import { IZulipConfigService } from '../zulip_core.interfaces';
import {
  MAX_FULL_NAME_LENGTH,
  MAX_SHORT_NAME_LENGTH,
  MIN_FULL_NAME_LENGTH
} from '../../db/zulip_accounts/zulip_accounts.constants';

/**
 * Zulip API响应接口
 */
interface ZulipApiResponse {
  result?: 'success' | 'error';
  msg?: string;
  message?: string;
}

/**
 * 用户列表响应接口
 */
interface ZulipUsersResponse extends ZulipApiResponse {
  members?: Array<{
    email: string;
    user_id: number;
    full_name: string;
  }>;
}

/**
 * 创建用户响应接口
 */
interface ZulipCreateUserResponse extends ZulipApiResponse {
  user_id?: number;
}

/**
 * API Key响应接口
 */
interface ZulipApiKeyResponse extends ZulipApiResponse {
  api_key?: string;
}
export interface UserRegistrationRequest {
  email: string;
  fullName: string;
  password?: string;
  shortName?: string;
}

/**
 * 用户注册响应接口
 */
export interface UserRegistrationResponse {
  success: boolean;
  userId?: number;
  email?: string;
  apiKey?: string;
  error?: string;
  details?: any;
}

/**
 * Zulip用户注册服务类
 *
 * 职责：
 * - 处理新用户在Zulip服务器上的注册
 * - 验证用户信息的有效性
 * - 与Zulip API交互创建用户账户
 * - 管理账号创建和错误处理
 */
@Injectable()
export class UserRegistrationService {
  private readonly logger = new Logger(UserRegistrationService.name);

  constructor(
    @Inject('ZULIP_CONFIG_SERVICE')
    private readonly configService: IZulipConfigService,
  ) {
    this.logger.log('UserRegistrationService初始化完成');
  }

  /**
   * 注册新用户到Zulip服务器
   *
   * 功能描述：
   * 在Zulip服务器上创建新用户账户
   *
   * 技术实现：
   * 1. 验证用户注册信息
   * 2. 检查用户是否已存在
   * 3. 调用Zulip API创建用户
   * 4. 获取用户API Key
   * 5. 返回注册结果
   *
   * @param request 用户注册请求数据
   * @returns Promise<UserRegistrationResponse>
   */
  async registerUser(request: UserRegistrationRequest): Promise<UserRegistrationResponse> {
    const startTime = Date.now();

    this.logger.log('开始注册Zulip用户', {
      operation: 'registerUser',
      email: request.email,
      fullName: request.fullName,
      timestamp: new Date().toISOString(),
    });

    try {
      // 1. 验证用户注册信息
      const validationResult = this.validateUserInfo(request);
      if (!validationResult.valid) {
        this.logger.warn('用户注册信息验证失败', {
          operation: 'registerUser',
          email: request.email,
          errors: validationResult.errors,
        });

        return {
          success: false,
          error: validationResult.errors.join(', '),
        };
      }

      // 实现Zulip用户创建逻辑
      // 注意：这里实现了完整的用户账号创建，包括验证和错误处理

      // 2. 检查用户是否已存在
      const userExists = await this.checkUserExists(request.email);
      if (userExists) {
        this.logger.log('用户已存在，尝试绑定已有账号', {
          operation: 'registerUser',
          email: request.email,
        });

        // 尝试获取已有用户信息
        const userInfo = await this.getExistingUserInfo(request.email);
        if (userInfo.success) {
          // 尝试生成API Key（如果提供了密码）
          let apiKey = undefined;
          if (request.password) {
            const apiKeyResult = await this.generateApiKey(userInfo.userId!, request.email, request.password);
            if (apiKeyResult.success) {
              apiKey = apiKeyResult.apiKey;
            }
          }

          const duration = Date.now() - startTime;

          this.logger.log('Zulip用户绑定成功（已存在）', {
            operation: 'registerUser',
            email: request.email,
            userId: userInfo.userId,
            hasApiKey: !!apiKey,
            duration,
            timestamp: new Date().toISOString(),
          });

          return {
            success: true,
            userId: userInfo.userId,
            email: request.email,
            apiKey: apiKey,
          };
        } else {
          return {
            success: false,
            error: '用户已存在，但无法获取用户信息',
          };
        }
      }

      // 3. 调用Zulip API创建用户
      const createResult = await this.createZulipUser(request);
      if (!createResult.success) {
        return {
          success: false,
          error: createResult.error || '创建用户失败',
        };
      }

      // 4. 获取用户API Key（如果需要）
      let apiKey = undefined;
      if (createResult.userId) {
        const apiKeyResult = await this.generateApiKey(createResult.userId, request.email, request.password);
        if (apiKeyResult.success) {
          apiKey = apiKeyResult.apiKey;
        }
      }

      const duration = Date.now() - startTime;

      this.logger.log('Zulip用户注册完成（模拟）', {
        operation: 'registerUser',
        email: request.email,
        duration,
        timestamp: new Date().toISOString(),
      });

      return {
        success: true,
        userId: createResult.userId,
        email: request.email,
        apiKey: apiKey,
      };

    } catch (error) {
      const err = error as Error;
      const duration = Date.now() - startTime;

      this.logger.error('Zulip用户注册失败', {
        operation: 'registerUser',
        email: request.email,
        error: err.message,
        duration,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return {
        success: false,
        error: '注册失败，请稍后重试',
      };
    }
  }

  /**
   * 验证用户注册信息
   *
   * 功能描述：
   * 验证用户提供的注册信息是否有效
   *
   * @param request 用户注册请求
   * @returns {valid: boolean, errors: string[]} 验证结果
   * @private
   */
  private validateUserInfo(request: UserRegistrationRequest): {
    valid: boolean;
    errors: string[];
  } {
    const errors: string[] = [];

    // 验证邮箱
    if (!request.email || !request.email.trim()) {
      errors.push('邮箱不能为空');
    } else if (!this.isValidEmail(request.email)) {
      errors.push('邮箱格式无效');
    }

    // 验证全名
    if (!request.fullName || !request.fullName.trim()) {
      errors.push('用户全名不能为空');
    } else if (request.fullName.trim().length < MIN_FULL_NAME_LENGTH) {
      errors.push('用户全名至少需要2个字符');
    } else if (request.fullName.trim().length > MAX_FULL_NAME_LENGTH) {
      errors.push('用户全名不能超过100个字符');
    }

    // 验证密码（如果提供）
    if (request.password && request.password.length < 6) {
      errors.push('密码至少需要6个字符');
    }

    // 验证短名称（如果提供）
    if (request.shortName && request.shortName.trim().length > MAX_SHORT_NAME_LENGTH) {
      errors.push('短名称不能超过50个字符');
    }

    return {
      valid: errors.length === 0,
      errors,
    };
  }

  /**
   * 验证邮箱格式
   *
   * @param email 邮箱地址
   * @returns boolean 是否有效
   * @private
   */
  private isValidEmail(email: string): boolean {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  /**
   * 检查用户是否已存在
   *
   * 功能描述：
   * 通过Zulip API检查指定邮箱的用户是否已存在
   *
   * @param email 用户邮箱
   * @returns Promise<boolean> 是否存在
   * @private
   */
  private async checkUserExists(email: string): Promise<boolean> {
    this.logger.debug('检查用户是否存在', {
      operation: 'checkUserExists',
      email,
    });

    try {
      // 获取Zulip配置
      const config = this.configService.getZulipConfig();

      // 构建API URL
      const apiUrl = `${config.zulipServerUrl}/api/v1/users`;

      // 构建认证头
      const auth = Buffer.from(`${config.zulipBotEmail}:${config.zulipBotApiKey}`).toString('base64');

      // 发送请求
      const response = await fetch(apiUrl, {
        method: 'GET',
        headers: {
          'Authorization': `Basic ${auth}`,
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        this.logger.warn('获取用户列表失败', {
          operation: 'checkUserExists',
          status: response.status,
          statusText: response.statusText,
        });
        return false; // 如果API调用失败，假设用户不存在
      }

      const data: ZulipUsersResponse = await response.json();

      // 检查用户是否在列表中
      if (data.members && Array.isArray(data.members)) {
        const userExists = data.members.some((user: any) =>
          user.email && user.email.toLowerCase() === email.toLowerCase()
        );

        this.logger.debug('用户存在性检查完成', {
          operation: 'checkUserExists',
          email,
          exists: userExists,
        });

        return userExists;
      }

      return false;

    } catch (error) {
      const err = error as Error;
      this.logger.error('检查用户存在性失败', {
        operation: 'checkUserExists',
        email,
        error: err.message,
      });

      // 如果检查失败，假设用户不存在，允许继续注册
      return false;
    }
  }

  /**
   * 创建Zulip用户
   *
   * 功能描述：
   * 通过Zulip API创建新用户账户
   *
   * @param request 用户注册请求
   * @returns Promise<{success: boolean, userId?: number, error?: string}>
   * @private
   */
  private async createZulipUser(request: UserRegistrationRequest): Promise<{
    success: boolean;
    userId?: number;
    error?: string;
  }> {
    this.logger.log('开始创建Zulip用户', {
      operation: 'createZulipUser',
      email: request.email,
      fullName: request.fullName,
    });

    try {
      // 获取Zulip配置
      const config = this.configService.getZulipConfig();

      // 构建API URL
      const apiUrl = `${config.zulipServerUrl}/api/v1/users`;

      // 构建认证头
      const auth = Buffer.from(`${config.zulipBotEmail}:${config.zulipBotApiKey}`).toString('base64');

      // 构建请求体
      const requestBody = new URLSearchParams();
      requestBody.append('email', request.email);
      requestBody.append('full_name', request.fullName);

      if (request.password) {
        requestBody.append('password', request.password);
      }

      if (request.shortName) {
        requestBody.append('short_name', request.shortName);
      }

      // 发送请求
      const response = await fetch(apiUrl, {
        method: 'POST',
        headers: {
          'Authorization': `Basic ${auth}`,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: requestBody.toString(),
      });

      const data: ZulipCreateUserResponse = await response.json();

      if (!response.ok) {
        this.logger.warn('Zulip用户创建失败', {
          operation: 'createZulipUser',
          email: request.email,
          status: response.status,
          statusText: response.statusText,
          error: data.msg || data.message,
        });

        return {
          success: false,
          error: data.msg || data.message || '创建用户失败',
        };
      }

      this.logger.log('Zulip用户创建成功', {
        operation: 'createZulipUser',
        email: request.email,
        userId: data.user_id,
      });

      return {
        success: true,
        userId: data.user_id,
      };

    } catch (error) {
      const err = error as Error;
      this.logger.error('创建Zulip用户异常', {
        operation: 'createZulipUser',
        email: request.email,
        error: err.message,
      }, err.stack);

      return {
        success: false,
        error: '系统错误，请稍后重试',
      };
    }
  }

  /**
   * 获取已有用户信息
   *
   * 功能描述：
   * 获取Zulip服务器上已存在用户的详细信息
   *
   * @param email 用户邮箱
   * @returns Promise<{success: boolean, userId?: number, userInfo?: any, error?: string}> 用户信息
   * @private
   */
  private async getExistingUserInfo(email: string): Promise<{
    success: boolean;
    userId?: number;
    userInfo?: any;
    error?: string;
  }> {
    this.logger.debug('获取已有用户信息', {
      operation: 'getExistingUserInfo',
      email,
    });

    try {
      // 获取Zulip配置
      const config = this.configService.getZulipConfig();

      // 构建API URL
      const apiUrl = `${config.zulipServerUrl}/api/v1/users`;

      // 构建认证头
      const auth = Buffer.from(`${config.zulipBotEmail}:${config.zulipBotApiKey}`).toString('base64');

      // 发送请求
      const response = await fetch(apiUrl, {
        method: 'GET',
        headers: {
          'Authorization': `Basic ${auth}`,
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        this.logger.warn('获取用户列表失败', {
          operation: 'getExistingUserInfo',
          status: response.status,
          statusText: response.statusText,
        });
        return {
          success: false,
          error: '获取用户列表失败',
        };
      }

      const data: ZulipUsersResponse = await response.json();

      // 查找指定用户
      if (data.members && Array.isArray(data.members)) {
        const existingUser = data.members.find((user: any) =>
          user.email && user.email.toLowerCase() === email.toLowerCase()
        );

        if (existingUser) {
          this.logger.debug('找到已有用户信息', {
            operation: 'getExistingUserInfo',
            email,
            userId: existingUser.user_id,
            fullName: existingUser.full_name,
          });

          return {
            success: true,
            userId: existingUser.user_id,
            userInfo: existingUser,
          };
        } else {
          return {
            success: false,
            error: '用户不存在',
          };
        }
      }

      return {
        success: false,
        error: '无效的用户列表响应',
      };

    } catch (error) {
      const err = error as Error;
      this.logger.error('获取已有用户信息失败', {
        operation: 'getExistingUserInfo',
        email,
        error: err.message,
      });

      return {
        success: false,
        error: err.message,
      };
    }
  }

  /**
   * 为用户生成API Key
   *
   * 功能描述：
   * 为新创建的用户生成API Key，用于后续的Zulip API调用
   *
   * @param userId 用户ID
   * @param email 用户邮箱
   * @param password 用户密码（可选，用于已存在用户）
   * @returns Promise<{success: boolean, apiKey?: string, error?: string}>
   * @private
   */
  private async generateApiKey(userId: number, email: string, password?: string): Promise<{
    success: boolean;
    apiKey?: string;
    error?: string;
  }> {
    this.logger.log('开始生成用户API Key', {
      operation: 'generateApiKey',
      userId,
      email,
      hasPassword: !!password,
    });

    try {
      // 获取Zulip配置
      const config = this.configService.getZulipConfig();

      if (password) {
        // 使用用户密码直接获取API Key
        const apiUrl = `${config.zulipServerUrl}/api/v1/fetch_api_key`;

        // 构建请求体
        const requestBody = new URLSearchParams();
        requestBody.append('username', email);
        requestBody.append('password', password);

        // 发送请求
        const response = await fetch(apiUrl, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: requestBody.toString(),
        });

        const data: ZulipApiKeyResponse = await response.json();

        if (!response.ok) {
          this.logger.warn('通过密码获取API Key失败', {
            operation: 'generateApiKey',
            userId,
            email,
            status: response.status,
            statusText: response.statusText,
            error: data.msg || data.message,
          });

          return {
            success: false,
            error: data.msg || data.message || '获取API Key失败',
          };
        }

        this.logger.log('通过密码获取API Key成功', {
          operation: 'generateApiKey',
          userId,
          email,
        });

        return {
          success: true,
          apiKey: data.api_key,
        };
      } else {
        // 使用管理员权限生成API Key
        const apiUrl = `${config.zulipServerUrl}/api/v1/users/${userId}/api_key/regenerate`;

        // 构建认证头
        const auth = Buffer.from(`${config.zulipBotEmail}:${config.zulipBotApiKey}`).toString('base64');

        // 发送请求
        const response = await fetch(apiUrl, {
          method: 'POST',
          headers: {
            'Authorization': `Basic ${auth}`,
            'Content-Type': 'application/json',
          },
        });

        const data: ZulipApiKeyResponse = await response.json();

        if (!response.ok) {
          this.logger.warn('生成API Key失败', {
            operation: 'generateApiKey',
            userId,
            email,
            status: response.status,
            statusText: response.statusText,
            error: data.msg || data.message,
          });

          return {
            success: false,
            error: data.msg || data.message || '生成API Key失败',
          };
        }

        this.logger.log('API Key生成成功', {
          operation: 'generateApiKey',
          userId,
          email,
        });

        return {
          success: true,
          apiKey: data.api_key,
        };
      }

    } catch (error) {
      const err = error as Error;
      this.logger.error('生成API Key异常', {
        operation: 'generateApiKey',
        userId,
        email,
        error: err.message,
      }, err.stack);

      return {
        success: false,
        error: '系统错误，请稍后重试',
      };
    }
  }
}