import { Injectable, ConflictException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcryptjs';
import * as crypto from 'crypto';

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

  findByUsername(username: string) {
    return this.prisma.user.findUnique({ where: { username } });
  }

  findById(id: number) {
    return this.prisma.user.findUnique({ where: { id } });
  }

  create(data: { username: string; email: string; passwordHash: string }) {
    return this.prisma.user.create({ data });
  }

  updateProfile(id: number, data: { firstName?: string; lastName?: string; email?: string }) {
    return this.prisma.user.update({ where: { id }, data });
  }

  findAll() {
    return this.prisma.user.findMany({
      select: {
        id: true,
        username: true,
        email: true,
        firstName: true,
        lastName: true,
        role: true,
        isPremium: true,
        canShareRecipes: true,
        createdAt: true,
      },
      orderBy: { username: 'asc' },
    });
  }

  setRole(id: number, role: string) {
    return this.prisma.user.update({ where: { id }, data: { role } });
  }

  setPremium(id: number, isPremium: boolean) {
    return this.prisma.user.update({ where: { id }, data: { isPremium } });
  }

  setRecipeSharing(id: number, canShareRecipes: boolean) {
    return this.prisma.user.update({ where: { id }, data: { canShareRecipes } });
  }

  async adminCreate(data: { username: string; email: string; password: string; role?: string }) {
    const existing = await this.prisma.user.findFirst({
      where: { OR: [{ username: data.username }, { email: data.email }] },
    });
    if (existing) {
      throw new ConflictException(
        existing.username === data.username ? 'Användarnamnet är redan taget' : 'E-postadressen används redan',
      );
    }
    const passwordHash = await bcrypt.hash(data.password, 12);
    return this.prisma.user.create({
      data: { username: data.username, email: data.email, passwordHash, role: data.role ?? 'user' },
    });
  }

  deleteUser(id: number) {
    return this.prisma.user.delete({ where: { id } });
  }

  async resetPassword(id: number): Promise<{ temporaryPassword: string }> {
    // Generera läsbart 12-teckens lösenord (4 ord från slumpmässiga bytes)
    const temporaryPassword = crypto.randomBytes(9).toString('base64url').slice(0, 12);
    const passwordHash = await bcrypt.hash(temporaryPassword, 12);
    await this.prisma.user.update({ where: { id }, data: { passwordHash } });
    return { temporaryPassword };
  }

  updateEmail(id: number, email: string) {
    return this.prisma.user.update({ where: { id }, data: { email } });
  }
}
