package com.cusc.nirvana.user.rnr.fp.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.MapUtils;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.exception.CuscUserException;
import com.cusc.nirvana.user.rnr.fp.dto.FpDirectTboxChangeDTO;
import com.cusc.nirvana.user.rnr.fp.service.IFpChangeTboxService;
import com.cusc.nirvana.user.rnr.mg.client.*;
import com.cusc.nirvana.user.rnr.mg.constants.RnrBizzTypeEnum;
import com.cusc.nirvana.user.rnr.mg.constants.RnrOrderStatusEnum;
import com.cusc.nirvana.user.rnr.mg.constants.RnrStatus;
import com.cusc.nirvana.user.rnr.mg.dto.MgCardNoticeDTO;
import com.cusc.nirvana.user.rnr.mg.dto.MgRnrCardInfoDTO;
import com.cusc.nirvana.user.rnr.mg.dto.RnrOrderDTO;
import com.cusc.nirvana.user.rnr.mg.dto.RnrRelationDTO;
import com.cusc.nirvana.user.util.CuscStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author changh
 * @date 2022/4/24
 */
@Service
@Slf4j
public class FpChangeTboxServiceImpl implements IFpChangeTboxService {

    @Resource
    private MgRnrCardInfoClient cardInfoClient;

    @Resource
    private MgRnrRelationClient rnrRelationClient;

    @Resource
    private MgSurplusBindClient mgSurplusBindClient;

    @Resource
    private IFpChangeTboxService changeTboxService;

    @Resource
    private RnrOrderClient rnrOrderClient;

    @Resource
    private OrgSimRelClient orgSimRelClient;


    /**
     * 卡换绑
     *
     * @return
     */
    @Override
    public Response submit(RnrRelationDTO relationDTO) {
        log.info("换卡fp入参:{}", JSON.toJSONString(relationDTO));
        List<MgRnrCardInfoDTO> unbindCardInfoDTOList = new ArrayList<>();
        List<MgRnrCardInfoDTO> bindCardInfoDTOList = new ArrayList<>();
        for (int i = 0; i < relationDTO.getCardList().size(); i++) {
            if (i < relationDTO.getCardList().size() / 2) {
                unbindCardInfoDTOList.add(relationDTO.getCardList().get(i));
            } else {
                bindCardInfoDTOList.add(relationDTO.getCardList().get(i));
            }

        }
        Response response = unbindCardList(unbindCardInfoDTOList);
        if (!response.isSuccess()) {
            return Response.createError("卡解绑失败");
        }
        return rnrRelationClient.saveRnrRelation(relationDTO);
    }

    @Override
    public Response<Boolean> unbindCardList(List<MgRnrCardInfoDTO> cardInfoDTOList) {
        log.info("换卡fp解绑入参:{}", JSON.toJSONString(cardInfoDTOList));
        for (MgRnrCardInfoDTO cardInfo : cardInfoDTOList) {
            cardInfo.setRnrStatus(RnrStatus.UNBOUND.getCode());
            //cardInfo.setRnrBizzType(RnrBizzTypeEnum.ChangeBinding.getCode());
        }
        return cardInfoClient.updateBatch(cardInfoDTOList);
    }

    @Override
    public Response<Boolean> bindCardList(List<MgRnrCardInfoDTO> cardInfoDTOList) {
        log.info("换卡fp绑定入参:{}", JSON.toJSONString(cardInfoDTOList));
        return cardInfoClient.insertBatch(cardInfoDTOList);
    }


    @Override
    public Response checkNewIccid(List<String> newCards) {
        log.info("换卡fp校验新iccid实名状态入参:{}", JSON.toJSONString(newCards));
        boolean checkResult = true;
        for (String iccid : newCards) {
            MgRnrCardInfoDTO infoDTO = new MgRnrCardInfoDTO();
            infoDTO.setIccid(iccid);
            Response<MgRnrCardInfoDTO> oneByIccid = cardInfoClient.getOneByIccid(infoDTO);
            log.info("换卡fp校验新iccid实名状态出参:{}", JSON.toJSONString(oneByIccid));
            if (!oneByIccid.isSuccess() || oneByIccid.getData() != null) {
                checkResult = false;
                break;
            }
        }
        return Response.createSuccess(checkResult);
    }


    @Override
    public Response queryResult() {
        //根据新的rnrid，查询短信状态--这里是从哪里查询
        return null;
    }

    @Override
    public Response directChangeBox(FpDirectTboxChangeDTO tboxChangeDTO) {

        List<String> oldIccids = new ArrayList<>(tboxChangeDTO.getNewOldIccidRelMap().values());
        List<MgRnrCardInfoDTO> oldCards = getOldIccidDTO(oldIccids, tboxChangeDTO.getVin());
        List<String> iccidList = oldCards.stream().map(a->a.getIccid()).collect(Collectors.toList());
        if (oldCards == null || oldCards.size() < 1) {
            return Response.createError("待解绑卡存在未实名");
        }
        List<MgRnrCardInfoDTO> newCards = createCardInfoDTOS(tboxChangeDTO, oldCards);
        Response unbindCards = changeTboxService.unbindCardList(oldCards);
        Response bindCards = changeTboxService.bindCardList(newCards);
        Response oldList = orgSimRelClient.updateBindIccid(iccidList);
//        orgSimRelClient.u

        //发送mq通知
        List<MgCardNoticeDTO> mgCardNoticeDTOS = createMqDTO(newCards, oldCards);

        MgRnrCardInfoDTO mgRnrCardInfoDTO = new MgRnrCardInfoDTO();

        List<MgRnrCardInfoDTO> mgRnrCardInfoDTOList = new ArrayList<>();

        for(MgRnrCardInfoDTO mgRnrCardInfo:newCards){
            mgRnrCardInfoDTO.setIccid(mgRnrCardInfo.getIccid());
            mgRnrCardInfoDTO.setIotId(mgRnrCardInfo.getIotId());
            mgRnrCardInfoDTOList.add(mgRnrCardInfoDTO);
        }
        orgSimRelClient.updateVin(mgRnrCardInfoDTOList);


        mgSurplusBindClient.sendMQ(mgCardNoticeDTOS);

        if (bindCards.isSuccess() && unbindCards.isSuccess() && oldList.isSuccess()) {
            return Response.createSuccess("更换设备成功");
        } else {
            return Response.createSuccess("更换设备失败", bindCards.getData());
        }
    }

    private List<MgRnrCardInfoDTO> getOldIccidDTO(List<String> iccids, String vin) {
        List<MgRnrCardInfoDTO> cardInfoDTOS = new ArrayList<>();
        MgRnrCardInfoDTO dto = new MgRnrCardInfoDTO();
        dto.setIotId(vin);
        Response<List<MgRnrCardInfoDTO>> listResponse = cardInfoClient.queryListByVin(dto);
        if (!listResponse.isSuccess()) {
            return cardInfoDTOS;
        }
        cardInfoDTOS = listResponse.getData().stream().filter(t -> iccids.contains(t.getIccid()) && t.getRnrStatus() == RnrStatus.RNR.getCode()).collect(Collectors.toList());
        return cardInfoDTOS;
    }

    private List<MgRnrCardInfoDTO> createCardInfoDTOS(FpDirectTboxChangeDTO tboxChangeDTO, List<MgRnrCardInfoDTO> oldCards) {
        List<String> newIccids = new ArrayList<>(tboxChangeDTO.getNewOldIccidRelMap().keySet());
        Map<String, MgRnrCardInfoDTO> oldCardMap = new HashMap<>();
        oldCards.forEach(mgRnrCardInfoDTO -> oldCardMap.put(mgRnrCardInfoDTO.getIccid(), mgRnrCardInfoDTO));
        List<MgRnrCardInfoDTO> cardInfoDTOS = new ArrayList<>();
        Map<String, String> relMap = tboxChangeDTO.getNewOldIccidRelMap();
        for (int i = 0; i < newIccids.size(); i++) {
            String iccid = newIccids.get(i);
            MgRnrCardInfoDTO mgRnrCardInfoDTO = new MgRnrCardInfoDTO();
            mgRnrCardInfoDTO.setUuid(CuscStringUtils.generateUuid());
            mgRnrCardInfoDTO.setIccid(iccid);
            mgRnrCardInfoDTO.setTenantNo(tboxChangeDTO.getTenantNo());
            mgRnrCardInfoDTO.setIotId(tboxChangeDTO.getVin());
            mgRnrCardInfoDTO.setRnrId(tboxChangeDTO.getRnrId());
            mgRnrCardInfoDTO.setOrderId(tboxChangeDTO.getOrderUuid());
            mgRnrCardInfoDTO.setCreator(tboxChangeDTO.getOperator());
            mgRnrCardInfoDTO.setOperator(tboxChangeDTO.getOperator());
            mgRnrCardInfoDTO.setRnrBizzType(RnrBizzTypeEnum.ChangeBinding.getCode());
            mgRnrCardInfoDTO.setRnrStatus(RnrStatus.RNR.getCode());
            mgRnrCardInfoDTO.setRoutingKey(tboxChangeDTO.getRoutingKey());

            //根据新旧卡的对应关系找到老卡的uuid进行赋值新卡字段oldCardId
            if (MapUtils.isNotEmpty(relMap)) {
                String oldIccid = relMap.get(iccid);
                MgRnrCardInfoDTO oldCardInfo = oldCardMap.get(oldIccid);
                if (null != oldCardInfo) {
                    mgRnrCardInfoDTO.setOldCardId(oldCardInfo.getUuid());
                }
            }
            cardInfoDTOS.add(mgRnrCardInfoDTO);
        }
        return cardInfoDTOS;
    }


    private List<MgCardNoticeDTO> createMqDTO(List<MgRnrCardInfoDTO> newIccids, List<MgRnrCardInfoDTO> oldIccids) {
        List<MgCardNoticeDTO> cardNoticeDTOS = new ArrayList<>();
        for (int i = 0; i < newIccids.size(); i++) {
            RnrOrderDTO rnrOrderDTO = new RnrOrderDTO();
            rnrOrderDTO.setUuid(newIccids.get(i).getOrderId());
            Response<RnrOrderDTO> response = rnrOrderClient.getByUuid(rnrOrderDTO);
            if(!response.isSuccess()){
                throw new CuscUserException(response.getCode(),response.getMsg());
            }
            MgCardNoticeDTO mgCardNoticeDTO = new MgCardNoticeDTO();
            mgCardNoticeDTO.setIccid(newIccids.get(i).getIccid());
            mgCardNoticeDTO.setOldIccid(oldIccids.get(i).getIccid());
            //mgCardNoticeDTO.setRnrId(newIccids.get(i).getRnrId());
            mgCardNoticeDTO.setTenantNo(newIccids.get(i).getTenantNo());
            mgCardNoticeDTO.setVin(newIccids.get(i).getIotId());
            mgCardNoticeDTO.setRnrBizzType(newIccids.get(i).getRnrBizzType());
            mgCardNoticeDTO.setOrderId(newIccids.get(i).getOrderId());
            mgCardNoticeDTO.setResultCode(RnrOrderStatusEnum.PASS.getCode());
            mgCardNoticeDTO.setOrgId(response.getData().getOrgId());
            //mgCardNoticeDTO.setOperationType(RnrBizzTypeEnum.ChangeBinding.getCode());
            cardNoticeDTOS.add(mgCardNoticeDTO);
        }
        return cardNoticeDTOS;
    }
}
