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.serverinfo.model.vo.ServerInfoVO;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.alm.JiraUtil;
import com.arms.egovframework.javaservice.esframework.model.vo.DocumentResultWrapper;
import com.arms.egovframework.javaservice.esframework.repository.common.EsCommonRepositoryWrapper;
import com.arms.egovframework.javaservice.esframework.esquery.SimpleQuery;
import com.atlassian.jira.rest.client.api.IssueRestClient;
import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.IssueLink;
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 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 JiraDiscoveryTest extends WireMockJiraConfig {

    @Autowired
    IssueService issueService;

    @MockitoBean
    CategoryMappingService categoryMappingService;

    @Autowired
    JiraUtil jiraUtil;

    @Autowired
    EsCommonRepositoryWrapper<AlmIssueEntity> esCommonRepositoryWrapper;

    @Autowired
    ServerInfoService serverInfoService;

    @BeforeEach
    void 요구사항키_셋업() {
        esCommonRepositoryWrapper.deleteIndex(-1);
        esCommonRepositoryWrapper.saveEmpty(new AlmIssueEntity());

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

        List<String> issueKeys = List.of("ARMSJIRASE-26", "ARMSJIRASE-27", "ARMSJIRASE-28", "ARMSJIRASE-37", "ARMSJIRASE-43" );

        for (String issueKey : issueKeys) {
            AlmIssueWithRequirementDTO almIssueWithRequirementDTO = new AlmIssueWithRequirementDTO();
            almIssueWithRequirementDTO.setJiraServerId("1000000000000000001");
            almIssueWithRequirementDTO.setIssueKey(issueKey);
            almIssueWithRequirementDTO.setServiceId(1L);
            almIssueWithRequirementDTO.setVersions(List.of(1L));
            almIssueWithRequirementDTO.setProjectKeyOrId("ARMSJIRASE");
            almIssueWithRequirementDTO.setCReqLink(1L);
            CReqProperty cReqProperty = new CReqProperty();
            cReqProperty.setCReqPriorityLink(1L);
            almIssueWithRequirementDTO.setCReqProperty(cReqProperty);

            issueService.preSaveReqStatus(almIssueWithRequirementDTO);

        }

        List<String> issueKeys2 = List.of("ARNN-5" );

        for (String issueKey : issueKeys2) {
            AlmIssueWithRequirementDTO almIssueWithRequirementDTO = new AlmIssueWithRequirementDTO();
            almIssueWithRequirementDTO.setJiraServerId("1000000000000000001");
            almIssueWithRequirementDTO.setIssueKey(issueKey);
            almIssueWithRequirementDTO.setServiceId(1L);
            almIssueWithRequirementDTO.setVersions(List.of(1L));
            almIssueWithRequirementDTO.setProjectKeyOrId("ARNN");
            almIssueWithRequirementDTO.setCReqLink(1L);
            CReqProperty cReqProperty = new CReqProperty();
            cReqProperty.setCReqPriorityLink(1L);
            almIssueWithRequirementDTO.setCReqProperty(cReqProperty);

            issueService.preSaveReqStatus(almIssueWithRequirementDTO);

        }

    }

    @Test
    public void 지라_증분_테스트_2025_01_01_2025_07_27() throws Exception {

        List<String> values = Arrays.asList("ARMSJIRASE", "ARNN");
        Collections.shuffle(values);
        for (String projectKey : values) {
            AlmIssueIncrementDTO almIssueIncrementDTO = AlmIssueIncrementDTO.builder()
                    .serverId("1000000000000000001")
                    .projectKey(projectKey)
                    .startDate("2025-01-01")
                    .endDate("2025-07-27")
                    .build();
            List<AlmIssueEntity> almIssueEntities = issueService.discoveryIncrementALmIssueAndGetReqAlmIssueEntities(almIssueIncrementDTO);
        }

        지라_데이터_검증();
    }

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


        List<String> projects = Arrays.asList("ARMSJIRASE", "ARNN");
        Collections.shuffle(projects);
        for (String projectKey : projects) {
            AlmIssueIncrementDTO almIssueIncrementDTO = AlmIssueIncrementDTO.builder()
                    .serverId("1000000000000000001")
                    .projectKey(projectKey)
                    .startDate("2025-01-01")
                    .endDate("2025-07-27")
                    .build();
            List<AlmIssueEntity> almIssueEntities = issueService.discoveryIncrementALmIssueAndGetReqAlmIssueEntities(almIssueIncrementDTO);
        }


        지라_데이터_검증();
    }


    public void 지라_데이터_검증(){

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

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

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

        JiraRestClient restClient = jiraUtil.createJiraOnPremiseCommunicator(serverInfoVO.getUri(),
                serverInfoVO.getUserId(),
                serverInfoService.getDecryptPasswordOrToken(serverInfoVO.getPasswordOrToken()));

        Function<String,LinkedListVO> retrieveAlmF = (str)->this.issueList(str,restClient);

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


    private LinkedListVO issueList( String key, JiraRestClient jiraRestClient) {

        Set<String> linkedIssueSet = new HashSet<>();

        Issue claim = jiraRestClient.getIssueClient().getIssue(key, List.of(IssueRestClient.Expandos.CHANGELOG)).claim();

        Iterable<IssueLink> issueLinks = claim.getIssueLinks();

        Objects.requireNonNull(issueLinks)
                .forEach(
                        a->{
                            linkedIssueSet.add(a.getTargetIssueKey());
                        }
                );

        return new LinkedListVO(claim.getProject().getKey(),claim.getKey(),linkedIssueSet.stream().toList());
    }

}
