import { Column, Entity, JoinTable, ManyToMany, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { CharacterTag } from './character-tag';
import { InteractionTag } from './interaction-tag';
import { TagName } from './tag-name';
import { WorkTag } from './work-tag';

/**
 * This entity is the main tag entity.
 * Tags have a name and a description.
 * They can tag a work, a character, or a character interaction.
 * They can also be in a hierarchy
 */
@Entity()
export class Tag implements IIdentifiableEntity, IMultiNamedEntity, IDescribableEntity, IHierachicalEntity<Tag> {
  @PrimaryGeneratedColumn()
  public id!: number;

  @Column({
    nullable: false,
    default: '',
  })
  public nameCanonical!: string;

  @OneToMany(() => TagName, (tagName: TagName) => tagName.entity)
  public names!: Promise<TagName[]>;

  /**
   * this tag tagging a work
   */
  @OneToMany(() => WorkTag, (workTag: WorkTag) => workTag.tag)
  public workTags!: Promise<WorkTag[]>;

  /**
   * this tag tagging characters
   */
  @OneToMany(() => CharacterTag, (characterTag: CharacterTag) => characterTag.tag)
  public characterTags!: Promise<CharacterTag[]>;

  /**
   * this tag tagging a character interaction
   */
  @OneToMany(() => InteractionTag, (interactionTag: InteractionTag) => interactionTag.tag)
  public interactionTags!: Promise<InteractionTag[]>;

  @ManyToMany(() => Tag, (tag: Tag) => tag.children)
  @JoinTable()
  public parents!: Promise<Tag[]>;

  @ManyToMany(() => Tag, (tag: Tag) => tag.parents)
  public children!: Promise<Tag[]>;

  @Column({
    nullable: false,
    default: '',
  })
  public description!: string;
}
