package cn.pluss.platform.ali.impl;

import cn.pluss.platform.ali.AliService;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultCode;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.device.DeviceOrderInfoService;
import cn.pluss.platform.deviceMerchantBuy.DeviceMerchantBuyService;
import cn.pluss.platform.deviceMerchantBuyDetail.DeviceMerchantBuyDetailService;
import cn.pluss.platform.dto.BatchInfoDTO;
import cn.pluss.platform.dto.DeviceMerchantBuyDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.MerchantBaseInfoMapper;
import cn.pluss.platform.mapper.SystemConfigMapper;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.AliPayParam;
import cn.pluss.platform.util.ParametersUtil;
import cn.pluss.platform.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.FileItem;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuchen
 * 
 * @Description
 */
@Transactional
@Slf4j
@RequiredArgsConstructor
@Service("aliService")
public class AliServiceImpl implements AliService {

    public static AlipayClient alipayClients = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
            AliPayParam.getAppId(), AliPayParam.getPri(), "json", "GBK", AliPayParam.getPub(), "RSA2");

    private final SystemConfigMapper systemConfigMapper;

    private final UserAppService userAppService;

    private final MerchantBaseInfoMapper merchantBaseInfoMapper;

    private final DeviceMerchantBuyService deviceMerchantBuyService;

    private final DeviceMerchantBuyDetailService deviceMerchantBuyDetailService;

    @Setter(onMethod_ = {@Autowired})
    private DeviceOrderInfoService deviceOrderInfoService;

    @Setter
    @Lazy
    private HttpServletRequest request;

    @Override
    public Result<String> getBatchNo(MerchantBaseInfo merchantBaseInfo) {
        AlipayClient alipayClient = alipayClients;
        AlipayOpenAgentCreateRequest request = new AlipayOpenAgentCreateRequest();
        request.setBizContent("{" + "\"account\":\"" + merchantBaseInfo.getAliAccount() + "\"," + "\"contact_info\":{"
                + "\"contact_name\":\"" + merchantBaseInfo.getContactName() + "\"," + "\"contact_mobile\":\""
                + merchantBaseInfo.getContactMobile() + "\"," + "\"contact_email\":\"" + merchantBaseInfo.getEmail() + "\"" + "}," + "}");
        try {
            AlipayOpenAgentCreateResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                if ("10000".equals(response.getCode())) {
                    return ResultGenerator.genSuccessResult(response.getBatchNo());
                } else {
                    return ResultGenerator.genFailResult(response.getSubMsg());
                }
            } else {
                return ResultGenerator.genFailResult(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultGenerator.genFailResult("系统繁忙,请稍后再试");
        }

    }

    @Override
    public Boolean facetofaceSign(BatchInfoDTO dto) {
        log.info("=========BatchInfoDTO=======" + JSONObject.toJSONString(dto));
        AlipayClient alipayClient = alipayClients;
        String businessLicensePic = dto.getBusinessLicensePic();
        try {
            SystemConfig systemConfig = new SystemConfig();
            systemConfig.setPropertyKey("REPLACE");
            SystemConfig querySystemConfig = systemConfigMapper.querySystemConfig(systemConfig);
            businessLicensePic = businessLicensePic.replace("https://www.shouyinbei.net",
                    querySystemConfig.getPropertyValue());
            log.info(businessLicensePic);
            FileItem BusinessLicensePic = new FileItem(businessLicensePic);
            String shopSignBoardPic = dto.getShopSignBoardPic();
            shopSignBoardPic = shopSignBoardPic.replace("https://www.shouyinbei.net",
                    querySystemConfig.getPropertyValue());
            log.info(shopSignBoardPic);
            FileItem ShopSignBoardPic = new FileItem(shopSignBoardPic);
            AlipayOpenAgentFacetofaceSignRequest request = new AlipayOpenAgentFacetofaceSignRequest();
            request.setBatchNo(dto.getBatchNo());
            request.setMccCode(dto.getMccCode());
            request.setBusinessLicenseNo(dto.getBusinessLicenseNo());
            request.setBusinessLicensePic(BusinessLicensePic);
            request.setShopSignBoardPic(ShopSignBoardPic);
            AlipayOpenAgentFacetofaceSignResponse response = alipayClient.execute(request);
            log.info("=====代签约当面付=====" + response);
            if (response.isSuccess()) {
                if ("10000".equals(response.getCode())) {
                    return true;
                } else {
                    return false;
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        return false;
    }

    @Override
    public Boolean agentConfirm(String batchNo) {
        log.info("=agentConfirm提交事务=" + batchNo);
        AlipayClient alipayClient = alipayClients;
        AlipayOpenAgentConfirmRequest request = new AlipayOpenAgentConfirmRequest();
        request.setBizContent("{" + "\"batch_no\":\"" + batchNo + "\"" + "  }");

        try {
            AlipayOpenAgentConfirmResponse response = alipayClient.execute(request);
            log.info("=agentConfirm提交事务=" + response);
            if (response.isSuccess()) {
                if ("10000".equals(response.getCode())) {
                    return true;
                } else {
                    return false;
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        return false;
    }

    @Override
    public Result<Map<String, Object>> appPayParam(Map<String, String> map, DeviceMerchantBuyDTO deviceMerchantBuyDTO) {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ParametersUtil.ZY_ALI_APP_ID, ParametersUtil.ZY_PRI, "json", "UTF-8", ParametersUtil.ZY_PUB, "RSA2");
        AlipayTradeAppPayRequest appPayRequest = getPayRequest(map);
        appPayRequest.setNotifyUrl(ParametersUtil.domain + "/wap/aliPay/aliCallBack");
        try {
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(appPayRequest);//这里和普通的接口调用不同，使用的是sdkExecute
            // System.out.println(response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
            boolean createOrder = createOrder(map.get("outTradeNo") + "", deviceMerchantBuyDTO, request);
            if (createOrder) {
                Map<String, Object> resultMap = new HashMap<>(16);
                resultMap.put("aliCode", response.getBody());
                return ResultGenerator.genSuccessResult(resultMap);
            } else {
                return ResultGenerator.genFailResult("系统繁忙，请稍后再试");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ResultGenerator.genFailResult("请求失败，请稍后再试");
        }
    }

    @Override
    public Result<Map<String, Object>> appPayParamV2(Map<String, String> map, DeviceMerchantBuyDTO deviceMerchantBuyDTO) {
        Map<String, Object> result = appPayParam(map);
        boolean createOrder = createOrder(map.get("outTradeNo") + "", deviceMerchantBuyDTO, request);
        if (createOrder) {
            deviceOrderInfoService.createOrder(map.get("outTradeNo") + "", deviceMerchantBuyDTO);
            return ResultGenerator.genSuccessResult(result);
        } else {
            return ResultGenerator.genFailResult("系统繁忙，请稍后再试");
        }
    }

    private AlipayTradeAppPayRequest getPayRequest(Map<String, String> map) {
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(map.get("body"));
        model.setSubject(map.get("subject"));
        model.setOutTradeNo(map.get("outTradeNo"));
        model.setTotalAmount(map.get("totalAmount"));
        appPayRequest.setBizModel(model);
        appPayRequest.setNotifyUrl(ParametersUtil.domain + "/wap/aliPay/aliCallBackV2");

        return appPayRequest;
    }

    @Override
    public Map<String, Object> appPayParam(Map<String, String> map) {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ParametersUtil.ZY_ALI_APP_ID, ParametersUtil.ZY_PRI, "json", "UTF-8", ParametersUtil.ZY_PUB, "RSA2");
        AlipayTradeAppPayRequest appPayRequest = getPayRequest(map);
        try {
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(appPayRequest);
            Map<String, Object> resultMap = new HashMap<>(16);
            resultMap.put("aliCode", response.getBody());
            return resultMap;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new MsgException("请求失败，请稍后再试");
        }
    }

    /**
     * createOrder:(创建订单). <br/>
     *
     * @param deviceMerchantBuyDTO
     * @return
     * 
     * @author Administrator
     * @since JDK 1.8
     */
    public boolean createOrder(String orderNo, DeviceMerchantBuyDTO deviceMerchantBuyDTO, HttpServletRequest request) {
        DeviceMerchantBuy deviceMerchantBuy = deviceMerchantBuyDTO.convertDeviceMerchantBuy();
        try {
            UserApp userApp = userAppService.queryUserAppByToken();
            Long userId = userApp.getUserId();
            MerchantBaseInfo merchantBaseInfo;
            List<MerchantBaseInfo> queryMerchantBaseInfoList = merchantBaseInfoMapper.selectListByUserId(userId);
            if (queryMerchantBaseInfoList != null && queryMerchantBaseInfoList.size() > 0) {
                merchantBaseInfo = queryMerchantBaseInfoList.get(0);
                deviceMerchantBuy.setMerchantCode(merchantBaseInfo.getMerchantCode());
                deviceMerchantBuy.setMerchantName(merchantBaseInfo.getMerchantName());
            }
            deviceMerchantBuy.setOrderNo(orderNo);
            deviceMerchantBuyService.saveDeviceMerchantBuy(deviceMerchantBuy);
            for (int i = 0; i < deviceMerchantBuyDTO.getQuantity(); i++) {
                DeviceMerchantBuyDetail deviceMerchantBuyDetail = new DeviceMerchantBuyDetail();
                deviceMerchantBuyDetail.setOrderNo(orderNo);
                deviceMerchantBuyDetail.setSoleCode(StringUtil.genRandomNum(3) + StringUtil.getBillno());
                deviceMerchantBuyDetailService.saveDeviceMerchantBuyDetail(deviceMerchantBuyDetail);
            }
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return false;
        }

    }

    @Override
    public Result<Map<String, Object>> appRefund(DeviceMerchantBuy deviceMerchantBuy) {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizContent("{" + "\"out_trade_no\":\"" + deviceMerchantBuy.getOrderNo() + "\"," + "\"refund_amount\":" + deviceMerchantBuy.getOrderAmount() + "" + "}");
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AliPayParam.getAppId(), AliPayParam.getPri(), "json", "UTF-8", AliPayParam.getPub(), "RSA2");
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                deviceMerchantBuy.setStatus("2");
                deviceMerchantBuyService.updateDeviceMerchantBuy(deviceMerchantBuy);
                Map<String, Object> result = new HashMap<String, Object>(16);
                result.put("aliCode", "退款成功");
                return ResultGenerator.genSuccessResult(result);
            } else {
                return ResultGenerator.genFailResult("退款失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ResultGenerator.genFailResult("退款失败");
        }

    }

    /**
     * 退款V2
     * @param orderDetail
     * @return
     */
    @Override
    public Map<String, Object> refundV2(MercOrderDetail orderDetail) {
        Map<String, Object> result = new HashMap<>(4);
        result.put("code", ResultCode.SUCCESS.code());
        result.put("msg","退款成功！");
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ParametersUtil.ZY_ALI_APP_ID, ParametersUtil.ZY_PRI, "json", "UTF-8", ParametersUtil.ZY_PUB, "RSA2");
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        String refundNo = "ALIR" + StringUtil.getBillno();
        result.put("refundNo",refundNo);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderDetail.getOrderNo());
        bizContent.put("refund_amount", orderDetail.getRefundAmt());
        bizContent.put("out_request_no", refundNo);
        bizContent.put("refund_reason",orderDetail.getRefundReason());
        request.setBizContent(bizContent.toString());
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            if(!response.isSuccess()){
                result.put("code",ResultCode.FAIL.code());
                result.put("msg",response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            result.put("code",ResultCode.FAIL.code());
            result.put("msg","退款失败");
        }
        return result;
    }
}
