package com.hfkj.service.gas.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hfkj.channel.gas.newlink2.NewLink2RequestService;
import com.hfkj.common.exception.BaseException;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.pay.util.SignatureUtil;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.dao.BsGasOrderAuditMapper;
import com.hfkj.entity.*;
import com.hfkj.openapi.model.response.OrderRefundNotifyModel;
import com.hfkj.openapi.model.response.ResponseOrderPushModel;
import com.hfkj.openapi.service.ApiGasOrderService;
import com.hfkj.service.agent.BsAgentApiParamService;
import com.hfkj.service.gas.BsGasOrderAuditService;
import com.hfkj.service.gas.BsGasOrderService;
import com.hfkj.service.order.BsOrderRefundService;
import com.hfkj.sysenum.gas.GasOrderAuditStatusEnum;
import com.hfkj.sysenum.gas.GasOrderAuditTypeEnum;
import com.hfkj.sysenum.gas.OrderOilStatus;
import com.hfkj.sysenum.merchant.MerchantSourceTypeEnum;
import com.hfkj.sysenum.order.OrderRefundStatusEnum;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("gasOrderAuditService")
public class BsGasOrderAuditServiceImpl implements BsGasOrderAuditService {
    @Resource
    private BsGasOrderAuditMapper gasOrderAuditMapper;
    @Resource
    private BsGasOrderService gasOrderService;
    @Resource
    private BsOrderRefundService orderRefundService;
    @Resource
    private ApiGasOrderService apiGasOrderService;
    @Resource
    private BsAgentApiParamService agentApiParamService;

    @Override
    public void editData(BsGasOrderAudit data) {
        data.setUpdateTime(new Date());
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            gasOrderAuditMapper.insert(data);
        } else {
            gasOrderAuditMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    public void create(BsGasOrderAudit data) {
        editData(data);
    }

    @Override
    public BsGasOrderAudit getDetail(String auditNo) {
        BsGasOrderAuditExample example = new BsGasOrderAuditExample();
        example.createCriteria().andAuditNoEqualTo(auditNo).andStatusNotEqualTo(GasOrderAuditStatusEnum.type0.getCode());
        List<BsGasOrderAudit> list = gasOrderAuditMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsGasOrderAudit getDetailByOrderNo(String orderNo, GasOrderAuditStatusEnum auditStatus) {
        BsGasOrderAuditExample example = new BsGasOrderAuditExample();
        example.createCriteria()
                .andOrderNoEqualTo(orderNo)
                .andStatusNotEqualTo(auditStatus.getCode());
        example.setOrderByClause("create_time desc");
        List<BsGasOrderAudit> list = gasOrderAuditMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void approval(String auditNo,String remark) {
        // 审核
        BsGasOrderAudit audit = getDetail(auditNo);
        if (audit == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到数据");
        }
        audit.setRejectRemark(remark);
        if (audit.getAuditType().equals(GasOrderAuditTypeEnum.type1.getCode())) {
            // 加油订单
            BsGasOrder gasOrder = gasOrderService.getDetailByOrderNo(audit.getOrderNo());
            if (gasOrder == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到加油订单");
            }
            if (!gasOrder.getStatus().equals(OrderOilStatus.STATUS5.getNumber())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "加油订单不处于退款中");
            }
            // 查询退款订单
            BsOrderRefund orderRefund = orderRefundService.getRefundByOrderNo(gasOrder.getOrderNo());
            if (orderRefund == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到加油退款订单");
            }
            orderRefund.setRefundFailReason(audit.getRejectRemark());

            // 处理加油订单
            if (gasOrder.getChannelType().equals(MerchantSourceTypeEnum.type4.getNumber())) {
                audit.setStatus(GasOrderAuditStatusEnum.type4.getCode());
                editData(audit);

                // 申请退款
                JSONObject refundCallBack = NewLink2RequestService.refundCallBack(gasOrder.getChannelOrderNo(),
                        "其他",
                        orderRefund.getRefundRemark(),
                        orderRefund.getRefundOrderNo());
                if (!refundCallBack.getString("code").equals("200")) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "申请退款失败:"+refundCallBack.getString("msg"));
                }
            } else {
                audit.setStatus(GasOrderAuditStatusEnum.type2.getCode());
                editData(audit);

                ResponseOrderPushModel response = new ResponseOrderPushModel();
                response.setOrderNo(gasOrder.getOrderNo());
                response.setChannelType(gasOrder.getChannelType());
                response.setChannelOrderNo(gasOrder.getChannelOrderNo());

                try {
                    // 退款金额
                    apiGasOrderService.refundPrice(gasOrder,orderRefund);
                    orderRefund.setRefundStatus(OrderRefundStatusEnum.status2.getCode());
                    orderRefund.setFinishTime(new Date());
                    orderRefundService.editData(orderRefund);

                    gasOrder.setStatus(OrderOilStatus.STATUS4.getNumber());
                    gasOrder.setRefundTime(orderRefund.getFinishTime());
                    gasOrderService.updateGasOrder(gasOrder);

                } catch (BaseException e) {
                    orderRefund.setRefundStatus(OrderRefundStatusEnum.status3.getCode());
                    orderRefund.setRefundFailReason("退款失败！");
                    orderRefundService.editData(orderRefund);

                    gasOrder.setStatus(OrderOilStatus.STATUS6.getNumber());
                    gasOrder.setReceiptFailRemark(orderRefund.getRefundFailReason());
                    gasOrderService.updateGasOrder(gasOrder);

                    throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.COMMON_ERROR, e.getErrorMsg());
                } catch (Exception e) {
                    orderRefund.setRefundStatus(OrderRefundStatusEnum.status3.getCode());
                    orderRefund.setRefundFailReason("退款失败！");
                    orderRefundService.editData(orderRefund);

                    gasOrder.setStatus(OrderOilStatus.STATUS6.getNumber());
                    gasOrder.setReceiptFailRemark(orderRefund.getRefundFailReason());
                    gasOrderService.updateGasOrder(gasOrder);

                    throw ErrorHelp.genException(SysCode.OpenApi, ErrorCode.COMMON_ERROR, "请求退款失败");
                } finally {
                    // 退款成功通知
                    if (gasOrder.getStatus().equals(OrderOilStatus.STATUS4.getNumber()) && gasOrder.getAgentId() != null) {
                        // 代理参数
                        BsAgentApiParam apiParam = agentApiParamService.getParam(gasOrder.getAgentId());
                        if (apiParam != null && StringUtils.isNotBlank(apiParam.getOrderRefundNotify())) {
                            // 通知数据
                            OrderRefundNotifyModel refundNotify = new OrderRefundNotifyModel();
                            refundNotify.setOrderNo(orderRefund.getOrderNo());
                            refundNotify.setChannelType(gasOrder.getChannelType());
                            refundNotify.setChannelOrderNo(gasOrder.getChannelOrderNo());
                            refundNotify.setRefundResult(orderRefund.getRefundStatus() == 2 ? true : false);
                            refundNotify.setRefundFailReason(orderRefund.getRefundFailReason());
                            refundNotify.setSign(SignatureUtil.createSign(refundNotify, apiParam.getAppSecret()));
                            try {
                                System.out.println("请求url：" + apiParam.getOrderRefundNotify());
                                System.out.println("请求参数：" + JSONObject.toJSONString(refundNotify));
                                String apiResp = HttpsUtils.doApiPost(apiParam.getOrderRefundNotify(), JSONObject.parseObject(JSONObject.toJSONString(refundNotify,SerializerFeature.WriteMapNullValue),JSONObject.class));
                                System.out.println("响应参数：" + apiResp);
                            } catch (Exception e) { }
                        }
                    }
                }
            }
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void reject(String auditNo, String remark) {
        // 审核
        BsGasOrderAudit audit = getDetail(auditNo);
        if (audit == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到数据");
        }
        audit.setStatus(GasOrderAuditStatusEnum.type3.getCode());
        audit.setRejectRemark(remark);
        editData(audit);

        if (audit.getAuditType().equals(GasOrderAuditTypeEnum.type1.getCode())) {
            // 加油订单
            BsGasOrder gasOrder = gasOrderService.getDetailByOrderNo(audit.getOrderNo());
            if (gasOrder == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到加油订单");
            }
            if (!gasOrder.getStatus().equals(OrderOilStatus.STATUS5.getNumber())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "加油订单不处于退款中");
            }
            // 查询退款订单
            BsOrderRefund orderRefund = orderRefundService.getRefundByOrderNo(audit.getOrderNo());
            if (orderRefund == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到加油退款订单");
            }
            orderRefund.setRefundFailReason(audit.getRejectRemark());
            orderRefund.setRefundStatus(OrderRefundStatusEnum.status3.getCode());
            orderRefundService.editData(orderRefund);

            gasOrder.setStatus(OrderOilStatus.STATUS6.getNumber());
            gasOrder.setReceiptFailRemark(remark);
            gasOrderService.updateGasOrder(gasOrder);

            // 处理加油订单
            if (gasOrder.getAgentId() != null) {
                // 代理参数
                BsAgentApiParam apiParam = agentApiParamService.getParam(gasOrder.getAgentId());
                if (apiParam != null && StringUtils.isNotBlank(apiParam.getOrderRefundNotify())) {
                    // 通知数据
                    OrderRefundNotifyModel refundNotify = new OrderRefundNotifyModel();
                    refundNotify.setOrderNo(orderRefund.getOrderNo());
                    refundNotify.setChannelType(gasOrder.getChannelType());
                    refundNotify.setChannelOrderNo(gasOrder.getChannelOrderNo());
                    refundNotify.setRefundResult(orderRefund.getRefundStatus() == 2 ? true : false);
                    refundNotify.setRefundFailReason(orderRefund.getRefundFailReason());
                    refundNotify.setSign(SignatureUtil.createSign(refundNotify, apiParam.getAppSecret()));
                    try {
                        System.out.println("请求url：" + apiParam.getOrderRefundNotify());
                        System.out.println("请求参数：" + JSONObject.toJSONString(refundNotify));
                        String apiResp = HttpsUtils.doApiPost(apiParam.getOrderRefundNotify(), JSONObject.parseObject(JSONObject.toJSONString(refundNotify,SerializerFeature.WriteMapNullValue),JSONObject.class));
                        System.out.println("响应参数：" + apiResp);
                    } catch (Exception e) { }
                }
            }
        }
    }

    @Override
    public List<BsGasOrderAudit> getList(Map<String, Object> param) {
        BsGasOrderAuditExample example = new BsGasOrderAuditExample();
        BsGasOrderAuditExample.Criteria criteria = example.createCriteria().andStatusNotEqualTo(GasOrderAuditStatusEnum.type0.getCode());

        if (StringUtils.isNotBlank(MapUtils.getString(param, "auditNo"))) {
            criteria.andAuditNoEqualTo(MapUtils.getString(param, "auditNo"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "orderNo"))) {
            criteria.andOrderNoLike("%"+MapUtils.getString(param, "orderNo")+"%");
        }

        if (MapUtils.getInteger(param, "channelType") != null) {
            criteria.andChannelTypeEqualTo(MapUtils.getInteger(param, "channelType"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "channelOrderNo"))) {
            criteria.andChannelOrderNoLike("%"+MapUtils.getString(param, "channelOrderNo")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "orderNo"))) {
            criteria.andOrderNoLike("%"+MapUtils.getString(param, "orderNo")+"%");
        }

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merNo"))) {
            criteria.andMerNoLike("%"+MapUtils.getString(param, "merNo")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%"+MapUtils.getString(param, "merName")+"%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (MapUtils.getLong(param, "createTimeS") != null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(param, "createTimeS")));
        }

        if (MapUtils.getLong(param, "createTimeE") != null) {
            criteria.andCreateTimeLessThanOrEqualTo(new Date(MapUtils.getLong(param, "createTimeE")));
        }

        example.setOrderByClause("create_time desc");
        return gasOrderAuditMapper.selectByExample(example);
    }
}
