package com.hai.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.DateUtil;
import com.hai.config.HuiLianTongUnionCardConfig;
import com.hai.dao.HighGasOrderPushMapper;
import com.hai.dao.OutRechargeOrderMapper;
import com.hai.dao.OutRechargeOrderMapperExt;
import com.hai.entity.*;
import com.hai.enum_type.OrderPushType;
import com.hai.model.OutOrderModel;
import com.hai.model.OutRechargeOrderModel;
import com.hai.model.OutUserOrderModel;
import com.hai.service.HighUserCardService;
import com.hai.service.HighUserService;
import com.hai.service.OutRechargeOrderService;
import io.swagger.models.auth.In;
import org.apache.commons.collections4.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 org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("outRechargeOrderService")
public class OutRechargeOrderServiceImpl implements OutRechargeOrderService {

    @Resource
    private OutRechargeOrderMapper outRechargeOrderMapper;

    @Resource
    private OutRechargeOrderMapperExt outRechargeOrderMapperExt;

    @Resource
    private HighUserCardService highUserCardService;

    @Resource
    private HighGasOrderPushMapper highGasOrderPushMapper;

    @Resource
    private HighUserService highUserService;

    @Override
    public List<OutRechargeOrder> getListRechargeOrder(Map<String, String> map) {
        OutRechargeOrderExample example = new OutRechargeOrderExample();
        OutRechargeOrderExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "userId") != null) {
            criteria.andUserIdEqualTo(MapUtils.getLong(map, "userId"));
        }

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

        if (MapUtils.getInteger(map, "payType") != null) {
            criteria.andPayTypeEqualTo(MapUtils.getInteger(map, "payType"));
        }
        if (MapUtils.getInteger(map, "code") != null) {
            criteria.andIdentificationCodeEqualTo(MapUtils.getLong(map, "code"));
        }

        if (MapUtils.getString(map, "orderNo") != null) {
            criteria.andOrderNoLike("%" + MapUtils.getString(map, "orderNo") + "%");
        }

        if (MapUtils.getString(map, "userPhone") != null) {
            criteria.andUserPhoneEqualTo(MapUtils.getString(map, "userPhone"));
        }

        if (MapUtils.getString(map, "rechargeContent") != null) {
            criteria.andRechargeContentLike("%" + MapUtils.getString(map, "rechargeContent") + "%");
        }

        if (MapUtils.getString(map, "phone") != null) {
            criteria.andUserPhoneEqualTo(MapUtils.getString(map, "phone"));
        }

        if (MapUtils.getString(map, "rechargeModel") != null) {
            criteria.andRechargeModelEqualTo(Integer.valueOf(MapUtils.getString(map, "rechargeModel")));
        }

        if (StringUtils.isNotBlank(map.get("payTimeS")) && StringUtils.isNotBlank(map.get("payTimeE"))) {
            criteria.andPayTimeBetween(
                    DateUtil.format(map.get("payTimeS") , "yyyy-MM-dd HH:mm:ss") ,
                    DateUtil.format(map.get("payTimeE") , "yyyy-MM-dd HH:mm:ss"));
        }
        if (StringUtils.isNotBlank(map.get("createTimeS")) && StringUtils.isNotBlank(map.get("createTimeE"))) {
            criteria.andCreateTimedBetween(
                    DateUtil.format(map.get("createTimeS") , "yyyy-MM-dd HH:mm:ss") ,
                    DateUtil.format(map.get("createTimeE") , "yyyy-MM-dd HH:mm:ss"));
        }

        example.setOrderByClause("create_timed desc");
        return outRechargeOrderMapper.selectByExample(example);
    }

    @Override
    public OutRechargeOrder findByOrderId(Long orderId) {
        return outRechargeOrderMapper.selectByPrimaryKey(orderId);
    }

    @Override
    public OutRechargeOrder findByOrderNo(String orderNo) {
        OutRechargeOrderExample example = new OutRechargeOrderExample();
        example.createCriteria().andOrderNoEqualTo(orderNo);
        return outRechargeOrderMapper.selectByExample(example).get(0);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void insertOrder(OutRechargeOrder outRechargeOrder) {
        outRechargeOrderMapper.insert(outRechargeOrder);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void updateOrder(OutRechargeOrder outRechargeOrder) {
        outRechargeOrderMapper.updateByPrimaryKey(outRechargeOrder);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void cancelOrder(Long orderId) {
        OutRechargeOrder order = findByOrderId(orderId);
        if (order != null) {
            order.setStatus(4); // 订单状态：1 待支付  2 已支付  3.已完成  4. 已取消  5.已退款
            order.setCancelTime(new Date());
            updateOrder(order);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void finishOrder(Long orderId) {
        OutRechargeOrder order = findByOrderId(orderId);
        if (order != null) {
            order.setStatus(3); // 订单状态：1 待支付  2 已支付  3.已完成  4. 已取消  5.已退款
            order.setFinishTime(new Date());
            updateOrder(order);
        }
    }

    @Override
    public List<OutRechargeOrderModel> getOrderCount(Map<String, Object> map) throws Exception {
        if(MapUtils.getLong(map, "createTimeS") != null) {
            map.put("createTimeS", DateUtil.date2String(new Date(MapUtils.getLong(map, "createTimeS")), "yyyy-MM-dd HH:mm:ss"));
        }

        if(MapUtils.getLong(map, "createTimeE") != null) {
            map.put("createTimeE", DateUtil.date2String(new Date(MapUtils.getLong(map, "createTimeE")), "yyyy-MM-dd HH:mm:ss"));
        }

        if(MapUtils.getLong(map, "payTimeS") != null) {
            map.put("payTimeS", DateUtil.date2String(new Date(MapUtils.getLong(map, "payTimeS")), "yyyy-MM-dd HH:mm:ss"));
        }


        if(MapUtils.getLong(map, "payTimeE") != null) {
            map.put("payTimeE", DateUtil.date2String(new Date(MapUtils.getLong(map, "payTimeE")), "yyyy-MM-dd HH:mm:ss"));
        }

        return outRechargeOrderMapper.selectOrderCount(map);
    }

    @Override
    public Long CountOrder() {
        OutRechargeOrderExample example = new OutRechargeOrderExample();
        example.createCriteria().andStatusEqualTo(2);
        return outRechargeOrderMapper.countByExample(example);
    }

    @Override
    public List<OutOrderModel> getListOrderCount(Map<String, String> map) throws Exception {
        String finishTimeS = map.get("finishTimeS");
        String finishTimeE = map.get("finishTimeE");
        Integer status;
        if (StringUtils.isNotBlank(map.get("status"))) {
            status = Integer.valueOf(map.get("status"));
        } else {
            status = null;
        }
        String fTimeS;
        String fTimeE;
        if (StringUtils.isNotBlank(finishTimeS)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(Long.parseLong(finishTimeS)));
            //时
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            //分
            calendar.set(Calendar.MINUTE, 00);
            //秒
            calendar.set(Calendar.SECOND, 00);
            fTimeS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());

        } else {
            fTimeS = "2010-09-13 22:36:01";
        }
        if (StringUtils.isNotBlank(finishTimeE)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(Long.parseLong(finishTimeE)));
            //时
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            //分
            calendar.set(Calendar.MINUTE, 00);
            //秒
            calendar.set(Calendar.SECOND, 00);
            fTimeE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
        } else {
            fTimeE = DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss");
        }
        return outRechargeOrderMapperExt.getListOrderCount(fTimeS , fTimeE , status);
    }

    @Override
    public List<OutUserOrderModel> getUserCountList(Map<String, String> map) throws Exception {
        String finishTimeS = map.get("finishTimeS");
        String finishTimeE = map.get("finishTimeE");
        String fTimeS;
        String fTimeE;
        if (StringUtils.isNotBlank(finishTimeS)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(Long.parseLong(finishTimeS)));
            //时
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            //分
            calendar.set(Calendar.MINUTE, 00);
            //秒
            calendar.set(Calendar.SECOND, 00);
            fTimeS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());

        } else {
            fTimeS = "2010-09-13 22:36:01";
        }
        if (StringUtils.isNotBlank(finishTimeE)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(Long.parseLong(finishTimeE)));
            //时
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            //分
            calendar.set(Calendar.MINUTE, 00);
            //秒
            calendar.set(Calendar.SECOND, 00);
            fTimeE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
        } else {
            fTimeE = DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss");
        }
        return outRechargeOrderMapperExt.getListUserCount(fTimeS , fTimeE);
    }

    @Override
    public void hltUnionCardPay(Long userCardId, Long orderId) {
        try {
            HighUserCard userCard = highUserCardService.getDetailById(userCardId);
            if(userCard == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到用户绑定的卡号信息");
            }
            OutRechargeOrder order = findByOrderId(orderId);
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单信息");
            }

            String goodsDesc = "充值话费";
            String tranDesc = order.getRechargeContent() + "充值" + order.getPayPrice() +"元话费";
            String instCode = "11101290";
            String businessType = "hisen_consume";

            // 工会卡支付
            JSONObject consumption = HuiLianTongUnionCardConfig.consumption(order.getOrderNo(), userCard.getCardNo(), order.getPayPrice(), businessType, instCode, goodsDesc, tranDesc);
            System.out.println("工会卡支付响应参数" + consumption.toJSONString());

            Map<String,Object> dataMap = new HashMap<>();
            dataMap.put("orderNo", order.getOrderNo());
            dataMap.put("cardType", "ghk");
            dataMap.put("cardNo", userCard.getCardNo());
            dataMap.put("checkPassword", "N");
            dataMap.put("tranAmount", order.getPayPrice());
            dataMap.put("tranChannel", "HiSen");
            dataMap.put("businessType", businessType);
            dataMap.put("instCode", instCode);
            dataMap.put("goodsDesc", goodsDesc);
            dataMap.put("tranDesc", tranDesc);
            HighGasOrderPush payPush = new HighGasOrderPush();
            payPush.setType(OrderPushType.type5.getType());
            payPush.setOrderNo(userCard.getCardNo());
            payPush.setCreateTime(new Date());
            payPush.setCode(consumption.getString("respCode"));
            payPush.setRequestContent(JSON.toJSONString(dataMap));
            payPush.setReturnContent(consumption.toJSONString());
            highGasOrderPushMapper.insert(payPush);

            if(!consumption.getString("respCode").equals("0000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, consumption.getString("respMessage"));
            }
            JSONObject consumptionResult = HuiLianTongUnionCardConfig.resolveResponse(consumption.getString("data"));
            if (consumptionResult.getBoolean("success") != true) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "交易失败!"+consumptionResult.getString("message"));
            }
            order.setPaySerialNo(consumptionResult.getString("orderId")); // 支付流水号
            order.setPayRealPrice(order.getPayPrice()); // 实付金额
            order.setStatus(2);
            order.setPayType(2);
            order.setPayTime(new Date()); // 支付时间
            updateOrder(order);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void goldPayOrder(Long userId, Long orderId) {
        OutRechargeOrder order = findByOrderId(orderId);
        if(order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_ORDER, "");
        }
        // 查询用户
        HighUser highUser = highUserService.findByUserId(userId);

        // 金币 1：100
        Integer goldNum = new BigDecimal(order.getPayPrice().toString()).multiply(new BigDecimal("100")).intValue();
        highUserService.goldHandle(userId, goldNum, 2, 2, order.getId());

        order.setPayRealPrice(order.getPayPrice()); // 实付金额
        order.setStatus(2);
        order.setPayType(3);
        order.setPayTime(new Date()); // 支付时间
        updateOrder(order);
    }
}
