package com.icomsys.main_vm.biz.common.system.service;

import com.google.gson.Gson;
import com.icomsys.main_vm.biz.advice.excep.CustomNotFoundException;
import com.icomsys.main_vm.biz.common.login.res.UserVo;
import com.icomsys.main_vm.biz.common.login.service.LoginService;
import com.icomsys.main_vm.biz.common.system.vo.*;
import com.icomsys.main_vm.common.code.MenuVo;
import com.icomsys.main_vm.common.code.code.UseYNCode;
import com.icomsys.main_vm.db.jpa.entity.system.TbCustPolicy;
import com.icomsys.main_vm.db.jpa.entity.system.TbIcsOprMngInfo;
import com.icomsys.main_vm.db.jpa.entity.system.TbServiceGrouop;
import com.icomsys.main_vm.db.jpa.entity.system.id.TbCustPolicyId;
import com.icomsys.main_vm.db.jpa.repo.conversation.TbProjectSettingRepo;
import com.icomsys.main_vm.db.jpa.repo.system.TbCustPolicyRepo;
import com.icomsys.main_vm.db.jpa.repo.system.TbIcsOprMngInfoRepo;
import com.icomsys.main_vm.db.jpa.repo.system.TbServiceGrouopRepo;
import com.icomsys.main_vm.db.jpa.repo.system.TbServiceGroupPolicyRepo;
import com.querydsl.core.QueryResults;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class SystemServiceGroupService {
    private final TbServiceGrouopRepo tbServiceGrouopRepo;
    private final TbCustPolicyRepo tbCustPolicyRepo;
    private final LoginService loginService;
    private final TbIcsOprMngInfoRepo tbIcsOprMngInfoRepo;
    private final TbServiceGroupPolicyRepo tbServiceGroupPolicyRepo;
    private final TbProjectSettingRepo tbProjectSettingRepo;
    private final SystemCustService systemCustService;


    @Transactional(readOnly = true)
    public QueryResults<SystemServiceGroupRes> ServiceGroupList(SystemServiceGroupReq dto) {
        QueryResults<SystemServiceGroupRes> result = tbServiceGrouopRepo.ServiceGroupList(dto);
        return result;
    }

    public SystemServiceGroupViewRes ServiceGroupSelect() {
        return ServiceGroupSelect(loginService.getUserVo().getLastUseServiceGroup());
    }

    @Transactional(readOnly = true)
    public SystemServiceGroupViewRes ServiceGroupSelect(String serviceGroup) {

        SystemServiceGroupViewRes result = new SystemServiceGroupViewRes();
        List<SystemServiceGroupViewSubListRes> sub = new ArrayList<>();
        List<SystemServiceGroupViewVo> selectService = tbServiceGrouopRepo.getServiceGroupView(serviceGroup);

        for (SystemServiceGroupViewVo e : selectService) {
            if (e.getServiceType().equals("M")) {
                List<String> pol = tbCustPolicyRepo.findByServiceGroup(e.getServiceGroup()).stream()
                        .map(f -> f.getPolicyVal()).collect(Collectors.toList());
                result.setPolicyParent(loginService.jstreeParentConvertToPolicy());
                result.setMainPolicyVal(pol);
                result.setMainMenu(loginService.authToAuthList(pol, 10000000));
                result.setCustCode(e.getCustCode());
                result.setMainServiceGroup(e.getServiceGroup());
                result.setMainServiceGroupName(e.getServiceGroupName());
                result.setMainServiceGroupDesc(e.getServiceGroupDesc());
                result.setMainUseYn(e.getUseYn());
                result.setMainOprMngCode(e.getOprMngCode());
            }
//            else {
                sub.add(SystemServiceGroupViewSubListRes
                        .builder()
                        .subServiceGroup(e.getServiceGroup())
                        .subServiceGroupName(e.getServiceGroupName())
                        .subServiceGroupDesc(e.getServiceGroupDesc())
                        .subUseYn(e.getUseYn())
                        .subOprMngCode(e.getOprMngCode())
                        .subPolicyVal(tbCustPolicyRepo.findByServiceGroup(e.getServiceGroup()).stream()
                                .map(f -> f.getPolicyVal()).collect(Collectors.toList()))
                        .build());
//            }
        }


        result.setSubService(sub);
//        log.info(" servicegroup - {} ", new Gson().toJson(result));
        return result;
    }

    @Transactional(readOnly = true)
    public List<String> SelectPolicy(String serviceGroup) {
        return tbCustPolicyRepo.findByServiceGroup(serviceGroup).stream().map(e -> e.getPolicyVal()).collect(Collectors.toList());
    }

    @Transactional
    public void ServiceGroupUpdate(SystemServiceGroupUpdateReq dto) throws CustomNotFoundException {
        List<String> modifySubVal = new ArrayList<>();
        List<String> insertSubVal = new ArrayList<>();
        List<String> delVal = new ArrayList<>();
        List<TbCustPolicyId> deleId = new ArrayList<>();
        List<TbCustPolicy> insertId = new ArrayList<>();
        modifySubVal = dto.getSubPolicyVal();
        insertSubVal = dto.getSubPolicyVal();

        log.info("system/serviceGroup/update - {}",new Gson().toJson(dto));

        TbServiceGrouop tsg = tbServiceGrouopRepo.findByServiceGroup(dto.getSubServiceGroup()).orElseThrow(() -> new CustomNotFoundException()).toUpdateSubService(dto, loginService.getUserVo());

        List<String> beforVal = tbCustPolicyRepo.findByServiceGroup(dto.getSubServiceGroup())
                .stream()
                .map(f -> f.getPolicyVal())
                .collect(Collectors.toList());

        for (String e : beforVal) {
            if (modifySubVal.contains(e)) {
                insertSubVal.remove(e);
            } else {
                delVal.add(e);
                deleId.add(TbCustPolicyId.builder()
                        .custCode(dto.getCustCode())
                        .serviceGroup(dto.getSubServiceGroup())
                        .policyVal(e)
                        .build());
            }
        }

        if (insertSubVal.size() > 0) {
            for (String e : insertSubVal) {
                insertId.add(TbCustPolicy.builder()
                        .custCode(dto.getCustCode())
                        .serviceGroup(dto.getSubServiceGroup())
                        .policyVal(e)
                        .build());
            }
        }
        tbCustPolicyRepo.deleteAllById(deleId);
        tbCustPolicyRepo.saveAll(insertId);
        tbServiceGroupPolicyRepo.deleteByServiceGroupAndPolicyValIn(dto.getSubServiceGroup(), delVal);
    }

    @Transactional
    public void ServiceGroupInsert(SystemServiceGroupUpdateReq dto) throws CustomNotFoundException {
        log.info("ServiceGroupInsert - {}", new Gson().toJson(dto));
        UserVo uv = loginService.getUserVo();
        tbServiceGrouopRepo.save(TbServiceGrouop.builder()
                .serviceGroup(dto.getSubServiceGroup().toUpperCase())
                .serviceGroupUpper(dto.getMainServiceGroup().toUpperCase())
                .custCode(dto.getCustCode())
                .serviceType("S")
                .serviceGroupName(dto.getSubServiceGroupName())
                .serviceGroupDesc(dto.getSubServiceGroupDesc())
                .useYn(dto.getSubUseYn())
                .registId(uv.getUserId())
                .registDate(LocalDateTime.now())
                .updateId(uv.getUserId())
                .updateDate(LocalDateTime.now())
                .build());
        tbCustPolicyRepo.saveAll(dto.getSubPolicyVal().stream()
                .map(e -> TbCustPolicy.builder()
                        .custCode(dto.getCustCode())
                        .serviceGroup(dto.getSubServiceGroup().toUpperCase())
                        .policyVal(e)
                        .build())
                .collect(Collectors.toList()));
        tbIcsOprMngInfoRepo.save(TbIcsOprMngInfo.builder()
                .custCode(dto.getCustCode())
                .serviceGroup(dto.getSubServiceGroup().toUpperCase())
                .oprMngCode(dto.getCustCode()+"_RCP_"+dto.getSubServiceGroup().toUpperCase())
                .solVal("RCP")
                .routeUrl("")
                .useYn(dto.getSubUseYn())
                .registId(uv.getUserId())
                .registDate(LocalDateTime.now())
                .updateId(uv.getUserId())
                .updateDate(LocalDateTime.now())
                .build());
        List<WisenutInsertReqVo> proSet = new ArrayList<>();
        proSet.add(WisenutInsertReqVo.builder()
                        .oprMngCode(dto.getCustCode()+"_RCP_"+dto.getSubServiceGroup())
                        .serviceGroupDesc(dto.getSubServiceGroupDesc())
                .build());
//        tbProjectSettingRepo.saveAll(systemCustService.WisenutInsert(proSet));
    }


    public String ServiceGroupDoubleCheck(SystemServiceGroupUpdateReq dto) {
        log.info("ServiceGroupDoubleCheck - {}", new Gson().toJson(dto));
        if (tbServiceGrouopRepo.existsByCustCodeAndServiceGroup(dto.getCustCode(), dto.getSubServiceGroup().toUpperCase())) {
            return UseYNCode.N.name();
        } else {
            return UseYNCode.Y.name();
        }
    }


}

