import { Entity, Column, OneToMany, ManyToMany, JoinTable, Relation } from "typeorm";
import { AbstractEntity } from "./AbstractEntity.js";
import { RecipeInstructionStepEntity } from "./RecipeInstructionStepEntity.js";
import { RecipeIngredientGroupEntity } from "./RecipeIngredientGroupEntity.js";
import { TagEntity } from "./TagEntity.js";

/**
 * Entity describing a recipe
 */
@Entity({ name: "recipe" })
export class RecipeEntity extends AbstractEntity {
    @Column({ nullable: false })
    title!: string;

    @Column({ nullable: true })
    amount?: number;

    @Column({ nullable: true, name: "amount_description" })
    amountDescription?: string;

    // make sure not to induce a circular dependency! use arrow function without brackets!
    @OneToMany(() => RecipeInstructionStepEntity, (instructionStep) => instructionStep.recipe, {
        cascade: true
    })
    instructionSteps!: RecipeInstructionStepEntity[];

    // make sure not to induce a circular dependency! use arrow function without brackets!
    @OneToMany(() => RecipeIngredientGroupEntity, (ingredientGroup) => ingredientGroup.recipe, {
        cascade: true
    })
    ingredientGroups!: Relation<RecipeIngredientGroupEntity>[];

    /**
     * Tags associated with this recipe.
     *
     * RecipeEntity is the *owning* side of the relation:
     *   - @JoinTable creates and owns the `recipe_tag` mapping table.
     *   - cascade insert/update allows tags to be persisted via recipe save.
     *
     * Deleting a Recipe removes its rows from recipe_tag automatically via the
     * ON DELETE CASCADE FK defined in the migration. Tags themselves are unaffected.
     * Deleting a Tag similarly removes its rows from recipe_tag via the other FK.
     *
     * make sure not to induce a circular dependency! use arrow function without brackets!
     */
    @ManyToMany(() => TagEntity, (tag) => tag.recipeList, {
        cascade: ["insert", "update"],
        eager: false,
        nullable: true,
    })
    @JoinTable({
        name: "recipe_tag",
        joinColumn:        { name: "recipe_id", referencedColumnName: "id" },
        inverseJoinColumn: { name: "tag_id",    referencedColumnName: "id" },
    })
    tagList?: TagEntity[];
}