package relations.selfref;

import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
 * ============================================================================
 * 关系情形 ⑤：自关联（树形结构）—— Category
 * ============================================================================
 *
 * 【关系 / Relationship】
 * EN — A category may have a parent category, and a parent has many child categories.
 *      Both sides are the SAME entity, so one foreign key column (parent_id) points back to
 *      this table's own primary key.
 * 中 — 分类可以有父分类，父分类又有多个子分类。两端都是同一个实体，
 *      所以用一个外键列 parent_id 指回本表自己的主键。
 *
 * 【生成表 / Generated table】
 *   category(id, name, parent_id)      parent_id → category.id
 *
 * 【考试来源 / Where it appears】
 * EN — Paper 2 Section B asks for a self-join on the Course table (PrerequisiteId), and
 *      Paper 1 asks for an association class; this mapping is the JPA version of that idea.
 * 中 — Paper 2 的 Section B 要求对 Course 表做自连接（PrerequisiteId），
 *      这里就是它在 JPA 里的写法。
 *
 * 【注意 / Note】
 * EN — Do NOT add orphanRemoval = true here if deleting a parent must not delete children;
 *      a tree often needs "re-parent children" instead of cascade delete.
 * 中 — 如果删除父节点不该连带删除子节点，这里不要加 orphanRemoval = true；
 *      树形结构通常需要“把子节点改挂到别处”，而不是级联删除。
 */
@Entity
public class Category {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Category parent;

    @OneToMany(mappedBy = "parent")
    private List<Category> children = new ArrayList<>();

    public Category() { }
    public Category(String name) { this.name = name; }

    public void addChild(Category child) {
        children.add(child);
        child.setParent(this);
    }

    public Long getId() { return id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Category getParent() { return parent; }
    public void setParent(Category parent) { this.parent = parent; }
    public List<Category> getChildren() { return children; }
}
