import { Injectable } from '@nestjs/common';
import * as bcrypt from 'bcryptjs';
import * as crypto from "node:crypto";
import { faker } from '@faker-js/faker';
import { PrismaService } from 'src/prisma/prisma.service';

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

  async runSeed() {
    await this.deleteSeed();
    const { listCreateTypeUsers } = await this.insertTipoUsuarios();
    await this.insertUsuarios(listCreateTypeUsers);
    return 'SEED EXECUTED SUCCESSFULLY';
  }

  async deleteSeed() {
    await this.prisma.usuarios.deleteMany();
    await this.prisma.personas.deleteMany();
    await this.prisma.tipos_usuarios.deleteMany();
    return "SE ELIMINO CORRECTAMENTE";
  }

  async insertTipoUsuarios() {
    const tipoUsuarios = [
      { id: 1, tipo_usuario: 'Administrador' },
      { id: 2, tipo_usuario: 'Cliente' },
    ];

    const listCreateTypeUsers: { id: number; tipo_usuario: string }[] = [];

    for (const tipoUsuario of tipoUsuarios) {
      const objeto = await this.prisma.tipos_usuarios.create({
        data: tipoUsuario,
      });
      listCreateTypeUsers.push(objeto);
    }

    return { listCreateTypeUsers };
  }

  async insertUsuarios(listCreateTypeUsers: { id: number; tipo_usuario: string }[]) {
    const listaUsuarios: {
      id: number;
      usuario: string | null;
      contrasena: string | null;
      email: string;
      persona_id: number;
      tipo_usuario_id: number;
      token: string | null;
      pais: string | null;
      telefono: string | null;
      imagen_perfil: string | null;
      confirmacion: boolean;
      estado: boolean;
      timezone: string | null;
      createdAt: Date;
      updatedAt: Date | null;
    }[] = [];

    for (let i = 0; i < 10; i++) {
      const id_tipo_usuario = faker.helpers.arrayElement(listCreateTypeUsers).id;
      const persona = await this.prisma.personas.create({
        data: {
          nombre: faker.person.firstName(),
          apellidos: faker.person.lastName(),
        },
      });

      const contrasenaEnTextoPlano = `usuario${i + 1}`;
      const contrasenaEncriptada = await bcrypt.hash(contrasenaEnTextoPlano, 10);
      const usuario = await this.prisma.usuarios.create({
        data: {
          usuario: `usuario${i + 1}`,
          contrasena: contrasenaEncriptada,
          email: `usuario${i + 1}@gmail.com`,
          persona_id: persona.id,
          tipo_usuario_id: id_tipo_usuario,
          token: crypto.randomUUID(),
          pais: faker.location.country(),
          telefono: faker.phone.number(),
          imagen_perfil: faker.image.avatar(),
          confirmacion: faker.datatype.boolean(),
          estado: true,
          timezone: 'America/Lima',
        },
      });

      listaUsuarios.push(usuario);
    }

    return listaUsuarios;
  }
}
