import { BadRequestException, ForbiddenException, Injectable, UnauthorizedException } from "@nestjs/common";
import bcrypt from "bcryptjs";
import { PrismaService } from "../../common/prisma/prisma.service";
import { isValidPassword } from "../../common/security/password";

@Injectable()
export class UsersService {
  constructor(private readonly prisma: PrismaService) {}

  getMe(userId: string) {
    return this.prisma.user.findUnique({
      where: { id: userId },
      select: {
        id: true,
        email: true,
        fullName: true,
        role: true,
        permissions: true,
        isActive: true,
        phone: true,
        avatarUrl: true,
      },
    });
  }

  async updateMe(userId: string, payload: { fullName?: string; phone?: string; avatarUrl?: string }) {
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user || !user.isActive) {
      throw new ForbiddenException("account_inactive");
    }
    const fullName = payload.fullName?.trim();
    const phone = payload.phone?.trim();
    const avatarUrl = payload.avatarUrl?.trim();
    if (fullName !== undefined && (fullName.length < 2 || fullName.length > 100)) throw new BadRequestException("invalid_full_name");
    if (phone !== undefined && phone.length > 30) throw new BadRequestException("invalid_phone");
    if (avatarUrl !== undefined && avatarUrl.length > 1000) throw new BadRequestException("invalid_avatar_url");
    return this.prisma.user.update({
      where: { id: userId },
      data: {
        fullName: fullName || user.fullName,
        ...(payload.phone !== undefined ? { phone: phone || null } : {}),
        ...(payload.avatarUrl !== undefined ? { avatarUrl: avatarUrl || null } : {}),
      },
      select: {
        id: true,
        email: true,
        fullName: true,
        phone: true,
        avatarUrl: true,
      },
    });
  }

  async changePassword(userId: string, body: { currentPassword?: string; newPassword?: string }) {
    if (!body.currentPassword || !body.newPassword) throw new BadRequestException("password_fields_required");
    if (!isValidPassword(body.newPassword)) {
      throw new BadRequestException("weak_password");
    }
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user || !(await bcrypt.compare(body.currentPassword, user.passwordHash))) throw new UnauthorizedException("invalid_current_password");
    const passwordHash = await bcrypt.hash(body.newPassword, 12);
    await this.prisma.user.update({ where: { id: userId }, data: { passwordHash, tokenVersion: { increment: 1 } } });
    return { changed: true };
  }

  async deleteMe(userId: string, password?: string) {
    if (!password) throw new BadRequestException("password_required");
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user || !(await bcrypt.compare(password, user.passwordHash))) throw new UnauthorizedException("invalid_credentials");
    await this.prisma.user.update({ where: { id: userId }, data: { isActive: false, status: "DELETED", tokenVersion: { increment: 1 }, email: `deleted-${user.id}@deleted.local`, phone: null, avatarUrl: null, fullName: "مستخدم محذوف" } });
    return { deleted: true };
  }
}
