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

import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.rnr.fp.common.ResponseCode;
import com.cusc.nirvana.user.rnr.fp.dto.VehicleUnboundVerifyRequestDTO;
import com.cusc.nirvana.user.rnr.fp.dto.VerifyVinCardResponseDTO;
import com.cusc.nirvana.user.rnr.fp.dto.VinCardDTO;
import com.cusc.nirvana.user.rnr.fp.dto.VinCardVerityResult;
import com.cusc.nirvana.user.rnr.fp.service.IVehicleRnrUnBoundService;
import com.cusc.nirvana.user.rnr.mg.client.MgRnrCardInfoClient;
import com.cusc.nirvana.user.rnr.mg.client.MgRnrCompanyInfoClient;
import com.cusc.nirvana.user.rnr.mg.client.MgRnrUnboundClient;
import com.cusc.nirvana.user.rnr.mg.client.MgVehicleCompanyClient;
import com.cusc.nirvana.user.rnr.mg.constants.NoticeStatusEnum;
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.MgRnrCardInfoDTO;
import com.cusc.nirvana.user.rnr.mg.dto.MgRnrCompanyInfoDTO;
import com.cusc.nirvana.user.rnr.mg.dto.MgVehicleCompanyDTO;
import com.cusc.nirvana.user.rnr.mg.dto.VehicleUnbindDTO;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yubo
 * @since 2022-04-24 17:13
 */
@Service
public class VehicleRnrUnBoundServiceImpl implements IVehicleRnrUnBoundService {

    @Resource
    private MgRnrCardInfoClient cardInfoClient;

    @Resource
    private MgRnrCompanyInfoClient companyInfoClient;

    @Resource
    private MgRnrUnboundClient mgRnrUnboundClient;

    @Resource
    private MgVehicleCompanyClient vehicleCompanyClient;

    @Override
    public Response<VerifyVinCardResponseDTO> verifyUnboundVinCardBatch(VehicleUnboundVerifyRequestDTO responseDTO) {
        return verifyUnboundVinCardBatch(responseDTO.getCardDTOS(), responseDTO.getTenantNo(), null, null);
    }

    @Override
    public Response batchUnbound(VehicleUnbindDTO requestDTO) {

        List<String> cardIds = new ArrayList<>();
        List<String> rnrIds = new ArrayList<>();

        List<VinCardDTO> cardDTOs = requestDTO.getCardList().stream()
                .map(card -> new VinCardDTO(card.getIotId(), card.getIccid(),null,null))
                .collect(Collectors.toList());
        //获取校验结果
        Response<VerifyVinCardResponseDTO> response = verifyUnboundVinCardBatch(cardDTOs, requestDTO.getInfo().getTenantNo(), cardIds, rnrIds);
        if (!response.isSuccess()) {
            return Response.createError(response.getMsg(), response.getCode());
        }

        //校验结果处理，计算失败次数
        List<VinCardVerityResult> iccidVerifyResults = response.getData().getIccidVerifyResults();
        int failCount = (int) iccidVerifyResults.stream().filter(r -> !r.isExist()).count();

        if (iccidVerifyResults.isEmpty()) {
            return Response.createError("没有需要解绑的记录", ResponseCode.INVALID_DATA.getCode());
        }
        if (failCount > 0) {
            return Response.createError("存在未绑定的记录", ResponseCode.INVALID_DATA.getCode());
        }

        requestDTO.getOrder().setOrderStatus(RnrOrderStatusEnum.PASS.getCode());
        requestDTO.getInfo().setRnrStatus(RnrStatus.UNBOUND.getCode());

        requestDTO.setRnrIds(rnrIds);
        requestDTO.setCardIds(cardIds);
        requestDTO.getCardList().stream().forEach(c -> {
            c.setRnrStatus(RnrStatus.UNBOUND.getCode());
            c.setNoticeStatus(NoticeStatusEnum.NONEED.getCode());
        });

        return mgRnrUnboundClient.batchUnbound(requestDTO);
    }

    //--------------- 私有方法区

    /**
     * 验证车卡信息
     */
    private Response<VerifyVinCardResponseDTO> verifyUnboundVinCardBatch(List<VinCardDTO> cardDTOS, String tenantNo, List<String> cardIds, List<String> rnrIds) {
        Map<String, Map<String, MgRnrCardInfoDTO>> vinCardMap = Maps.newHashMap();
        List<VinCardVerityResult> iccidVerifyResults = new ArrayList<>();
        VinCardVerityResult verityResult;

        if (StringUtils.isBlank(tenantNo)) {
            return Response.createError("租户编号不能为空", ResponseCode.INVALID_DATA.getCode());
        }

        //查询公司名下所有实名业务
        MgVehicleCompanyDTO vehicleCompanyDTO = new MgVehicleCompanyDTO();
        vehicleCompanyDTO.setTenantNo(tenantNo);
        Response<MgVehicleCompanyDTO> vcResp = vehicleCompanyClient.getVehicleCompany(vehicleCompanyDTO);
        if (vcResp == null || !vcResp.isSuccess() || vcResp.getData() == null) {
            return Response.createError("未查询到对应的车企信息", ResponseCode.INVALID_DATA.getCode());
        }
        vehicleCompanyDTO = vcResp.getData();

        //查询公司的业务信息
        MgRnrCompanyInfoDTO mgRnrCompanyInfoDTO = new MgRnrCompanyInfoDTO();
        mgRnrCompanyInfoDTO.setCompanyName(vehicleCompanyDTO.getCompanyName());
        Response<List<String>> response = companyInfoClient.findRnrIdsByCompanyName(mgRnrCompanyInfoDTO);
        if (!response.isSuccess()) {
            return Response.createError(response.getMsg(), response.getCode());
        }
        Set<String> rnrIdSet = new HashSet<>(response.getData());

        for (VinCardDTO verifyDTO : cardDTOS) {
            String vin = verifyDTO.getVin();
            String iccid = verifyDTO.getIccid();

            //根据vin获取已绑定的iccid map
            Map<String, MgRnrCardInfoDTO> map = vinCardMap.get(vin);
            if (map == null) {
                MgRnrCardInfoDTO mgRnrCardInfoDTO = new MgRnrCardInfoDTO();
                mgRnrCardInfoDTO.setIotId(vin);
                mgRnrCardInfoDTO.setRnrBizzType(RnrBizzTypeEnum.Bind.getCode());
                Response<List<MgRnrCardInfoDTO>> listResponse = cardInfoClient.queryBindListByVinAndBizType(mgRnrCardInfoDTO);
                if (!listResponse.isSuccess()) {
                    return Response.createError(listResponse.getMsg(), listResponse.getCode());
                }
                map = listResponse.getData().stream().collect(Collectors.toMap(MgRnrCardInfoDTO::getIccid, dto -> dto));
                vinCardMap.put(vin, map);
            }

            //校验
            verityResult = new VinCardVerityResult();
            verityResult.setVin(vin);
            verityResult.setIccid(iccid);

            String msg = "";
            boolean bind = true;
            if (!map.containsKey(iccid)) {
                msg = "车辆[" + vin + "]和卡[" + iccid + "]未绑定";
                bind = false;
            } else if (!rnrIdSet.contains(map.get(iccid).getRnrId())) {
                //只能解绑自己公司的卡
                msg = "没有权限解绑";
                bind = false;
            }

            verityResult.setExist(bind);
            verityResult.setMsg(msg);
            iccidVerifyResults.add(verityResult);

            if (cardIds != null && bind) {
                cardIds.add(map.get(iccid).getUuid());
            }
            if (rnrIds != null && bind) {
                rnrIds.add(map.get(iccid).getRnrId());
            }
        }
        return Response.createSuccess(new VerifyVinCardResponseDTO(iccidVerifyResults));
    }
}
