import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as bcrypt from 'bcrypt';
import * as path from 'path';
import * as fs from 'fs';
import { User } from '@/entities/user.entity';
import {
  UpdateProfileDto,
  ChangePasswordDto,
  QueryUserDto,
  VerifyIdentityDto,
} from './dto/user.dto';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepo: Repository<User>,
  ) {}

  async findById(id: number) {
    const user = await this.userRepo.findOne({ where: { id } });
    if (!user) throw new NotFoundException('用户不存在');
    return user;
  }

  async findByPhone(phone: string) {
    return this.userRepo.findOne({ where: { phone } });
  }

  async updateProfile(id: number, dto: UpdateProfileDto) {
    await this.userRepo.update(id, dto);
    return this.findById(id);
  }

  async changePassword(id: number, dto: ChangePasswordDto) {
    const user = await this.userRepo
      .createQueryBuilder('user')
      .where('user.id = :id', { id })
      .addSelect('user.password')
      .getOne();

    if (!user || !user.password) {
      throw new NotFoundException('用户不存在');
    }

    const isMatch = await bcrypt.compare(dto.oldPassword, user.password);
    if (!isMatch) {
      throw new NotFoundException('旧密码错误');
    }

    const hashed = await bcrypt.hash(dto.newPassword, 10);
    await this.userRepo.update(id, { password: hashed });
    return { message: '密码修改成功' };
  }

  async findAll(query: QueryUserDto) {
    const { page = 1, pageSize = 10, keyword, status, role } = query;
    const qb = this.userRepo.createQueryBuilder('user');

    if (keyword) {
      qb.andWhere('(user.phone LIKE :kw OR user.nickname LIKE :kw)', {
        kw: `%${keyword}%`,
      });
    }
    if (status) {
      qb.andWhere('user.status = :status', { status });
    }
    if (role) {
      qb.andWhere('user.role = :role', { role });
    }

    qb.orderBy('user.createdAt', 'DESC');
    qb.skip((page - 1) * pageSize).take(pageSize);

    const [list, total] = await qb.getManyAndCount();
    return {
      list,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    };
  }

  async freeze(id: number) {
    await this.userRepo.update(id, { status: 'frozen' });
    return { message: '账号已冻结' };
  }

  async unfreeze(id: number) {
    await this.userRepo.update(id, { status: 'active' });
    return { message: '账号已解冻' };
  }

  async uploadAvatar(userId: number, file: Express.Multer.File) {
    if (!file) {
      throw new BadRequestException('请上传文件');
    }

    // 验证文件类型
    const allowedMimes = ['image/jpeg', 'image/png', 'image/jpg', 'image/webp'];
    if (!allowedMimes.includes(file.mimetype)) {
      throw new BadRequestException('只支持 jpg、png、webp 格式的图片');
    }

    // 验证文件大小（5MB）
    if (file.size > 5 * 1024 * 1024) {
      throw new BadRequestException('图片大小不能超过 5MB');
    }

    // 生成文件名
    const ext = path.extname(file.originalname);
    const filename = `avatar_${userId}_${Date.now()}${ext}`;
    const uploadDir = path.join(process.cwd(), 'uploads', 'avatars');
    const filepath = path.join(uploadDir, filename);

    // 确保目录存在
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }

    // 保存文件
    fs.writeFileSync(filepath, file.buffer);

    // 生成访问 URL
    const url = `/uploads/avatars/${filename}`;

    // 更新用户头像
    await this.userRepo.update(userId, { avatar: url });

    return { url };
  }

  async verifyIdentity(userId: number, dto: VerifyIdentityDto) {
    const user = await this.findById(userId);

    // 检查是否已经实名认证
    if (user.isVerified) {
      throw new BadRequestException('您已完成实名认证，无需重复认证');
    }

    // 这里应该调用第三方实名认证服务（如阿里云实人认证、腾讯云身份认证等）
    // 为了演示，这里简化处理，直接通过
    // 实际生产环境需要对接真实的实名认证API
    const isValid = await this.validateIdentity(dto.realName, dto.idCard);

    if (!isValid) {
      throw new BadRequestException('实名认证失败，请检查姓名和身份证号是否正确');
    }

    // 更新用户实名信息
    await this.userRepo.update(userId, {
      realName: dto.realName,
      idCard: dto.idCard,
      isVerified: true,
      verifiedAt: new Date(),
    });

    return {
      code: 0,
      message: '实名认证成功',
      data: {
        isVerified: true,
        realName: dto.realName,
        verifiedAt: new Date(),
      }
    };
  }

  async getVerifyStatus(userId: number) {
    const user = await this.userRepo
      .createQueryBuilder('user')
      .where('user.id = :id', { id: userId })
      .addSelect('user.realName')
      .getOne();

    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    return {
      code: 0,
      data: {
        isVerified: user.isVerified,
        realName: user.realName,
        verifiedAt: user.verifiedAt,
      }
    };
  }

  /**
   * 验证身份信息（对接第三方实名认证服务）
   * 实际生产环境需要对接真实的实名认证API
   */
  private async validateIdentity(realName: string, idCard: string): Promise<boolean> {
    // TODO: 对接第三方实名认证服务
    // 例如：阿里云实人认证、腾讯云身份认证等
    // const result = await thirdPartyService.verify(realName, idCard);
    // return result.success;

    // 简单的格式验证
    const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
    if (!idCardRegex.test(idCard)) {
      return false;
    }

    // 姓名长度验证
    if (realName.length < 2 || realName.length > 50) {
      return false;
    }

    // 模拟异步调用
    await new Promise(resolve => setTimeout(resolve, 100));

    // 演示环境直接返回true
    return true;
  }
}
