package com.arms.api.issue.almapi.service;

import com.arms.api.issue.almapi.model.dto.AlmIssueIncrementDTO;
import com.arms.api.issue.almapi.model.dto.AlmIssueWithRequirementDTO;
import com.arms.api.issue.almapi.model.vo.AlmIssueWithRequirementVO;
import com.arms.api.issue.almapi.model.dto.CReqProperty;
import com.arms.api.issue.almapi.model.entity.AlmIssueEntity;
import com.arms.api.issue.almapi.model.vo.cloudjiraspec.CloudJiraIssueRawDataVO;
import com.arms.api.serverinfo.model.vo.ServerInfoVO;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.alm.JiraApi;
import com.arms.api.util.alm.JiraUtil;
import com.arms.egovframework.javaservice.esframework.config.EsIndexTemplateConfig;
import com.arms.egovframework.javaservice.esframework.esquery.SimpleQuery;
import com.arms.egovframework.javaservice.esframework.model.vo.DocumentResultWrapper;
import com.arms.egovframework.javaservice.esframework.repository.common.EsCommonRepositoryWrapper;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.*;
import java.util.function.Function;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@SpringBootTest(properties = {
        "spring.profiles.active=dev",
        "arms-index-name.jiraissue=test_jiraissue",
        "arms-index-name.serverinfo=test_serverinfo"
})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ARMSCloudJiraDiscoveryTest extends WireMockCloudJira2Config {

    @Autowired
    IssueService issueService;

    @Autowired
    ServerInfoService serverInfoService;

    @MockitoBean
    CategoryMappingService categoryMappingService;

    @Autowired
    EsCommonRepositoryWrapper<AlmIssueEntity> esCommonRepositoryWrapper;

    @Autowired
    EsIndexTemplateConfig esIndexTemplateConfig;

    @Autowired
    JiraUtil jiraUtil;

    @Autowired
    JiraApi jiraApi;

    @BeforeEach
    void 요구사항키_셋업() {

        esCommonRepositoryWrapper.deleteIndex(-1);
        esCommonRepositoryWrapper.saveEmpty(new AlmIssueEntity());

        when(categoryMappingService.getMappingCategory(any(),any(),any(),any()))
                .thenReturn("");

        List<String> issueKeys = List.of("ARMSTEST-1", "ARMSTEST-4", "ARMSTEST-5", "ARMSTEST-6", "ARMSTEST-7", "ARMSTEST-39", "ARMSTEST-42","ARMSTEST-43","ARMSTEST-44");

        for (String issueKey : issueKeys) {
            AlmIssueWithRequirementDTO almIssueWithRequirementDTO = new AlmIssueWithRequirementDTO();
            almIssueWithRequirementDTO.setJiraServerId("1000000000000000004");
            almIssueWithRequirementDTO.setIssueKey(issueKey);
            almIssueWithRequirementDTO.setServiceId(1L);
            almIssueWithRequirementDTO.setVersions(List.of(1L));
            almIssueWithRequirementDTO.setProjectKeyOrId("ARMSTEST");
            almIssueWithRequirementDTO.setCReqLink(1L);

            CReqProperty cReqProperty = new CReqProperty();
            cReqProperty.setCReqPriorityLink(1L);
            almIssueWithRequirementDTO.setCReqProperty(cReqProperty);

            issueService.preSaveReqStatus(almIssueWithRequirementDTO);

        }
    }

    @Test
    public void 암스_클라우드_지라_요구사항_별_테스트() throws Exception {

        List<String> values = Arrays.asList("ARMSTEST-1", "ARMSTEST-4", "ARMSTEST-5", "ARMSTEST-6", "ARMSTEST-7", "ARMSTEST-39", "ARMSTEST-42","ARMSTEST-43","ARMSTEST-44");
        Collections.shuffle(values);

        for (String value : values) {
            AlmIssueWithRequirementDTO almIssueWithRequirementDTO = new AlmIssueWithRequirementDTO();
            almIssueWithRequirementDTO.setJiraServerId("1000000000000000004");
            almIssueWithRequirementDTO.setIssueKey(value);
            almIssueWithRequirementDTO.setServiceId(1L);
            almIssueWithRequirementDTO.setVersions(List.of(1L));
            almIssueWithRequirementDTO.setProjectKeyOrId("ARMSTEST");
            almIssueWithRequirementDTO.setCReqLink(1L);
            CReqProperty cReqProperty = new CReqProperty();
            cReqProperty.setCReqPriorityLink(1L);
            almIssueWithRequirementDTO.setCReqProperty(cReqProperty);
//            AlmIssueEntity almIssueEntity = issueService.discoveryALmIssueAndGetReqAlmIssueEntity(almIssueWithRequirementVO);
        }

        암스_클라우드지라_데이터_검증();
    }

    @Test
    public void 암스_클라우드_지라_증분_테스트_2025_01_01_2025_07_27() {

        List<String> values = Arrays.asList("ARMSTEST");
        Collections.shuffle(values);

        for (String value : values) {
            AlmIssueIncrementDTO almIssueIncrementDTO = AlmIssueIncrementDTO.builder()
                    .serverId("1000000000000000004")
                    .projectKey(value)
                    .startDate("2025-07-01")
                    .endDate("2025-08-04")
                    .build();
            List<AlmIssueEntity> almIssueEntities = issueService.discoveryIncrementALmIssueAndGetReqAlmIssueEntities(almIssueIncrementDTO);
        }

        암스_클라우드지라_데이터_검증();
    }

    @Test
    public void 전체_수집_다음_증분_수집() throws Exception {

        List<String> projectValues = Arrays.asList("ARMSTEST");
        Collections.shuffle(projectValues);

        for (String value : projectValues) {
            AlmIssueIncrementDTO almIssueIncrementDTO = AlmIssueIncrementDTO.builder()
                    .serverId("1000000000000000004")
                    .projectKey(value)
                    .startDate("2025-07-01")
                    .endDate("2025-08-04")
                    .build();
            List<AlmIssueEntity> almIssueEntities = issueService.discoveryIncrementALmIssueAndGetReqAlmIssueEntities(almIssueIncrementDTO);
        }

        암스_클라우드지라_데이터_검증();
    }


    public void 암스_클라우드지라_데이터_검증(){

        DocumentResultWrapper<AlmIssueEntity> findRecentHits
            = esCommonRepositoryWrapper.findRecentHits(SimpleQuery.termQueryFilter("jira_server_id", "1000000000000000004"));

        List<AlmIssueEntity> docs = findRecentHits.toDocs();

        ServerInfoVO serverInfoVO = serverInfoService.verifyServerInfo("1000000000000000004");

        WebClient webClient = jiraUtil.createJiraCloudCommunicator(serverInfoVO.getUri(), serverInfoVO.getUserId(), serverInfoService.getDecryptPasswordOrToken(serverInfoVO.getPasswordOrToken()));

        Function<String,LinkedListVO> retrieveAlmF = (str)->this.issueList(webClient,jiraApi.getEndpoint().getIssue().getBase() + "/" + str + "?" + jiraApi.getParameter().getFields());

        new EsDataValidationTest(esCommonRepositoryWrapper,retrieveAlmF).dataValid(docs);

    }


    private LinkedListVO issueList( WebClient webClient, String endpoint) {
        Set<String> linkedIssueSet = new HashSet<>();
        CloudJiraIssueRawDataVO block = jiraUtil.getWithRawData(webClient, endpoint, CloudJiraIssueRawDataVO.class);
        Objects.requireNonNull(block)
            .getFields().getIssuelinks().stream().filter(Objects::nonNull)
                .forEach(a -> {
                    if(a.getInwardIssue()!=null){
                        linkedIssueSet.add(a.getInwardIssue().getKey());
                    }

                    if(a.getOutwardIssue()!=null){
                        linkedIssueSet.add(a.getOutwardIssue().getKey());
                    }
                });

        return new LinkedListVO(
                 Objects.requireNonNull(block).getFields().getProject().getKey()
                ,Objects.requireNonNull(block).getKey()
                ,linkedIssueSet.stream().toList()
        );
    }


}
