package com.ningdatech.carapi.sys.entity;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ningdatech.carapi.common.base.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
 * 包括id、create_time、created_by、updated_by、update_time、label、parent_id、sort_value 字段的表继承的树形实体
 *
 * @author PoffyZhang
 * @since 2022/09/30
 */
@Getter
@Setter
@Accessors(chain = true)
@ToString(callSuper = true)
public class TreeEntity<E extends TreeEntity<E, T>, T extends Serializable> extends BaseEntity {

    @TableId(value = "id", type = IdType.AUTO)
    protected Long id;

    /**
     * 名称
     */
    @ApiModelProperty(value = "名称")
    @NotEmpty(message = "名称不能为空")
    @Size(max = 255, message = "名称长度不能超过255")
    @TableField(value = "name", condition = LIKE)
    protected String name;

    /**
     * 菜单标题
     */
    @ApiModelProperty(value = "菜单标题")
    @NotEmpty(message = "菜单标题不能为空")
    @Size(max = 255, message = "菜单标题长度不能超过255")
    @TableField(value = "title", condition = LIKE)
    protected String title;

    /**
     * 父菜单ID
     */
    @ApiModelProperty(value = "父ID")
    @TableField(value = "pid")
    protected Long pid;

    /**
     * 排序
     */
    @ApiModelProperty(value = "排序号")
    @TableField(value = "sort")
    protected Integer sort;

    /**
     * 顶层菜单
     */
    @ApiModelProperty(value = "顶层菜单")
    @TableField(exist = false)
    protected String topMenu;

    /**
     * 路径
     */
    @ApiModelProperty(value = "路径")
    @Size(max = 255, message = "路径长度不能超过255")
    @TableField(value = "path", condition = LIKE)
    protected String path;


    @ApiModelProperty(value = "子节点", hidden = true)
    @TableField(exist = false)
    protected Set<E> children;


    /**
     * 层级
     */
    @ApiModelProperty(value = "层级")
    @TableField(exist = false)
    protected Integer level = 1;


    /**
     * 初始化子类
     */
    @JsonIgnore
    public void initChildren() {
        if (getChildren() == null) {
            Comparator<TreeEntity<E, T>> comparator = Comparator.comparing(w -> ObjectUtil.defaultIfNull(w.getSort(), 0));
            comparator = comparator.thenComparing(TreeEntity::getId);
            this.setChildren(new TreeSet<>(comparator));
        }
    }

    @JsonIgnore
    public void addChildren(E child) {
        initChildren();
        children.add(child);
    }

    public Integer getSize() {
        if (CollUtil.isNotEmpty(getChildren())) {
            return getChildren().size();
        }
        return 0;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}
