package com.bcxin.tenant.domain.entities;
import com.bcxin.Infrastructures.entities.EntityAbstract;
import com.bcxin.Infrastructures.entities.IAggregate;
import com.bcxin.Infrastructures.enums.ResourceReferenceType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.sql.Timestamp;
import java.time.Instant;

@Getter
@Setter(AccessLevel.PROTECTED)
@Table(name = "external_groups")
@Entity
public class ExternalGroupEntity extends EntityAbstract implements IAggregate {
    @Id
    @Column(length = 50)
    private String id;

    @Column(nullable = false, length = 200)
    private String name;

    @Column(name = "display_order", nullable = false)
    private int displayOrder;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "principal_id", referencedColumnName = "id",
            foreignKey = @ForeignKey(name = "fk_groups_principal_id", value = ConstraintMode.CONSTRAINT))
    private ExternalMemberEntity principal;

    @Column(name = "principal_name", nullable = true)
    private String principalName;

    /**
     * 索引树, 提高检索速度
     */
    @Column(name = "index_tree", nullable = false, length = 500)
    private String indexTree;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id", referencedColumnName = "id",
            foreignKey = @ForeignKey(name = "fk_groups_parent_id", value = ConstraintMode.CONSTRAINT))
    private ExternalGroupEntity parent;

    @Column(nullable = false, name = "created_time")
    private Timestamp createdTime;

    @Column(nullable = true, name = "last_updated_time")
    private Timestamp lastUpdatedTime;

    @Column(nullable = false,name = "reference_type")
    private ResourceReferenceType referenceType;

    /**
     *  目前均指企业的Id
     */
    @Column(nullable = false,name = "reference_number",length = 200)
    private String referenceNumber;

    public void change(String name, int displayOrder) {
        this.setName(name);
        this.setDisplayOrder(displayOrder);
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }

    public void assignPrincipal(ExternalMemberEntity externalMember) {
        if (externalMember == null) {
            this.setPrincipal(null);
            this.setPrincipalName(null);
        }else {
            this.setPrincipal(externalMember);
            this.setPrincipalName(externalMember.getTenantUser().getName());
        }
    }

    public ExternalGroupEntity(){
        this.setCreatedTime(Timestamp.from(Instant.now()));
    }

    public static ExternalGroupEntity create(ResourceReferenceType referenceType,String referenceNumber,
                                             String id,String name,int displayOrder) {
        ExternalGroupEntity group = new ExternalGroupEntity();
        group.setId(id);
        group.change(name, displayOrder);
        group.setReferenceType(referenceType);
        group.setReferenceNumber(referenceNumber);

        return group;
    }

    public void assign(ExternalGroupEntity parent)
    {
        this.setParent(parent);

        if (parent != null) {
            this.setIndexTree(String.format("%s-%s", parent.getIndexTree(), this.getId()));
        } else {
            this.setIndexTree(this.getId());
        }
    }
}
