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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cusc.nirvana.common.result.BaseEnum;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.exception.CuscUserException;
import com.cusc.nirvana.user.rnr.fp.constants.BizTypeEnum;
import com.cusc.nirvana.user.rnr.fp.dao.entity.FpRnrSmsInfoPO;
import com.cusc.nirvana.user.rnr.fp.dto.*;
import com.cusc.nirvana.user.rnr.fp.service.IFpRnrSmsInfoService;
import com.cusc.nirvana.user.rnr.fp.service.IFpSurplusCardBindService;
import com.cusc.nirvana.user.rnr.fp.service.IRnrService;
import com.cusc.nirvana.user.rnr.fp.service.ShortMessageCheckService;
import com.cusc.nirvana.user.rnr.mg.client.MgSurplusBindClient;
import com.cusc.nirvana.user.rnr.mg.client.RnrOrderClient;
import com.cusc.nirvana.user.rnr.mg.constants.NoticeStatusEnum;
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.RnrOrderDTO;
import com.cusc.nirvana.user.rnr.mg.dto.RnrRelationDTO;
import com.cusc.nirvana.user.rnr.mg.dto.SurplusConfirmDto;
import com.cusc.nirvana.user.util.CuscStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yubo
 * @since 2022-05-03 17:01
 */
@Service
@Slf4j
public class FpSurplusCardBindServiceImpl implements IFpSurplusCardBindService {

    @Autowired
    MgSurplusBindClient surplusBindClient;

    @Autowired
    ShortMessageCheckService messageCheckService;

    @Autowired
    private IFpRnrSmsInfoService smsInfoService;

    @Autowired
    private IRnrService rnrService;

    @Autowired
    private RnrOrderClient orderClient;

    @Value("${message.callback.timeout:120}")
    private int timeOut;

    /**
     * 一车多卡绑定
     *
     * @param dto
     * @return
     */
    @Override
    public Response surplusCardBind(RnrRelationDTO dto) {
        rnrService.cardNumberCheck(dto);

        dto.getCardList().forEach(card -> {
            card.setRnrStatus(RnrStatus.INIT.getCode());
            card.setNoticeStatus(NoticeStatusEnum.NONEED.getCode());
        });
        Response response = surplusBindClient.saveSurplusRnrRelation(dto);
        if (!response.isSuccess()) {
            throw new CuscUserException(response.getCode(), response.getMsg());
        }

        //发送短信
        response = sendMessage(dto);
        if (!response.isSuccess()) {
            throw new CuscUserException(response.getCode(), response.getMsg());
        }
        return Response.createSuccess(BaseEnum.SUCCESS.getMsg(), dto.getOrder().getUuid());
    }

    /**
     * 一车多卡绑定 不发短信 默认确认以及工单状态也默认通过
     *
     * @param dto
     * @return
     */
    @Override
    public Response surplusCardBindDirect(RnrRelationDTO dto) {
        rnrService.cardNumberCheck(dto);

        dto.getCardList().forEach(card -> {
            card.setRnrStatus(RnrStatus.INIT.getCode());
            card.setNoticeStatus(NoticeStatusEnum.NONEED.getCode());
        });
        Response response = surplusBindClient.saveSurplusRnrRelation(dto);
        if (!response.isSuccess()) {
            throw new CuscUserException(response.getCode(), response.getMsg());
        }

        return Response.createSuccess(BaseEnum.SUCCESS.getMsg(), dto.getOrder().getUuid());
    }

    /**
     * 短信回调
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean confirm(SurplusConfirmDto dto) {
        Response<Boolean> booleanResponse = surplusBindClient.surplusConfirm(dto);
        if (!booleanResponse.isSuccess()) {
            throw new CuscUserException(booleanResponse.getCode(), booleanResponse.getMsg());
        }
        return true;
    }

    /**
     * 查询结果
     *
     * @param bean
     * @return
     */
    @Override
    public SurplusQueryResponseDTO queryResult(SurplusQueryRequestDTO bean) {
        SurplusQueryResponseDTO responseDTO = new SurplusQueryResponseDTO();

        long currentTimeMillis = System.currentTimeMillis();

        //查询工单信息
        RnrOrderDTO rnrOrderDTO = new RnrOrderDTO();
        rnrOrderDTO.setUuid(bean.getOrderId());
        Response<RnrOrderDTO> byUuid = orderClient.getByUuid(rnrOrderDTO);
        if (!byUuid.isSuccess() || byUuid.getData() == null) {
            throw new CuscUserException("", "查询工单信息失败：" + byUuid.getMsg());
        }

        //
        rnrOrderDTO = byUuid.getData();
        if (!RnrOrderStatusEnum.notFinished(rnrOrderDTO.getOrderStatus())) {
            responseDTO.setOrderId(rnrOrderDTO.getUuid());
            responseDTO.setOrderStatus(rnrOrderDTO.getOrderStatus());
            return responseDTO;
        }

        //查询短信信息
        QueryWrapper<FpRnrSmsInfoPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", bean.getOrderId());
        queryWrapper.orderByDesc("create_time");
        List<FpRnrSmsInfoPO> list = smsInfoService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            throw new CuscUserException("", "获取短信信息失败");
        }

        //校验时间
        long time = list.get(0).getCreateTime().getTime();

        log.info("判断超时,{},{},{},{}", currentTimeMillis, timeOut, time, currentTimeMillis - timeOut * 1000);

        if (currentTimeMillis - timeOut * 1000 > time) {
            log.info("短信回复超时，设置成失败状态");

            throw new CuscUserException("", "回复短信超时");

//            SurplusConfirmDto confirmDto = new SurplusConfirmDto();
//            confirmDto.setOrderId(bean.getOrderId());
//            confirmDto.setCallbackStatusEnum(MessageCallbackStatusEnum.TIMEOUT.getCode());
//            Response<Boolean> response = surplusBindClient.surplusConfirm(confirmDto);
//            if (!response.isSuccess()) {
//                throw new CuscUserException(response.getCode(), "回复短信超时：" + response.getMsg());
//            }
//
//            //重新获取工单状态
//            rnrOrderDTO.setUuid(bean.getOrderId());
//            byUuid = orderClient.getByUuid(rnrOrderDTO);
//            if (!byUuid.isSuccess() || byUuid.getData() == null) {
//                throw new CuscUserException("", "查询工单信息失败：" + byUuid.getMsg());
//            }
//            responseDTO.setOrderId(byUuid.getData().getUuid());
//            responseDTO.setOrderStatus(byUuid.getData().getOrderStatus());
//            return responseDTO;
        } else {
            //未超时直接返回状态
            responseDTO.setOrderId(rnrOrderDTO.getUuid());
            responseDTO.setOrderStatus(rnrOrderDTO.getOrderStatus());
            return responseDTO;
        }

    }

    /**
     * 发送短信
     *
     * @param relationDTO
     */
    @Override
    @Transactional
    public Response sendMessage(RnrRelationDTO relationDTO) {
        SmsRequestDTO smsRequestDTO = toSmsRequestDto(relationDTO);

        //短信入库
        FpRnrSmsInfoDTO fpRnrSmsInfoDTO = new FpRnrSmsInfoDTO();
        fpRnrSmsInfoDTO.setIsDelete(0);
        fpRnrSmsInfoDTO.setCreateTime(new Date(System.currentTimeMillis()));
        fpRnrSmsInfoDTO.setUuid(CuscStringUtils.generateUuid());
        fpRnrSmsInfoDTO.setSendPhone(smsRequestDTO.getPhone());
        fpRnrSmsInfoDTO.setRnrId(relationDTO.getInfo().getUuid());
        fpRnrSmsInfoDTO.setOrderId(relationDTO.getOrder().getUuid());
        fpRnrSmsInfoDTO.setIccids(relationDTO.getCardList().stream().map(c -> c.getIccid())
                .collect(Collectors.joining(",")));
        fpRnrSmsInfoDTO.setSendContent(smsRequestDTO.getParams().toString());
        fpRnrSmsInfoDTO.setBizType(MessageBizTypeEnum.BIND.getCode());
        fpRnrSmsInfoDTO.setCreator(relationDTO.getInfo().getCreator());
        fpRnrSmsInfoDTO.setOperator(relationDTO.getInfo().getCreator());

        //发送短信
        Response<SmsResponseDTO> response = messageCheckService.sendSms(smsRequestDTO);
        if (!response.isSuccess()) {
            throw new CuscUserException(response.getCode(), response.getMsg());
        }
        fpRnrSmsInfoDTO.setSendSmsId(response.getData().getMessageId());
        smsInfoService.insert(fpRnrSmsInfoDTO);
        return Response.createSuccess();
    }

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

    //短信消息
    private SmsRequestDTO toSmsRequestDto(RnrRelationDTO dto) {
        SmsRequestDTO smsRequestDTO = new SmsRequestDTO();
        smsRequestDTO.setTenantNo(dto.getOrder().getTenantNo());
        smsRequestDTO.setBizType(BizTypeEnum.BIND.getCode());
        smsRequestDTO.setPhone(dto.getInfo().getPhone());
        //短信参数
        List<String> params = new ArrayList<>();
        params.add(dto.getInfo().getFullName() + "女士/先生");
        params.add(dto.getCardList().get(0).getIotId());
        params.add(dto.getCardList().stream().map(c -> c.getIccid()).collect(Collectors.joining(",")));
        smsRequestDTO.setParams(params);
        return smsRequestDTO;
    }
}
