import { Injectable, UnauthorizedException, BadRequestException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';
import { PrismaService } from '../../prisma/prisma.service';

@Injectable()
export class AuthService {
  constructor(
    private prisma: PrismaService,
    private jwtService: JwtService,
  ) {}

  async register(data: { username?: string; phone?: string; email?: string; password: string; nickname?: string }) {
    if (!data.username && !data.phone && !data.email) {
      throw new BadRequestException('请填写用户名、手机号或邮箱');
    }

    if (data.username) {
      const exists = await this.prisma.user.findUnique({ where: { username: data.username } });
      if (exists) throw new BadRequestException('用户名已被注册');
    }
    if (data.phone) {
      const exists = await this.prisma.user.findUnique({ where: { phone: data.phone } });
      if (exists) throw new BadRequestException('手机号已被注册');
    }
    if (data.email) {
      const exists = await this.prisma.user.findUnique({ where: { email: data.email } });
      if (exists) throw new BadRequestException('邮箱已被注册');
    }

    const passwordHash = await bcrypt.hash(data.password, 10);
    const user = await this.prisma.user.create({
      data: {
        username: data.username || null,
        phone: data.phone || null,
        email: data.email || null,
        passwordHash,
        nickname: data.nickname || data.username || data.phone || data.email?.split('@')[0],
      },
    });
    return this.generateTokens(user.id);
  }

  async login(account: string, password: string) {
    const user = await this.prisma.user.findFirst({
      where: {
        OR: [{ username: account }, { phone: account }, { email: account }],
        deletedAt: null,
      },
    });

    if (!user || !user.passwordHash) {
      throw new UnauthorizedException('账号或密码错误');
    }

    const isValid = await bcrypt.compare(password, user.passwordHash);
    if (!isValid) {
      throw new UnauthorizedException('账号或密码错误');
    }

    await this.prisma.user.update({
      where: { id: user.id },
      data: { lastLoginAt: new Date() },
    });

    return this.generateTokens(user.id);
  }

  async refreshAccessToken(accessToken: string) {
    try {
      const payload = this.jwtService.verify(accessToken, { ignoreExpiration: true });
      const user = await this.prisma.user.findUnique({
        where: { id: payload.sub, deletedAt: null },
      });
      if (!user || user.status !== 'ACTIVE') {
        throw new UnauthorizedException('用户不可用');
      }
      return this.generateTokens(user.id);
    } catch {
      throw new UnauthorizedException('Token 无效');
    }
  }

  async getProfile(userId: number) {
    return this.prisma.user.findUnique({
      where: { id: userId },
      select: {
        id: true,
        username: true,
        phone: true,
        email: true,
        nickname: true,
        avatar: true,
        status: true,
        memberPlan: true,
        memberExpire: true,
        sandboxDaily: true,
        createdAt: true,
      },
    });
  }

  private generateTokens(userId: number) {
    const payload = { sub: userId };
    return {
      accessToken: this.jwtService.sign(payload, { expiresIn: '7d' }),
      refreshToken: this.jwtService.sign(payload, { expiresIn: '30d' }),
    };
  }
}
