package com.jeequan.jeepay.thirdparty.channel.sybpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.TransferOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.openapi.biz.transfer.TransferOrderParam;
import com.jeequan.jeepay.core.model.params.IsvParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.thirdparty.channel.AbstractTransferService;
import com.jeequan.jeepay.thirdparty.channel.sybpay.kits.SybpayKits;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 转账接口： 收银呗
 */
@Slf4j
@Service
public class SybpayTransferService extends AbstractTransferService {

    @Override
    public String getIfCode() {
        return CS.IF_CODE.SYBPAY;
    }

    @Override
    public boolean isSupport(String entryType) {
        // 收银呗安全发仅支持 支付宝 和 银行卡入账方式
        if(TransferOrder.ENTRY_ALIPAY_CASH.equals(entryType) || TransferOrder.ENTRY_BANK_CARD.equals(entryType)){
            return true;
        }
        return false;
    }

    @Override
    public String preCheck(TransferOrderParam bizRQ, TransferOrder transferOrder) {
        super.preCheck(bizRQ, transferOrder);

        if(!TransferOrder.ENTRY_ALIPAY_CASH.equals(transferOrder.getEntryType()) && !TransferOrder.ENTRY_BANK_CARD.equals(transferOrder.getEntryType())){
            throw new BizException("只支持转账到支付宝或者银行卡");
        }
        //调用前查下余额
        JSONObject bizData = new JSONObject(2);
        JSONObject result = SybpayKits.reqApi(SybpayKits.QUERY_BALANCE_DOMAIN,bizData);
        BigDecimal balance = result.getBigDecimal("available_amount");
        BigDecimal amount = BigDecimal.valueOf(transferOrder.getAmount()).divide(BigDecimal.valueOf(100));
        if(amount.compareTo(balance) > 0){
            throw new BizException("账户余额不足，请及时充值");
        }
        return null;
    }

    @Override
    public ChannelRetMsg transfer(TransferOrderParam bizRQ, TransferOrder transferOrder) throws Exception {
        JSONObject reqData = new JSONObject();
        reqData.put("notifyUrl",getNotifyUrl(transferOrder.getTransferId()));
        reqData.put("name",transferOrder.getAccountName());
        reqData.put("outOrderNo",transferOrder.getTransferId());
        reqData.put("price", AmountUtil.convertCent2Dollar(transferOrder.getAmount()));
        reqData.put("remark",transferOrder.getTransferDesc());
        reqData.put("pay_type","1");
        if(TransferOrder.ENTRY_ALIPAY_CASH.equals(transferOrder.getEntryType())){
            reqData.put("pay_type","0");
        }
        String channelExtraStr = transferOrder.getChannelExtra();
        reqData.put("payee_inst_name",transferOrder.getBankName());
        reqData.put("payee_account_type","2");
        if(StringUtils.isNotEmpty(channelExtraStr)){
            JSONObject channelExtra = JSON.parseObject(channelExtraStr);
            reqData.put("inst_province",channelExtra.getString("provinceName"));
            reqData.put("inst_city",channelExtra.getString("cityName"));
            reqData.put("inst_branch_name",channelExtra.getString("branchName"));
            reqData.put("payee_account_type", MchApplyment.SETT_ACCOUNT_TYPE_CORPORATE.equals(channelExtra.getString("settleType")) ? "1" : "2");
        }
        reqData.put("account",transferOrder.getAccountNo());
        JSONObject result = SybpayKits.reqApi(SybpayKits.TRANS_DOMAIN,reqData);
        ChannelRetMsg retMsg = ChannelRetMsg.waiting();
        retMsg.setChannelOrderId(result.getString("order_sn"));
        return retMsg;
    }

    @Override
    public ChannelRetMsg query(TransferOrder transferOrder, IsvParams isvParams) {
        JSONObject reqData = new JSONObject();
        reqData.put("order_sn",transferOrder.getChannelOrderNo());
        JSONObject result = SybpayKits.reqApi(SybpayKits.TRANS_QUERY_DOMAIN,reqData);
        int state = result.getIntValue("state");
        if(state == 0 || state == 3){
            return ChannelRetMsg.waiting();
        }
        if (state == 1){
            return ChannelRetMsg.confirmSuccess(result.getString("order_sn"));
        }
        if (state == 2 || state == 4){
            return ChannelRetMsg.confirmFail(result.getString("state"),result.getString("request_msg"));
        }
        return ChannelRetMsg.waiting();
    }
}
