import { randomUUID } from 'node:crypto'

import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'
import bcrypt from 'bcryptjs'

import { BaseEntity } from '#application/base/baseEntity'
import { UUID } from '#application/types'
import { Character } from '#entities/character'
import { PasswordResetToken } from '#entities/passwordResetToken'


export class BaseUser extends BaseEntity {
  @PrimaryKey()
  id = randomUUID()

  @Property({ unique: true })
  username!: string

  @Property({ unique: true })
  email!: string

  @Property()
  password!: string

  @Property()
  online = false

  @OneToMany(() => Character, (character) => character.user)
  characters = new Collection<Character>(this)

  @OneToMany(() => PasswordResetToken, (token) => token.user)
  passwordResetTokens = new Collection<PasswordResetToken>(this)

  setId(id: UUID) {
    this.id = id
    return this
  }

  getId() {
    return this.id
  }

  setUsername(username: string) {
    this.username = username
    return this
  }

  getUsername() {
    return this.username
  }

  setEmail(email: string) {
    this.email = email
    return this
  }

  getEmail() {
    return this.email
  }

  setPassword(password: string) {
    this.password = bcrypt.hashSync(password, 10)
    return this
  }

  getPassword() {
    return this.password
  }

  setOnline(online: boolean) {
    this.online = online
    return this
  }

  getOnline() {
    return this.online
  }

  setCharacters(characters: Collection<Character>) {
    this.characters = characters
    return this
  }

  getCharacters() {
    return this.characters
  }

  setPasswordResetTokens(passwordResetTokens: Collection<PasswordResetToken>) {
    this.passwordResetTokens = passwordResetTokens
    return this
  }

  getPasswordResetTokens() {
    return this.passwordResetTokens
    return this
  }
}