package com.jeequan.jeepay.mch.ctrl.paytest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.ApiField;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchConfig;
import com.jeequan.jeepay.db.entity.MchPayPassage;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.mch.ctrl.CommonCtrl;
import com.jeequan.jeepay.model.DeviceInfo;
import com.jeequan.jeepay.model.JeepayObject;
import com.jeequan.jeepay.request.PayOrderCreateRequest;
import com.jeequan.jeepay.response.PayOrderCreateResponse;
import com.jeequan.jeepay.service.impl.*;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashSet;
import java.util.Set;

/*
* 支付测试类
*
* @author terrfly
*
* @date 2021/6/22 9:43
*/
@RestController
@RequestMapping("/api/paytest")
public class PaytestController extends CommonCtrl {

    @Autowired private MchAppService mchAppService;
    @Autowired private MchPayPassageService mchPayPassageService;
    @Autowired private SysConfigService sysConfigService;
    @Autowired private MchConfigService mchConfigService;
    @Autowired private MchStoreService mchStoreService;

    /** 查询商户对应应用下支持的支付方式 **/
    @PreAuthorize("hasAuthority('ENT_MCH_PAY_TEST_PAYWAY_LIST')")
    @GetMapping("/payways/{appId}")
    public ApiRes payWayList(@PathVariable("appId") String appId) {
        JSONObject respJson = new JSONObject();
        Set<String> payWaySet = new HashSet<>();
        mchPayPassageService.list(
                MchPayPassage.gw().select(MchPayPassage::getWayCode)
                        .eq(MchPayPassage::getMchNo, getCurrentMchNo())
                        .eq(MchPayPassage::getAppId, appId)
                        .eq(MchPayPassage::getState, CS.PUB_USABLE)
        ).forEach(r -> payWaySet.add(r.getWayCode()));

        // 收银台权限默认开启
        respJson.put("webCashierIsShow", true);
        // 商户是否拥有便捷收银台权限
        Byte mchWebCashierConfig = mchConfigService.getConfigValByMchNoAndKey(getCurrentMchNo(), MchConfig.WEB_CASHIER_STATE, Byte.class);
        // 配置不为空 && 配置为关闭状态 显示状态修改为false
        if (mchWebCashierConfig != null && mchWebCashierConfig == CS.NO) {
            respJson.put("webCashierIsShow", false);
        }

        respJson.put("payWaySet", payWaySet);
        return ApiRes.ok(respJson);
    }


    /** 调起下单接口 **/
    @PreAuthorize("hasAnyAuthority('ENT_MCH_PAY_TEST_DO', 'ENT_C_QUICKCASHIER')")
    @PostMapping("/payOrders")
    public ApiRes doPay() {

        //获取请求参数
//        String appId = getValString("appId");
        String storeId = getValStringRequired("storeId");
        Long amount = getRequiredAmountL("amount");
        String mchOrderNo = getValStringRequired("mchOrderNo");
        String wayCode = getValStringRequired("wayCode");

        Byte divisionMode = getValByteRequired("divisionMode");
        String orderTitle = getValString("orderTitle");

        if(StringUtils.isEmpty(orderTitle)){
            throw new BizException("订单标题不能为空");
        }

        // 前端明确了支付参数的类型 payDataType
        String payDataType = getValString("payDataType");
        String authCode = getValString("authCode");
        String autoPosExtra = getValString("autoPosExtra");

        // 当前没有传入应用，那么使用默认应用
        MchStore store = mchStoreService.getById(storeId);

        MchAppEntity mchAppEntity = mchAppService.getById(store.getBindAppId());
        if(mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getAppId().equals(store.getBindAppId())){
            throw new BizException("商户应用不存在或不可用");
        }

        PayOrderCreateRequest request = new PayOrderCreateRequest();
        PayOrderCreateReqModelAddStoreId model = new PayOrderCreateReqModelAddStoreId();
        model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
        request.setBizModel(model);

        model.setMchNo(getCurrentMchNo()); // 商户号
        model.setAppId(store.getBindAppId());
        model.setStoreId(storeId);
        model.setMchOrderNo(mchOrderNo);
        model.setWayCode(wayCode);
        model.setAmount(amount);
        // PayPal通道使用USD类型货币
        if(wayCode.equalsIgnoreCase(CS.PAY_WAY_CODE.PP_PC)) {
            model.setCurrency("USD");
        }else {
            model.setCurrency("CNY");
        }
        model.setClientIp(getClientIp());
        model.setSubject(orderTitle + "[" + getCurrentMchNo() + "商户联调]");
        model.setBody(orderTitle + "[" + getCurrentMchNo() + "商户联调]");

        DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();

        model.setNotifyUrl(dbApplicationConfig.getMchSiteUrl() + "/api/anon/paytestNotify/payOrder"); //回调地址
        model.setDivisionMode(divisionMode); //分账模式
//        model.setReturnUrl("https://www.jeequan.com");

        //设置扩展参数
        JSONObject extParams = new JSONObject();
        if(StringUtils.isNotEmpty(payDataType)) {
            extParams.put("payDataType", payDataType.trim());
        }
        if(StringUtils.isNotEmpty(authCode)) {
            extParams.put("authCode", authCode.trim());
        }
        model.setChannelExtra(extParams.toString());

        if (StringUtils.isNotBlank(autoPosExtra)) {
            model.setChannelBizData(autoPosExtra); // 业务参数
            // 设备参数
            JSONObject deviceJSON = JSON.parseObject(autoPosExtra);
            if (deviceJSON != null && !deviceJSON.isEmpty()) {
                DeviceInfo deviceInfo = new DeviceInfo();
                deviceInfo.setDeviceType(PayOrder.DEVICE_TYPE_AUTO_POS);
                deviceInfo.setDeviceNo(deviceJSON.getString("deviceNo"));

                model.setDeviceInfo(deviceInfo);
            }
        }

        JeepayClient jeepayClient = new JeepayClient(dbApplicationConfig.getPaySiteUrl(), mchAppEntity.getAppSecret());

        try {
            PayOrderCreateResponse response = jeepayClient.execute(request);
            if(response.getCode() != 0){
                throw new BizException(response.getMsg());
            }
            return ApiRes.ok(response.get());
        } catch (JeepayException e) {
            throw new BizException(e.getMessage());
        }
    }

    /** 收银台地址 **/
    @PreAuthorize("hasAnyAuthority('ENT_MCH_CASHIER_URL')")
    @PostMapping("/createCashier")
    public ApiRes createCashier() {

        //获取请求参数
        String appId = getValString("appId");
        String storeId = getValStringRequired("storeId");

        // 当前没有传入应用，那么使用默认应用
        if(StringUtils.isBlank(appId)){
            appId = mchAppService.getDefaultApp(getCurrentMchNo()).getAppId();
        }

        MchAppEntity mchAppEntity = mchAppService.getById(appId);
        if(mchAppEntity == null || mchAppEntity.getState() != CS.PUB_USABLE || !mchAppEntity.getAppId().equals(appId)){
            throw new BizException("商户应用不存在或不可用");
        }

        DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
        try {
            String payUrl = dbApplicationConfig.genCashierPayUrl(appId, storeId+"");
            return ApiRes.ok(payUrl);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    /** 与阿里云sdk一样，  直接extends PayOrderCreateReqModel无法传入到接口中对应的参数。 需要把所有的参数放进来。。。   = = 。   **/
    @Data
    public static class PayOrderCreateReqModelAddStoreId extends JeepayObject {

        @ApiField("pas")
        private String pas;

        @ApiField("storeId")
        private String storeId;
        @ApiField("storeUserId")
        private Long storeUserId;

        private static final long serialVersionUID = -3998573128290306948L;

        @ApiField("mchNo")
        private String mchNo;      // 商户号
        @ApiField("appId")
        private String appId;      // 应用ID
        @ApiField("mchOrderNo")
        String mchOrderNo;          // 商户订单号
        @ApiField("wayCode")
        String wayCode;             // 支付方式
        @ApiField("amount")
        Long amount;                // 支付金额
        @ApiField("currency")
        String currency;            // 货币代码，当前只支持cny
        @ApiField("clientIp")
        String clientIp;            // 客户端IP
        @ApiField("subject")
        String subject;             // 商品标题
        @ApiField("body")
        String body;                // 商品描述
        @ApiField("channelBizData")
        String channelBizData;  // 渠道业务参数
        @ApiField("notifyUrl")
        String notifyUrl;           // 异步通知地址
        @ApiField("returnUrl")
        String returnUrl;           // 跳转通知地址
        @ApiField("expiredTime")
        String expiredTime;         // 订单失效时间
        @ApiField("channelExtra")
        String channelExtra;        // 特定渠道额外支付参数
        @ApiField("channelUser")
        String channelUser;         // 渠道用户标识,如微信openId,支付宝账号
        @ApiField("extParam")
        String extParam;            // 商户扩展参数
        @ApiField("divisionMode")
        private Byte divisionMode;   // 分账模式： 0-该笔订单不允许分账[默认], 1-支付成功按配置自动完成分账, 2-商户手动分账(解冻商户金额)
        @ApiField("sellerRemark")
        String sellerRemark;            // 卖家备注
        @ApiField("deviceInfo")
        private DeviceInfo deviceInfo;   // 设备信息


    }

}
