import { Injectable, Logger, ConflictException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../entities/User';
import { v4 as uuidv4 } from 'uuid';
import * as bcrypt from 'bcrypt';
import { MailService } from '../../core/mail/MailService';

@Injectable()
export class RegistrationService {
  private readonly logger = new Logger(RegistrationService.name);

  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private mailService: MailService,
  ) {}

  /**
   * 注册新用户
   * @param username 用户名
   * @param email 邮箱
   * @param password 密码
   * @param companyName 公司名称
   * @param phone 电话
   * @param businessType 业务类型
   * @returns 注册结果
   */
  async register(
    username: string,
    email: string,
    password: string,
    companyName: string,
    phone: string,
    businessType: string,
  ): Promise<{ userId: string; verificationToken: string }> {
    try {
      // 检查用户名是否已存在
      const existingUser = await this.userRepository.findOne({
        where: [{ username }, { email }],
      });

      if (existingUser) {
        if (existingUser.username === username) {
          throw new ConflictException('Username already exists');
        } else {
          throw new ConflictException('Email already exists');
        }
      }

      // 加密密码
      const hashedPassword = await bcrypt.hash(password, 10);
      const verificationToken = uuidv4();

      // 创建用户
      const user = this.userRepository.create({
        id: uuidv4(),
        username,
        email,
        password: hashedPassword,
        companyName,
        phone,
        businessType,
        verificationToken,
        isVerified: false,
        createdAt: new Date(),
        updatedAt: new Date(),
      });

      await this.userRepository.save(user);

      // 发送验证邮件
      await this.mailService.sendVerificationEmail(email, verificationToken);

      this.logger.log(`Registered new user: ${username} (${email})`);
      return { userId: user.id, verificationToken };
    } catch (error) {
      this.logger.error('Failed to register user', error);
      throw error;
    }
  }

  /**
   * 验证用户邮箱
   * @param token 验证令牌
   * @returns 验证结果
   */
  async verifyEmail(token: string): Promise<boolean> {
    try {
      const user = await this.userRepository.findOne({
        where: { verificationToken: token },
      });

      if (!user) {
        throw new BadRequestException('Invalid verification token');
      }

      if (user.isVerified) {
        throw new BadRequestException('Email already verified');
      }

      user.isVerified = true;
      user.verificationToken = null;
      user.updatedAt = new Date();

      await this.userRepository.save(user);

      this.logger.log(`Verified email for user: ${user.username}`);
      return true;
    } catch (error) {
      this.logger.error('Failed to verify email', error);
      throw error;
    }
  }

  /**
   * 重发验证邮件
   * @param email 邮箱
   * @returns 发送结果
   */
  async resendVerificationEmail(email: string): Promise<boolean> {
    try {
      const user = await this.userRepository.findOne({
        where: { email },
      });

      if (!user) {
        throw new BadRequestException('User not found');
      }

      if (user.isVerified) {
        throw new BadRequestException('Email already verified');
      }

      const newToken = uuidv4();
      user.verificationToken = newToken;
      user.updatedAt = new Date();

      await this.userRepository.save(user);
      await this.mailService.sendVerificationEmail(email, newToken);

      this.logger.log(`Resent verification email to: ${email}`);
      return true;
    } catch (error) {
      this.logger.error('Failed to resend verification email', error);
      throw error;
    }
  }

  /**
   * 获取用户信息
   * @param userId 用户ID
   * @returns 用户信息
   */
  async getUserInfo(userId: string): Promise<User> {
    try {
      const user = await this.userRepository.findOne({
        where: { id: userId },
        select: ['id', 'username', 'email', 'companyName', 'phone', 'businessType', 'isVerified', 'createdAt'],
      });

      if (!user) {
        throw new BadRequestException('User not found');
      }

      return user;
    } catch (error) {
      this.logger.error('Failed to get user info', error);
      throw error;
    }
  }
}
