package com.gic.haoban.manage.service.service.out.impl.licence;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.enterprise.api.constant.EnterpriseServiceEnum;
import com.gic.enterprise.api.dto.EnterpriseUsingPermissionDto;
import com.gic.enterprise.api.service.EnterpriseUseForbidService;
import com.gic.haoban.manage.api.dto.WxEnterpriseDTO;
import com.gic.haoban.manage.api.dto.licence.AppOrderCheckDTO;
import com.gic.haoban.manage.api.dto.licence.AppOrderNoticeDTO;
import com.gic.haoban.manage.api.dto.licence.AppOrderPageDTO;
import com.gic.haoban.manage.api.dto.qdto.licence.AppOrderPageQDTO;
import com.gic.haoban.manage.api.dto.qdto.licence.AppOrderQDTO;
import com.gic.haoban.manage.api.service.licence.AppOrderApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.entity.TabHaobanAppOrder;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterprise;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterpriseRelated;
import com.gic.haoban.manage.service.service.TabHaobanAppOrderService;
import com.gic.haoban.manage.service.service.WxEnterpriseRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.util.SignatureGetterUtil;
import com.gic.redis.data.util.RedisUtil;
import com.gic.wechat.api.dto.qywx.fee.AppOrderInfoResponseDTO;
import com.gic.wechat.api.dto.qywx.fee.AppOrderResponseListDTO;
import com.gic.wechat.api.dto.qywx.fee.OpenOrderResponseDTO;
import com.gic.wechat.api.dto.qywx.response.QywxResponseDTO;
import com.gic.wechat.api.service.qywx.QywxOrderApiService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @description:
 * @Author: wenhua
 * @Date: 2023/6/25 15:44
 */
@Service("appOrderApiServiceImpl")
public class AppOrderApiServiceImpl implements AppOrderApiService {

    private static final Logger logger = LogManager.getLogger(AppOrderApiServiceImpl.class);

    @Autowired
    private TabHaobanAppOrderService tabHaobanAppOrderService;
    @Autowired
    private QywxOrderApiService qywxOrderApiService;
    @Autowired
    private Config config;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private EnterpriseUseForbidService enterpriseUseForbidService;
    @Autowired
    private WxEnterpriseRelatedService wxEnterpriseRelatedService;

    @Override
    public ServiceResponse<Page<AppOrderPageDTO>> getAppOrderPage(AppOrderPageQDTO qdto) {
        Page<AppOrderPageDTO> orderPage = tabHaobanAppOrderService.getAppOrderPage(qdto);
        List<AppOrderPageDTO> list = orderPage.getResult();
        if (CollUtil.isNotEmpty(list)) {
            Date now = new Date();
            //判断支付时间是否过期，需要更改订单状态，已过期的订单默认取消
            for (AppOrderPageDTO dto : list) {
                if (dto.getOrderStatus() == 1 && now.after(dto.getExpireTime())) {
                    dto.setOrderStatus(3);
                    //需要取消订单
                    cancelAppOrder(dto.getId());
                }
                if (dto.getOrderStatus() == 2){
                    if (now.before(dto.getBeginTime())){
                        dto.setEffectiveState(1);
                    }else if (now.before(dto.getEndTime())){
                        dto.setEffectiveState(2);
                    }else if (now.after(dto.getEndTime())){
                        dto.setEffectiveState(3);
                    }
                }
            }
            orderPage.setResult(list);
        }
        return ServiceResponse.success(orderPage);
    }

    @Override
    public ServiceResponse<Boolean> saveAppOrder(AppOrderQDTO qdto) {
        //调用企业微信接口，创建付款订单
        if (null == qdto) {
            return ServiceResponse.failure("-9999", "参数不能为空！");
        }
        String wxEnterpriseId = qdto.getWxEnterpriseId();
        String secret = config.getQywxCashierSecret();
        String promotionCaseName = config.getPromotionCaseName();
        String promotionCaseId = config.getPromotionCaseId();
        String buySuiteId = config.getBuySuiteId();
        WxEnterpriseDTO wxEnterpriseDTO = wxEnterpriseService.selectById(wxEnterpriseId);
        String openCorpid = wxEnterpriseDTO.getOpenCorpid();
        String serviceCorpid = config.getCorpid();
        /**
         * 按照企业微信接口提供参数
         * {
         *   "business_type": 3,
         *   "custom_corpid": "wx979abee1572365f9",
         *   "pay_type": 1,
         *   "product_list": {
         *     "promotion_case": {
         *       "order_type": 0,
         *       "case_id": "slne7508097f40c4f8e",
         *       "promotion_edition_name": "固定单价",
         *       "duration_days": 30,
         *       "buy_info_list": [{
         *           "suiteid": "wx8838a73b0f57a7b5",
         *           "appid": 2,
         *           "user_count": 10
         *         },
         *         {
         *           "suiteid": "wx15ab15f7b1ced876",
         *           "user_count": 20
         *         }
         *       ],
         *     }
         *   },
         *   "nonce_str": "129031823",
         *   "ts": 1548302135,
         *   "sig": "mPOwVW/vQ74xN+b+Yu1KMa9RrmhKJaJjAtXHTof+EpU="
         * }
         */
        JSONObject json = new JSONObject();
        HashMap<String, Object> map1 = new HashMap<>();
        HashMap<String, Object> map2 = new HashMap<>();
        List<HashMap<String, Object>> buyInfoList = new ArrayList<>();
        HashMap<String, Object> buyInfoMap = new HashMap<>();
        buyInfoMap.put("suiteid", buySuiteId);
        buyInfoMap.put("user_count", qdto.getUserNum());
        buyInfoList.add(buyInfoMap);
        //获取秒级时间戳
        long timeStamp = System.currentTimeMillis() / 1000;
        //签名算法
        SignatureGetterUtil signatureGetterUtil = new SignatureGetterUtil(secret);
        String nonceStr = signatureGetterUtil.generateRandomString(12);
        String sig = null;
        map2.put("order_type", qdto.getOrderType());
        map2.put("case_id", promotionCaseId);
        map2.put("promotion_edition_name", promotionCaseName);
        map2.put("duration_days", qdto.getDuration());
        map2.put("buy_info_list", buyInfoList);
        map1.put("promotion_case", map2);
        json.put("business_type", 3);
        json.put("custom_corpid", openCorpid);
        json.put("pay_type", 0);
        json.put("product_list", map1);
        json.put("nonce_str", nonceStr);
        json.put("ts", timeStamp);
        try {
            logger.info("签名算法参数校验：{}", JSON.toJSONString(json));
            sig = signatureGetterUtil.get(JSON.toJSONString(json));
        } catch (Exception e) {
            logger.info("签名算法异常！");
            throw new RuntimeException(e);
        }
        json.put("sig", sig);
        //调用企业微信创建收款订单接口
        ServiceResponse<OpenOrderResponseDTO> response = qywxOrderApiService.createOpenOrder(serviceCorpid, openCorpid, JSON.toJSONString(json));
        logger.info("调用企业微信创建收款订单返回信息：{}", JSON.toJSONString(response));
        if (response.isSuccess()) {
            OpenOrderResponseDTO dto = response.getResult();
            TabHaobanAppOrder appOrder = JSONObject.parseObject(JSONObject.toJSONString(qdto), TabHaobanAppOrder.class);
            Date now = new Date();
            appOrder.setOrderId(dto.getOrderId());
            appOrder.setOrderUrl(dto.getOrderUrl());
            appOrder.setOriginPrice(dto.getOriginPrice());
            appOrder.setPaidPrice(dto.getPaidPrice());
            appOrder.setId(UniqueIdUtils.uniqueLong());
            appOrder.setOrderStatus(1);
            appOrder.setCreateTime(now);
            appOrder.setUpdateTime(now);
            appOrder.setDeleteFlag(0);
            //默认6天支付有效期
            appOrder.setExpireTime(DateUtil.addDay(now, 6));
            tabHaobanAppOrderService.insert(appOrder);
            return ServiceResponse.success(true);
        }
        return ServiceResponse.failure(response.getCode(), response.getMessage());
    }

    @Override
    public ServiceResponse<Boolean> cancelAppOrder(Long orderId) {
        TabHaobanAppOrder appOrder = tabHaobanAppOrderService.queryById(orderId);
        if (null == appOrder) {
            return ServiceResponse.failure("-9999", "无效的orderId！");
        }
        String wxEnterpriseId = appOrder.getWxEnterpriseId();
        WxEnterpriseDTO wxEnterpriseDTO = wxEnterpriseService.selectById(wxEnterpriseId);
        String openCorpid = wxEnterpriseDTO.getOpenCorpid();
        String serviceCorpid = config.getCorpid();
        String secret = config.getQywxCashierSecret();
        //获取秒级时间戳
        long timeStamp = System.currentTimeMillis() / 1000;
        //签名算法
        SignatureGetterUtil signatureGetterUtil = new SignatureGetterUtil(secret);
        String nonceStr = signatureGetterUtil.generateRandomString(12);
        String sig = null;
        JSONObject json = new JSONObject();
        json.put("order_id", appOrder.getOrderId());
        json.put("nonce_str", nonceStr);
        json.put("ts", timeStamp);
        try {
            logger.info("签名算法参数校验：{}", JSON.toJSONString(json));
            sig = signatureGetterUtil.get(JSON.toJSONString(json));
        } catch (Exception e) {
            logger.info("签名算法异常！");
            throw new RuntimeException(e);
        }
        json.put("sig", sig);
        //调用企业微信创建收款订单接口
        ServiceResponse<QywxResponseDTO> response = qywxOrderApiService.cancelOpenOrder(serviceCorpid, openCorpid, JSON.toJSONString(json));
        logger.info("调用企业微信创建收款订单返回信息：{}", JSON.toJSONString(response));
        if (response.isSuccess()) {
            TabHaobanAppOrder newAppOrder = new TabHaobanAppOrder();
            newAppOrder.setId(appOrder.getId());
            newAppOrder.setOrderStatus(3);
            newAppOrder.setUpdateTime(new Date());
            tabHaobanAppOrderService.update(newAppOrder);
            return ServiceResponse.success(true);
        }
        return ServiceResponse.failure(response.getCode(), response.getMessage());
    }

    @Override
    public ServiceResponse<AppOrderCheckDTO> checkAppOrder(String wxEnterpriseId) {
        AppOrderPageQDTO qdto = new AppOrderPageQDTO();
        AppOrderCheckDTO result = new AppOrderCheckDTO();
        Date now = new Date();
        Date endTime = DateUtil.addDay(now, -1);
        Date appOrderEndTime = DateUtil.addDay(now, -1);
        result.setNow(now);
        List<TabHaobanWxEnterpriseRelated> enterpriseIdList = wxEnterpriseRelatedService.getByWxEnterpriseId(wxEnterpriseId);
        if (CollUtil.isNotEmpty(enterpriseIdList)) {
            for (TabHaobanWxEnterpriseRelated a : enterpriseIdList) {
                //查询好办企业到期时间
                ServiceResponse<EnterpriseUsingPermissionDto> resp = this.enterpriseUseForbidService.getPermisssionByCode(a.getEnterpriseId(), EnterpriseServiceEnum.HAO_BAN.getRightMenuCode());
                if (resp.isSuccess()) {
                    EnterpriseUsingPermissionDto dto = resp.getResult();
                    Date endDate = dto.getServiceEndDate();
                    if (endTime.before(endDate)) {
                        endTime = endDate;
                    }
                }
            }
        }
        qdto.setWxEnterpriseId(wxEnterpriseId);
        qdto.setPageNum(1);
        qdto.setPageSize(10000);
        Page<AppOrderPageDTO> page = this.getAppOrderPage(qdto).getResult();
        List<AppOrderPageDTO> list = page.getResult();
        if (CollUtil.isNotEmpty(list)) {
            Date beginTime = new Date();
            Integer num = 0;
            for (AppOrderPageDTO dto : list) {
                if (dto.getOrderStatus() == 2 ){
                    num += dto.getUserNum();
                    if (appOrderEndTime.before(dto.getEndTime())){
                        appOrderEndTime = dto.getEndTime();
                        beginTime = dto.getBeginTime();
                    }
                }
            }
            if (num>=1000000){
                result.setUserNum(1000000);
            }else {
                result.setUserNum(num);
            }
            if (now.before(endTime)){
                result.setType(2);
                result.setEndTime(endTime);
                result.setBeginTime(beginTime);
            }else {
                result.setType(1);
            }
        } else {
            result.setType(0);
        }
        int i = DateUtil.daysBetween(appOrderEndTime, endTime);
        if(i< 0){
            i = 0;
        }
        result.setContractDay(i);
        return ServiceResponse.success(result);
    }
    @Override
    public ServiceResponse<AppOrderNoticeDTO> noticeAppOrder(String wxEnterpriseId) {
        AppOrderPageQDTO qdto = new AppOrderPageQDTO();
        AppOrderNoticeDTO result = new AppOrderNoticeDTO();
        WxEnterpriseDTO wxEnterpriseDTO = wxEnterpriseService.selectById(wxEnterpriseId);
        if (wxEnterpriseDTO != null && wxEnterpriseDTO.getWxSecurityType() == 5){
            //自建应用不需要弹窗
            result.setType(0);
            return ServiceResponse.success(result);
        }
        qdto.setWxEnterpriseId(wxEnterpriseId);
        qdto.setPageNum(1);
        qdto.setPageSize(10000);
        Page<AppOrderPageDTO> page = this.getAppOrderPage(qdto).getResult();
        List<AppOrderPageDTO> list = page.getResult();
        logger.info("查询的付费应用订单列表：{}",JSON.toJSONString(list));
        Date now = new Date();
        Date endTime = DateUtil.addDay(now, -1);
        boolean flag = false;
        if (CollUtil.isNotEmpty(list)) {
            for (AppOrderPageDTO dto : list) {
                if (dto.getOrderStatus() == 1){
                    result.setPayFlag(0);
                    result.setOrderUrl(dto.getOrderUrl());
                }
                if (dto.getOrderStatus() == 2 && endTime.before(dto.getEndTime())){
                    endTime = dto.getEndTime();
                    flag=true;
                }
            }
            if (DateUtil.addDay(now,30).before(endTime)){
                result.setType(0);
                result.setEndTime(endTime);
            }else if (now.before(endTime)){
                result.setType(4);
                result.setEndTime(endTime);
            }else if (now.after(endTime)){
                if (flag){
                    result.setType(2);
                    result.setEndTime(endTime);
                }else {
                    result.setType(1);
                }
            }
        }else {
            result.setType(1);
        }
        return ServiceResponse.success(result);
    }

    @Override
    public ServiceResponse<Boolean> qywxCallBack(String param) {
        logger.info("接收企业微信回调参数：{}", JSON.toJSONString(param));
        if (StrUtil.isBlank(param)) {
            return ServiceResponse.success(false);
        }
        JSONObject object = JSONObject.parseObject(param, JSONObject.class);
        String infoType = object.getString("infoType");
        String orderId = object.getString("orderId");
        String timeStamp = object.getString("timeStamp");
        //将秒级时间戳转换位Date类型
        SimpleDateFormat formatter = new SimpleDateFormat(DateUtil.FORMAT_DATETIME_19);
        String date_time = formatter.format(new Date(Long.valueOf(timeStamp) * 1000L));
        Date date = DateUtil.strToDate(date_time, DateUtil.FORMAT_DATETIME_19);
        TabHaobanAppOrder orderInfo = tabHaobanAppOrderService.queryByOrderId(orderId);
        if ("open_order".equals(infoType)){
            if (orderInfo != null){
                logger.info("已经存在收款订单:{}",orderId);
                return ServiceResponse.success(true);
            }
            //不存在的需要根据订单id获取订单详情，并保存进数据库
            String suiteid = config.getWxSuiteid();
            logger.info("获取的wxSuiteid:{}",suiteid);
            JSONObject json = new JSONObject();
            json.put("orderid", orderId);
            ServiceResponse<AppOrderInfoResponseDTO> response = qywxOrderApiService.getAppOrderInfo(suiteid, null, JSON.toJSONString(json));
            logger.info("查询订单详情返回信息：{}", JSON.toJSONString(response));
            if (response.isSuccess()){
                AppOrderInfoResponseDTO result = response.getResult();
                String paidCorpid = result.getPaidCorpid();
                TabHaobanWxEnterprise wxEnterpriseInfo = wxEnterpriseService.getEnterpriseBycorpId(paidCorpid);
                if (wxEnterpriseInfo == null){
                    logger.info("客户企业的corpid:{}无效！",paidCorpid);
                    return ServiceResponse.success(false);
                }
                TabHaobanAppOrder order = toTabHaobanAppOrder(result, wxEnterpriseInfo.getWxEnterpriseId());
                order.setCreateTime(date);
                tabHaobanAppOrderService.insert(order);
            }else {
                return ServiceResponse.failure(response.getCode(),response.getMessage());
            }
        }
        if ("pay_for_app_success".equals(infoType)){
            if (orderInfo == null){
                logger.info("不存在收款订单:{}",orderId);
                return ServiceResponse.success(true);
            }
            if( orderInfo.getPayTime() != null){
                //该笔订单已处理
                logger.info("该笔订单已处理！");
                return ServiceResponse.success(false);
            }
            orderInfo.setOrderStatus(2);
            orderInfo.setPayTime(date);
            tabHaobanAppOrderService.update(orderInfo);
        }
        if ("refund".equals(infoType)){
            if (orderInfo == null){
                logger.info("不存在收款订单:{}",orderId);
                return ServiceResponse.success(true);
            }
            if (orderInfo.getOrderStatus() == 2){
                orderInfo.setOrderStatus(6);
                tabHaobanAppOrderService.update(orderInfo);
            }
        }
        return ServiceResponse.success(true);
    }

    @Override
    public ServiceResponse<Boolean> getAppOrderList(String param) {
        if(StrUtil.isBlank(param)){
            return ServiceResponse.failure("-9999","参数不能为空");
        }
        logger.info("定时获取好办付费应用订单列表参数：{}",param);
        String suiteid = config.getWxSuiteid();
        ServiceResponse<AppOrderResponseListDTO> response = qywxOrderApiService.getAppOrderInfoList(suiteid, null, param);
        if (response.isSuccess()){
            AppOrderResponseListDTO result = response.getResult();
            List<AppOrderInfoResponseDTO> orderList = result.getOrderList();
            if (CollUtil.isNotEmpty(orderList)){
                List<TabHaobanAppOrder> appOrderList = new ArrayList<>();
                for (AppOrderInfoResponseDTO dto : orderList){
                    String paidCorpid = dto.getPaidCorpid();
                    TabHaobanWxEnterprise wxEnterpriseInfo = wxEnterpriseService.getEnterpriseBycorpId(paidCorpid);
                    if (wxEnterpriseInfo == null){
                        logger.info("客户企业的corpid:{}无效！",paidCorpid);
                        continue;
                    }
                    TabHaobanAppOrder order = toTabHaobanAppOrder(dto, wxEnterpriseInfo.getWxEnterpriseId());
                    appOrderList.add(order);
                }
                //批量插入
                tabHaobanAppOrderService.insertBatch(appOrderList);
            }
        }
        return ServiceResponse.failure(response.getCode(),response.getMessage());
    }
    private TabHaobanAppOrder toTabHaobanAppOrder(AppOrderInfoResponseDTO dto,String wxEnterpriseId ){
        TabHaobanAppOrder appOrder = JSONObject.parseObject(JSONObject.toJSONString(dto), TabHaobanAppOrder.class);
        Date now = new Date();
        appOrder.setOriginPrice(dto.getPrice());
        appOrder.setPaidPrice(dto.getPrice());
        appOrder.setUserNum(dto.getUserCount());
        appOrder.setDuration(dto.getOrderPeriod());
        appOrder.setCreatorId(dto.getOperatorId());
        appOrder.setId(UniqueIdUtils.uniqueLong());
        appOrder.setWxEnterpriseId(wxEnterpriseId);
        appOrder.setCreateTime(now);
        appOrder.setUpdateTime(now);
        appOrder.setDeleteFlag(0);
        //默认6天支付有效期
        appOrder.setExpireTime(DateUtil.addDay(now, 6));
        return appOrder;
    }
}
