package com.arms.api.analysis.topmenu.service;

import com.arms.api.analysis.topmenu.model.dto.TopMenuDTO;
import com.arms.api.analysis.topmenu.model.vo.ReqAndIssueTotalCountVO;
import com.arms.api.issue.almapi.model.entity.AlmIssueEntity;
import com.arms.api.util.model.dto.PdServiceAndIsReqDTO;
import com.arms.egovframework.javaservice.esframework.esquery.SimpleQuery;
import com.arms.egovframework.javaservice.esframework.repository.common.EsCommonRepositoryWrapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@Service
@AllArgsConstructor
public class AnalysisTopMenuImpl implements AnalysisTopMenu {

    private final EsCommonRepositoryWrapper<AlmIssueEntity> esCommonRepositoryWrapper;

    @Override
    public ReqAndIssueTotalCountVO topMenuTotalCountWithReqAndSubtask(TopMenuDTO topMenuDTO) {

        PdServiceAndIsReqDTO pdServiceAndIsReq = topMenuDTO.getPdServiceAndIsReq();

        Long pdServiceLink = pdServiceAndIsReq.getPdServiceId();
        List<Long> pdServiceVersions = pdServiceAndIsReq.getPdServiceVersions();
        Set<Long> versionSet = new HashSet<>(pdServiceVersions);

        List<AlmIssueEntity> retrieveIssues =
                esCommonRepositoryWrapper.findRecentHits(
                    SimpleQuery.termsQueryFilter("linkedIssuePdServiceIds", List.of(pdServiceLink))
                            .andTermsQueryFilter("linkedIssuePdServiceVersions", pdServiceVersions)
                            .andExistsQueryFilter("isReq")
                ).toDocs();

        long req = 0L;
        long subtask = 0L;
        long notAssignedReq = 0L;
        long notAssignedNotReq = 0L;
        // case 분류해서 증가하는것 검토.
        for (AlmIssueEntity issue : retrieveIssues) {
            Long pdServiceId = issue.getPdServiceId();
            // 요구사항
            if (isRightReqIssue(issue, pdServiceLink, versionSet)) {
                req++;
                if (isNotAssignedIssue(issue)) {
                    notAssignedReq++;
                }
            } else {
                subtask++;
                if (isNotAssignedIssue(issue)) {
                    notAssignedNotReq++;
                }
            }
        }

        return ReqAndIssueTotalCountVO.builder()
                .total(req+subtask)
                .req(req).notAssignedReq(notAssignedReq)
                .subtask(subtask).notAssignedNotReq(notAssignedNotReq)
                .build();
    }

    /*
    * 서비스에서 사용하는 private method 작성
    * */
    // 적합한 요구사항 이슈인지 검증
    private boolean isRightReqIssue(AlmIssueEntity issue, Long pdServiceId, Set<Long> versionSet) {
        return Boolean.TRUE.equals(issue.getIsReq())
                && Objects.equals(issue.getPdServiceId(), pdServiceId)
                && isContainsRightVersion(issue.getPdServiceVersions(), versionSet);
    }

    // 버전 검증
    private boolean isContainsRightVersion(List<Long> versions, Set<Long> versionSet) {
        if (versions == null || versionSet == null || versions.isEmpty() || versionSet.isEmpty()) {
            return false;
        }
        return versions.stream().anyMatch(versionSet::contains);

    }

    // 담당자 존재여부
    private boolean isNotAssignedIssue(AlmIssueEntity issue) {
        return ObjectUtils.isEmpty(issue.getAssignee());
    }
}
