package com.arms.api.issue.almapi.model.vo;

import com.arms.api.issue.almapi.model.dto.IssueDTO;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.util.*;


@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@EqualsAndHashCode(of = {"id","key","upperKey","fromKey","parentKey"})
@Slf4j
public class AlmIssueVO implements Cloneable{

    private AlmIssueWithRequirementVO almIssueWithRequirementVO;

    private String id;

    private String key;

    private String upperKey;

    private String parentKey;

    private String self;

    private IssueFieldData fields;

    private String armsStateCategory;

    private String rawData;

    private String fromKey;

    private boolean excludeFromSave;

    private IssueDTO currentIssueDTO;

    private List<Long> linkedIssuePdServiceIds;

    private List<Long> linkedIssuePdServiceVersions;

    @Builder.Default
    private Set<String> linkedIssue = new HashSet<>();

    public AlmIssueVO parentKey(String parentKey) {
        AlmIssueVO clone = this.clone();
        clone.parentKey = parentKey;
        return clone;
    }

    public boolean isIncludeFromSave() {
        return !excludeFromSave;
    }

    public List<String> getLinkedIssues(){
        return new ArrayList<>(linkedIssue);
    }

    public void addLinkedIssue(AlmIssueVO almIssueVO){
        if(almIssueVO.fromKey!=null){
            Object[] array = Arrays.stream(almIssueVO.fromKey.split("-")).toArray();
            if(array.length==2){
                linkedIssue.add(almIssueVO.almIssueWithRequirementVO.getJiraServerId() +"_"+ array[0] +"_"+almIssueVO.fromKey);
            }else{
                linkedIssue.add(almIssueVO.almIssueWithRequirementVO.getJiraServerId() +"_"+ almIssueVO.fields.getProject().getKey() +"_"+almIssueVO.fromKey);
            }
        }
        if(almIssueVO.getUpperKey()!=null){
            this.upperKey = almIssueVO.getUpperKey();
        }
    }


    public String recentId(){
        return this.almIssueWithRequirementVO.getJiraServerId() +"_"+this.fields.getProject().getKey()+"_"+this.key;
    }

    public String recentParentId(){
        return this.almIssueWithRequirementVO.getJiraServerId() +"_"+this.fields.getProject().getKey()+"_"+this.parentKey;
    }

    public AlmIssueVOResponse toAlmIssueResponseVO() {
        return AlmIssueVOResponse.builder()
                .id(this.id)
                .key(this.key)
                .self(this.self)
                .fields(this.fields).build();
    }

    @Override
    public AlmIssueVO clone() {
        try {
            AlmIssueVO clone = (AlmIssueVO) super.clone();
            clone.linkedIssue = new HashSet<>(this.linkedIssue);
            // TODO: copy mutable state here, so the clone can't change the internals of the original
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
