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

import com.arms.api.issue.almapi.model.vo.cloudjiraspec.CloudJiraIssueRawDataVO;
import com.arms.api.serverinfo.model.vo.ServerInfoVO;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;



@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@Slf4j
@EqualsAndHashCode(of = {"cloudJiraIssueRawDataVO"})
public class CloudJiraIssueVO {

    private CloudJiraIssueRawDataVO cloudJiraIssueRawDataVO;

    private ServerInfoVO serverInfoVO;

    private AlmIssueWithRequirementVO almIssueWithRequirementVO;

    private boolean excludeFromSave;

    private List<Long> linkedIssuePdServiceIds;

    private List<Long> linkedIssuePdServiceVersions;

    public AlmIssueVO toAlmIssueVOByStateCategory(String armsStateCategory){
         return AlmIssueVO.builder()
                    .upperKey(cloudJiraIssueRawDataVO.getParentKey())
                    .id(cloudJiraIssueRawDataVO.getId())
                    .self(cloudJiraIssueRawDataVO.getSelf())
                    .key(cloudJiraIssueRawDataVO.getKey())
                    .fields(cloudJiraIssueRawDataVO.getFields())
                    .rawData(cloudJiraIssueRawDataVO.getRawData())
                    .almIssueWithRequirementVO(almIssueWithRequirementVO)
                    .excludeFromSave(excludeFromSave)
                    .linkedIssue(relationRecentIds())
                    .armsStateCategory(armsStateCategory)
                    .linkedIssuePdServiceIds(linkedIssuePdServiceIds)
                    .linkedIssuePdServiceVersions(linkedIssuePdServiceVersions)
                .build();
    }

    public AlmIssueVO toAlmIssueVO() {
        return AlmIssueVO.builder()
                .upperKey(cloudJiraIssueRawDataVO.getParentKey())
                .id(cloudJiraIssueRawDataVO.getId())
                .self(cloudJiraIssueRawDataVO.getSelf())
                .key(cloudJiraIssueRawDataVO.getKey())
                .fields(cloudJiraIssueRawDataVO.getFields())
                .rawData(cloudJiraIssueRawDataVO.getRawData())
                .build();
    }

    public IssueFieldData cloudJiraIssueField(){
        return cloudJiraIssueRawDataVO.getFields();
    }

    public String recentId(){
        return this.serverInfoVO.getConnectId() +"_"+ cloudJiraIssueRawDataVO.getFields().getProject().getKey()+"_"+ cloudJiraIssueRawDataVO.getKey();
    }

    public String recentId(String key){
        return this.serverInfoVO.getConnectId() +"_"+ cloudJiraIssueRawDataVO.getFields().getProject().getKey()+"_"+key;
    }

    public CloudJiraIssueVO markAsExcludedFromSave(){
        return CloudJiraIssueVO.builder()
                .cloudJiraIssueRawDataVO(this.cloudJiraIssueRawDataVO)
                .serverInfoVO(this.serverInfoVO)
                .almIssueWithRequirementVO(this.almIssueWithRequirementVO)
                .excludeFromSave(true)
                .build();
    }

    public CloudJiraIssueVO appliedLinkedIssuePdServiceElement(List<AlmIssueWithRequirementVO> almIssueWithRequirementVOS){

        return CloudJiraIssueVO.builder()
                .cloudJiraIssueRawDataVO(this.cloudJiraIssueRawDataVO)
                .serverInfoVO(this.serverInfoVO)
                .almIssueWithRequirementVO(
                    almIssueWithRequirementVOS
                        .stream()
                        .filter(a-> a.getIssueKey().equals(almIssueWithRequirementVO.getIssueKey()))
                        .findFirst()
                        .orElseGet(()->this.almIssueWithRequirementVO)
                )
                .linkedIssuePdServiceIds(almIssueWithRequirementVOS.stream().map(AlmIssueWithRequirementVO::getServiceId).toList())
                .linkedIssuePdServiceVersions(almIssueWithRequirementVOS.stream().flatMap(a->a.getVersions().stream()).toList())
                .excludeFromSave(this.excludeFromSave)
                .build();
    }

    public Set<String> relationRecentIds(){

        List<IssueLink> issueRelations = cloudJiraIssueRawDataVO.getFields().getIssuelinks();

        Set<String> set = issueRelations
                .stream()
                .filter(a -> !ObjectUtils.isEmpty(a.getInwardIssue()))
                .map(a -> {
                    String projectKey = Arrays.stream(a.getInwardIssue().getKey().split("-")).findFirst().orElseGet(() -> almIssueWithRequirementVO.getProjectKeyOrId());
                    return almIssueWithRequirementVO.extractIssueKeyFromMainKey(projectKey, a.getInwardIssue().getKey());
                })
                .collect(Collectors.toSet());


        set.addAll(issueRelations
                .stream()
                .filter(a -> !ObjectUtils.isEmpty(a.getOutwardIssue()))
                .map(a -> {
                    String projectKey = Arrays.stream(a.getOutwardIssue().getKey().split("-")).findFirst().orElseGet(() -> almIssueWithRequirementVO.getProjectKeyOrId());
                    return almIssueWithRequirementVO.extractIssueKeyFromMainKey(projectKey, a.getOutwardIssue().getKey());
                })
                .collect(Collectors.toSet()));

        return set;

    }

}
