package com.bcxin.tenant.domain.entities;

import com.bcxin.Infrastructures.entities.EntityAbstract;
import com.bcxin.Infrastructures.entities.IAggregate;
import com.bcxin.Infrastructures.enums.InviteType;
import com.bcxin.Infrastructures.enums.RelationshipsStatus;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

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

@Getter
@Setter(AccessLevel.PROTECTED)
@Table(name = "tenant_organization_relationships")
@Entity
public class OrganizationRelationshipEntity extends EntityAbstract implements IAggregate {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(name = "id",nullable = false)
    private long id;

    @Column(name = "parent_id",length = 50)
    private String parentId;

    @Column(name = "parent_name")
    private String parentName;

    @Column(name = "selected_organization_id",length = 50,nullable = false)
    private String selectedOrganizationId;

    @Column(name = "selected_organization_name",nullable = false)
    private String selectedOrganizationName;

    @Column(name = "selected_organization_note")
    private String selectedOrganizationNote;

    @Column(name = "code")
    private String code;

    @Column(name = "contact_name",length = 20,nullable = false)
    private String contactName;

    @Column(name = "contact_telephone",length = 20,nullable = false)
    private String contactTelephone;

    @OneToOne(cascade = CascadeType.DETACH,fetch = FetchType.EAGER)
    @JoinColumn(name = "organization_type_id", referencedColumnName = "id")
    private OrganizationTypeEntity organizationType;

    @Column(name = "relationship_index_tree",length = 1000,nullable = false)
    private String relationshipIndexTree;

    @Enumerated(EnumType.ORDINAL)
    @Column(name = "status",length = 3,nullable = false)
    private RelationshipsStatus status;

    @Column(name = "last_reply_note")
    private String lastReplyNote;

    @Column(name = "last_reply_employee_id",length = 100)
    private String lastReplyEmployeeId;

    @Column(name = "last_reply_employee_name",length = 30)
    private String lastReplyEmployeeName;

    @Column(name = "last_reply_time")
    private Timestamp lastReplyTime;

    @Column(name = "organization_id",length = 50,nullable = false)
    private  String organizationId;

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

    @Column(name = "creator_id",length = 50,nullable = false)
    private String creatorId;

    @Column(name = "last_updated_time")
    private Timestamp lastUpdateTime;

    @Enumerated(EnumType.ORDINAL)
    @Column(name = "invite_type",length = 3,nullable = false)
    private InviteType inviteType;


    @Column(name = "is_deleted")
    private boolean isDeleted;

    public OrganizationRelationshipEntity() {
        this.setCreateTime(new Timestamp(System.currentTimeMillis()));
    }

    public OrganizationRelationshipEntity( String parentId, String parentName, String selectedOrganizationId,
                                           String selectedOrganizationName,String selectedOrganizationNote, String code, String contactName,
                                           String contactTelephone, OrganizationTypeEntity organizationType,
                                           String relationshipIndexTree, RelationshipsStatus status, String lastReplyNote,
                                           String lastReplyEmployeeId, String lastReplyEmployeeName,
                                           Timestamp lastReplyTime, String organizationId, String creatorId,
                                           Timestamp lastUpdateTime, InviteType inviteType,boolean isDeleted) {
        this();
        this.parentId = parentId;
        this.parentName = parentName;
        this.selectedOrganizationId = selectedOrganizationId;
        this.selectedOrganizationName = selectedOrganizationName;
        this.selectedOrganizationNote = selectedOrganizationNote;
        this.code = code;
        this.contactName = contactName;
        this.contactTelephone = contactTelephone;
        this.organizationType = organizationType;
        this.relationshipIndexTree = relationshipIndexTree;
        this.status = status;
        this.lastReplyNote = lastReplyNote;
        this.lastReplyEmployeeId = lastReplyEmployeeId;
        this.lastReplyEmployeeName = lastReplyEmployeeName;
        this.lastReplyTime = lastReplyTime;
        this.organizationId = organizationId;
        this.creatorId = creatorId;
        this.lastUpdateTime = lastUpdateTime;
        this.inviteType = inviteType;
        this.isDeleted = isDeleted;
    }
    public static OrganizationRelationshipEntity create(String parentId, String parentName, String selectedOrganizationId, String selectedOrganizationName,String selectedOrganizationNote, String code, String contactName, String contactTelephone, OrganizationTypeEntity organizationType, String relationshipIndexTree, RelationshipsStatus status, String lastReplyNote, String lastReplyEmployeeId, String lastReplyEmployeeName, Timestamp lastReplyTime, String organizationId, String creatorId, InviteType inviteType) {
        Timestamp timestamp = Timestamp.from(Instant.now());
        return new OrganizationRelationshipEntity(parentId,
                parentName,
                selectedOrganizationId,
                selectedOrganizationName,
                selectedOrganizationNote,
                code,
                contactName,
                contactTelephone,
                organizationType,
                relationshipIndexTree,
                status,
                lastReplyNote,
                lastReplyEmployeeId,
                lastReplyEmployeeName,
                lastReplyTime,
                organizationId,
                creatorId,
                timestamp,
                inviteType,false);
    }

    public void change(String parentId, String parentName, String code, String contactName, String contactTelephone, OrganizationTypeEntity organizationType, String relationshipIndexTree, RelationshipsStatus status, String lastReplyNote, String lastReplyEmployeeId, String lastReplyEmployeeName, Timestamp lastReplyTime) {
        if (parentId != null){
            this.setParentId(parentId);
        }
        if (parentName != null){
            this.setParentName(parentName);
        }
        if (code != null){
            this.setCode(code);
        }
        if (contactName != null){
            this.setContactName(contactName);
        }
        if (contactTelephone != null){
            this.setContactTelephone(contactTelephone);
        }
        if (organizationType != null){
            this.setOrganizationType(organizationType);
        }
        if (relationshipIndexTree != null){
            this.setRelationshipIndexTree(relationshipIndexTree);
        }
        if (status != null){
            this.setStatus(status);
        }
        if (lastReplyNote != null){
            this.setLastReplyNote(lastReplyNote);
        }
        if (lastReplyEmployeeId != null){
            this.setLastReplyEmployeeId(lastReplyEmployeeId);
        }
        if (lastReplyEmployeeName != null){
            this.setLastReplyEmployeeName(lastReplyEmployeeName);
        }
        if (lastReplyTime != null){
            this.setLastReplyTime(lastReplyTime);
        }
        this.setLastUpdateTime(Timestamp.from(Instant.now()));
    }

    public void changeRelationshipInfo(String organizationNote,
                                       OrganizationTypeEntity organizationType,
                                       String parentId,
                                       String parentName,
                                       String parentIndex,
                                       String code,
                                       String contactName,
                                       String contactTelephone){
        if(organizationNote !=null){
            this.setSelectedOrganizationNote(organizationNote);
        }
        if(organizationType != null){
            this.setOrganizationType(organizationType);
        }
        if(parentId != null){
            this.setParentId(parentId);
        }
        if(parentName != null){
            this.setParentName(parentName);
        }
        if(parentIndex != null){
            this.setRelationshipIndexTree(parentIndex + "---" + this.getSelectedOrganizationId());
        }
        if(code != null){
            this.setCode(code);
        }
        if(contactName != null){
            this.setContactName(contactName);
        }
        if(contactTelephone != null){
            this.setContactTelephone(contactTelephone);
        }
        this.setLastUpdateTime(Timestamp.from(Instant.now()));
    }

    public void changeRelationshipStatus( RelationshipsStatus status) {
        if (status != null){
            this.setStatus(status);
        }
        this.setLastUpdateTime(Timestamp.from(Instant.now()));
    }

    public void removeRelationship() {
        this.setDeleted(true);
        this.setLastUpdateTime(Timestamp.from(Instant.now()));
    }
    public void restartRelationship(InviteType inviteType) {
        this.setDeleted(false);
        if (inviteType != null){
            if (inviteType.equals(InviteType.Invite)){
                this.setStatus(RelationshipsStatus.TargetVerify);
            }else {
                this.setStatus(RelationshipsStatus.Verify);
            }
        }
        this.setLastUpdateTime(Timestamp.from(Instant.now()));
    }
}
