package com.arms.api.wbs.service;

import com.arms.api.kafka.reqadd.model.ReqAddDTO;
import com.arms.api.kafka.reqadd.service.ReqAddProxyServiceSync;
import com.arms.api.util.communicate.external.백엔드코어통신기;
import com.arms.api.util.response.CommonResponse;
import com.arms.api.wbs.model.dto.ServerDataDTO;
import com.arms.api.wbs.model.vo.ReqAddAndWbsRowVO;
import com.arms.api.wbs.model.vo.WbsRowVO;
import com.arms.api.wbs.repository.WbsRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static com.arms.api.wbs.model.enums.ReqPriorityMapper.*;

@Slf4j
@Service
@AllArgsConstructor
public class WbsServiceImpl implements WbsService{

    private final WbsRepository wbsRepository;

    private final ReqAddProxyServiceSync reqAddProxyServiceSync;

    private final ObjectMapper objectMapper;

    private final 백엔드코어통신기 백엔드코어통신기;

    @Override
    public WbsRowVO wbsRowVO(String id) {
        return wbsRepository.findById(id).orElse(new WbsRowVO());
    }

    @Override
    public List<WbsRowVO> saveAllThenGetWbsRowVOS(ReqAddAndWbsRowVO reqAddAndWbsRowVO) {

        List<WbsRowVO> wbsRowVOS = reqAddAndWbsRowVO.getWbsRowVOS();

        wbsRowVOS.forEach(row -> row.idByServiceId(reqAddAndWbsRowVO.getPdServiceId()));

        wbsRepository.saveAll(wbsRowVOS);

        List<WbsRowVO> wbsRowVOSByServiceId = findByServiceId(reqAddAndWbsRowVO.getPdServiceId());

        wbsRowVOSByServiceId.forEach(a -> {
            ServerDataDTO data = a.getData();
            try {

                String changeReqTableName = "T_ARMS_REQADD_" + reqAddAndWbsRowVO.getPdServiceId();

                CommonResponse.ApiResult<Long> getReqAddCIdTitle
                        = 백엔드코어통신기.getReqAddCIdTitle(changeReqTableName,data.getJobName());

                Long cId = getReqAddCIdTitle.getResponse();

                String payload = objectMapper.writeValueAsString(
                    ReqAddDTO.builder()
                        .c_id(cId)
                        .c_title(data.getJobName())
                        .c_req_pdservice_link(reqAddAndWbsRowVO.getPdServiceId())
                        .c_req_pdservice_versionset_link(reqAddAndWbsRowVO.getPdServiceVersion())
                        .c_req_urgency_link(mapUrgency(data.getUrgency()))
                        .c_req_importance_link(mapImportance(data.getImportance()))
                        .c_req_difficulty_link(mapDifficulty(data.getDifficulty()))
                        .c_req_priority_value(Double.valueOf(data.getPriority()))
                        .ref(2L)
                        .c_type("default")
                        .c_req_contents("<p>요구사항 내용을 기록합니다.</p>\n")
                        .c_req_desc("설명")
                        .c_req_etc("비고")
                        .c_req_state_link(10L)
                        .c_req_reviewer01("none")
                        .c_req_reviewer02("none")
                        .c_req_reviewer03("none")
                        .c_req_reviewer04("none")
                        .c_req_reviewer05("none")
                        .c_req_reviewer01_status("Draft")
                        .c_req_reviewer02_status("Draft")
                        .c_req_reviewer03_status("Draft")
                        .c_req_reviewer04_status("Draft")
                        .c_req_reviewer05_status("Draft")
                        .c_req_owner("admin")
                        .c_req_writer("[admin] - 9af24080-050d-4943-b40e-d789c0f976ee")
                    .build());

                if(cId == null){
                    reqAddProxyServiceSync
                        .publishToKafka("ADD_NODE", "POST", changeReqTableName, payload)
                        .subscribe(
                                result -> {
                                    WbsRowVO wbsRowVO = wbsRepository.findById(a.getId()).get();
                                    wbsRowVO.setRequestComplete();
                                    wbsRepository.save(wbsRowVO);

                                },
                                error -> {}
                        );
                }else{
                    reqAddProxyServiceSync
                            .publishToKafka("UPDATE_NODE", "POST", changeReqTableName, payload)
                            .subscribe(
                                    result -> {
                                        WbsRowVO wbsRowVO = wbsRepository.findById(a.getId()).get();
                                        wbsRowVO.setRequestComplete();
                                        wbsRepository.save(wbsRowVO);
                                    },
                                    error -> {}
                            );
                }
            } catch (JsonProcessingException e) {
                log.error("ReqAddDTO JSON 직렬화 실패: {}", e.getMessage(), e);
            }
        });

        return wbsRowVOSByServiceId;
    }

    @Override
    public List<WbsRowVO> findByServiceId(Long serviceId) {
        List<String> ids = wbsRepository.scan(serviceId + ":*");
        return StreamSupport.stream(wbsRepository.findAllById(ids).spliterator(), false)
                .collect(Collectors.toList());
    }


    @Override
    public void deleteById(String pattern){
        wbsRepository.deleteByPattern(pattern);
    }

}
