import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'
import { BaseEntity } from '#application/base/baseEntity'
import { User } from './user'
import { Zone } from './zone'
import { CharacterType } from './characterType'
import { CharacterHair } from './characterHair'
import { CharacterItem } from './characterItem'
import { CharacterEquipment } from './characterEquipment'
import { Chat } from './chat'

@Entity()
export class Character extends BaseEntity {
  @PrimaryKey()
  id!: number

  @ManyToOne(() => User)
  user!: User

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

  @Property()
  online = false

  @Property()
  role = 'player'

  @OneToMany(() => Chat, (chat) => chat.character)
  chats = new Collection<Chat>(this)

  // Position
  @ManyToOne(() => Zone, { nullable: true })
  zone?: Zone

  @Property()
  positionX = 0

  @Property()
  positionY = 0

  @Property()
  rotation = 0

  // Customization
  @ManyToOne()
  characterType?: CharacterType | null | undefined

  @ManyToOne()
  characterHair?: CharacterHair | null | undefined

  // Inventory
  @OneToMany({ mappedBy: 'character' })
  items = new Collection<CharacterItem>(this)

  @OneToMany({ mappedBy: 'character' })
  equipment = new Collection<CharacterEquipment>(this)

  // Stats
  @Property()
  alignment = 50

  @Property()
  hitpoints = 100

  @Property()
  mana = 100

  @Property()
  level = 1

  @Property()
  experience = 0

  @Property()
  strength = 10

  @Property()
  dexterity = 10

  @Property()
  intelligence = 10

  @Property()
  wisdom = 10

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

  getId() {
    return this.id
  }

  setUser(user: User) {
    this.user = user
    return this
  }

  getUser() {
    return this.user
  }

  setName(name: string) {
    this.name = name
    return this
  }

  getName() {
    return this.name
  }

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

  getOnline() {
    return this.online
  }

  setRole(role: string) {
    this.role = role
    return this
  }

  getRole() {
    return this.role
  }

  setChats(chats: Collection<Chat>) {
    this.chats = chats
    return this
  }

  getChats() {
    return this.chats
  }

  setZone(zone: Zone | undefined) {
    this.zone = zone
    return this
  }

  getZone() {
    return this.zone
  }

  setPositionX(positionX: number) {
    this.positionX = positionX
    return this
  }

  getPositionX() {
    return this.positionX
  }

  setPositionY(positionY: number) {
    this.positionY = positionY
    return this
  }

  getPositionY() {
    return this.positionY
  }

  setRotation(rotation: number) {
    this.rotation = rotation
    return this
  }

  getRotation() {
    return this.rotation
  }

  setCharacterType(characterType: CharacterType | null | undefined) {
    this.characterType = characterType
    return this
  }

  getCharacterType() {
    return this.characterType
  }

  setCharacterHair(characterHair: CharacterHair | null | undefined) {
    this.characterHair = characterHair
    return this
  }

  getCharacterHair() {
    return this.characterHair
  }

  setItems(items: Collection<CharacterItem>) {
    this.items = items
    return this
  }

  getItems() {
    return this.items
  }

  setEquipment(equipment: Collection<CharacterEquipment>) {
    this.equipment = equipment
    return this
  }

  getEquipment() {
    return this.equipment
  }

  setAlignment(alignment: number) {
    this.alignment = alignment
    return this
  }

  getAlignment() {
    return this.alignment
  }

  setHitpoints(hitpoints: number) {
    this.hitpoints = hitpoints
    return this
  }

  getHitpoints() {
    return this.hitpoints
  }

  setMana(mana: number) {
    this.mana = mana
    return this
  }

  getMana() {
    return this.mana
  }

  setLevel(level: number) {
    this.level = level
    return this
  }

  getLevel() {
    return this.level
  }

  setExperience(experience: number) {
    this.experience = experience
    return this
  }

  getExperience() {
    return this.experience
  }

  setStrength(strength: number) {
    this.strength = strength
    return this
  }

  getStrength() {
    return this.strength
  }

  setDexterity(dexterity: number) {
    this.dexterity = dexterity
    return this
  }

  getDexterity() {
    return this.dexterity
  }

  setIntelligence(intelligence: number) {
    this.intelligence = intelligence
    return this
  }

  getIntelligence() {
    return this.intelligence
  }

  setWisdom(wisdom: number) {
    this.wisdom = wisdom
    return this
  }

  getWisdom() {
    return this.wisdom
  }
}