package com.clx.performance.listener;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.clx.open.sdk.callback.message.OrderInfoMessage;
import com.clx.order.enums.OrderEnum;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.config.ConfiguredOpenProperties;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dao.vehiclewarn.VehicleWarnUserDao;
import com.clx.performance.model.vehiclewarn.VehicleWarnUser;
import com.msl.common.open.ConfiguredOpenClient;
import com.msl.common.result.Result;
import com.msl.message.sdk.action.MessageAction;
import com.msl.message.sms.api.sms.SmsMessage;
import com.msl.message.sms.api.sms.content.SmsMessageContentImpl;
import com.msl.message.sms.api.sms.recipient.SmsMessageRecipientImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.clx.performance.enums.OrderEnum.Status.*;
import static com.msl.message.sms.api.enums.RecipientTypeEnum.USER_MOBILE;

@Slf4j
@Component
@AllArgsConstructor
public class SendOrderStatusNoticeSmsListener {

    private static final Map<Integer,String> CODE_MAP = new HashMap<>();
    private final ConfiguredOpenClient configuredOpenClient;
    private final VehicleWarnUserDao vehicleWarnUserDao;
    private final ConfiguredOpenProperties properties;
    private final OrderFeign orderFeign;

    public static final Integer  CANCEL_REASON_CODE = 1000000;

    static {
        CODE_MAP.put(WAIT_QUOTATION.getCode(),"orderWaitQuotation");
        CODE_MAP.put(PLATFORM_UNDERTAKING.getCode(),"orderPlatformUndertaking");
        CODE_MAP.put(SUCCESS.getCode(),"orderSuccess");
        CODE_MAP.put(COMPLETED.getCode(),"orderCompleted");
        CODE_MAP.put(CANCELED.getCode(),"orderCanceled");
        CODE_MAP.put(CANCEL_REASON_CODE,"orderCanceledHaveReason");


    }

    @RabbitListener(queues = RabbitKeyConstants.SEND_ORDER_STATUS_NOTICE_SMS_QUEUE)
    public void onMessage(Message message) {
        try{
            log.info("监听到发送订单状态通知短信,消息内容{}", new String(message.getBody()));


            OrderInfoMessage order = JSONUtil.toBean(new String(message.getBody()),
                    new TypeReference<MqWrapper<OrderInfoMessage>>() {
                    },false).getData();

            String targets = getTargets(order.getOrderStatus());
            log.info("获取需要发送短信的手机号列表:{}",targets);
            if(StringUtils.isBlank(targets)){
                return;
            }

            SmsMessage smsMessage = new SmsMessage();

            //设置消息内容
            SmsMessageContentImpl smsMessageContent= new SmsMessageContentImpl();

            Integer code = getCode(order.getOrderNo(), order.getOrderStatus());

            //模版code
            smsMessageContent.setCode(CODE_MAP.get(code));



            //模版参数
            Map<String, Object> params = new HashMap<>();
            params.put("sendAddressShorter",order.getSendAddressShorter());
            params.put("receiveAddressShorter",order.getReveiveAddressShorter());
            params.put("orderNo",order.getOrderNo());

            params.put("cancelReason",getCancelReason(order.getOrderNo(),code));


            smsMessageContent.setParams(params);


            //设置消息接收人
            SmsMessageRecipientImpl smsMessageRecipient = new SmsMessageRecipientImpl();
            smsMessageRecipient.setUserType(USER_MOBILE.getCode());
            smsMessageRecipient.setTargets(targets);


            smsMessage.setContent(smsMessageContent);
            smsMessage.setRecipient(smsMessageRecipient);

            //从消息中心注册获取的通道key
            smsMessage.setAccessKey(properties.getAccessKey());


            //向消息中心发送消息
            log.info("订单状态提醒发送短信开始，请求参数：{}", JSON.toJSONString(smsMessage));
            Result<Object> result = configuredOpenClient.doAction(new MessageAction(smsMessage));
            log.info("订单状态提醒发送短信结束，响应结果：{}", JSON.toJSONString(result));
        }catch (Exception e){
            log.info("监听到发送订单状态通知短信发生异常，异常原因：{}", ExceptionUtils.getStackTrace(e));
        }
    }

    private String getTargets(int code){
        return vehicleWarnUserDao.listAllEnable()
                .stream()
                .filter(item -> JSONUtil.toList(item.getOrderWarnTypeJson(), Integer.class).contains(code))
                .map(VehicleWarnUser::getMobile)
                .collect(Collectors.joining(","));
    }


    public Integer getCode(String orderNo,int orderStatus){
        if(Objects.equals(orderStatus,CANCELED.getCode())){
            FeignOrderVO orderInfoFeign = orderFeign.getOrderInfoFeign(orderNo);
            //判断是否煤源的订单，煤源的订单需要查询取消原因
            if(Objects.equals(orderInfoFeign.getType(), OrderEnum.OrderType.COAL_SOURCE.getCode())){
                return CANCEL_REASON_CODE;
            }
        }
        return orderStatus;
    }

    public String getCancelReason(String orderNo,int code){
        if(Objects.equals(code,CANCEL_REASON_CODE)){
            log.info("通过订单号查询订单取消原因,订单号:{}",orderNo);
            Result<String> orderCancelReason = orderFeign.getOrderCancelReason(orderNo);
            log.info("通过订单号查询订单取消原因,订单号:{},响应结果:{}",orderNo,orderCancelReason);
            if(orderCancelReason.succeed()){
                return orderCancelReason.getData();
            }
        }
        return null;
    }
}
