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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.FileItem;
import com.alipay.api.domain.AlipayOpenAgentConfirmModel;
import com.alipay.api.domain.AlipayOpenAgentCreateModel;
import com.alipay.api.domain.ContactModel;
import com.alipay.api.domain.SignAddressInfo;
import com.alipay.api.request.AlipayOpenAgentConfirmRequest;
import com.alipay.api.request.AlipayOpenAgentCreateRequest;
import com.alipay.api.request.AlipayOpenAgentFacetofaceSignRequest;
import com.alipay.api.request.AlipayOpenAgentOrderQueryRequest;
import com.alipay.api.response.AlipayOpenAgentConfirmResponse;
import com.alipay.api.response.AlipayOpenAgentCreateResponse;
import com.alipay.api.response.AlipayOpenAgentFacetofaceSignResponse;
import com.alipay.api.response.AlipayOpenAgentOrderQueryResponse;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchApplymentService;
import com.jeequan.jeepay.core.model.applyment.AlipayApplymentInfo;
import com.jeequan.jeepay.core.model.applyment.ApplymentSignInfo;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvsubMchParams;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.thirdparty.model.AlipayClientWrapper;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.URL;

/**
 * 支付宝接口进件
 *
 * @author xiaoyu
 * 
 * @date 2022/1/17 9:58
 */
@Service
@Slf4j
public class AlipayMchApplymentService implements IIsvmchApplymentService<AlipayApplymentInfo> {

    @Autowired private ConfigContextQueryService configContextQueryService;
    @Autowired protected SysConfigService sysConfigService;
    @Autowired protected MchInfoService mchInfoService;

    @Override
    public MchApplyment firstApplyment(MchApplyment mchApplyment) {
        MchApplyment result = new MchApplyment();

        // 发起商户是否为特约商户
        if (StringUtils.isEmpty(mchApplyment.getIsvNo())) {
            throw new BizException("当前商户非特约商户");
        }

        // 查询当前商户信息
        MchInfo mchInfo = mchInfoService.getById(mchApplyment.getMchNo());

        MchAppConfigContext context = new MchAppConfigContext();
        context.setMchInfo(mchInfo);
        context.setMchType(mchInfo.getType());
        AlipayClientWrapper alipayClientWrapper = configContextQueryService.getAlipayClientWrapper(context);
        if (alipayClientWrapper == null) {
            throw new BizException("当前服务商未配置支付宝参数");
        }

        // 获取详细参数
        AlipayApplymentInfo info = JSON.parseObject(mchApplyment.getApplyDetailInfo(), AlipayApplymentInfo.class);

        /* 发起进件 */
        if (AlipayApplymentInfo.PRODUCT_TYPE_OFFLINE.equals(info.getProductType())) {   // 当面付
            result = toApplyOffline(info, alipayClientWrapper);
        }else {
            result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            result.setApplyErrorInfo("尚未支持该产品");
        }
        result.setApplyDetailInfo(JSON.toJSONString(info)); //重新更新全量参数（包含imgCache）

        return result;
    }

    @Override
    public MchApplyment rejectModify(MchApplyment mchApplyment) {
        return firstApplyment(mchApplyment);
    }

    @Override
    public MchApplyment replenishInfo(MchApplyment mchApplyment) {
        return null;
    }

    @Override
    public MchApplyment query(MchApplyment mchApplyment) {

        // 查询当前商户信息
        MchInfo mchInfo = mchInfoService.getById(mchApplyment.getMchNo());

        MchAppConfigContext context = new MchAppConfigContext();
        context.setMchInfo(mchInfo);
        context.setMchType(mchInfo.getType());
        AlipayClientWrapper alipayClientWrapper = configContextQueryService.getAlipayClientWrapper(context);
        if (alipayClientWrapper == null) {
            throw new BizException("当前服务商未配置支付宝参数");
        }
        // 调用查询接口
        AlipayOpenAgentOrderQueryRequest queryRequest = new AlipayOpenAgentOrderQueryRequest();
        // 调用进件接口
        JSONObject reqJSON = new JSONObject();
        reqJSON.put("batch_no", mchApplyment.getChannelApplyNo()); // 接入方商户号+申请编号 唯一
        queryRequest.setBizContent(reqJSON.toJSONString());
        log.info("请求支付宝进件查询接口参数： req={}", reqJSON);
        AlipayOpenAgentOrderQueryResponse queryResponse = alipayClientWrapper.execute(queryRequest);
        log.info("请求支付宝查询接口 code={}, msg={}, subCode={}, subMsg={}", queryResponse.getCode(), queryResponse.getMsg(), queryResponse.getSubCode(), queryResponse.getSubMsg());

        // 创建返回对象
        MchApplyment result = new MchApplyment();
        // 业务异常
        if(!queryResponse.isSuccess()){
            result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            result.setApplyErrorInfo(queryResponse.getCode() + "[" + queryResponse.getMsg() + "]" + queryResponse.getSubCode() + "[" + queryResponse.getSubMsg() + "]");
            return result;
        }

        // 审核状态
        if(queryResponse.isSuccess()){
            if ("MERCHANT_CONFIRM".equals(queryResponse.getOrderStatus())) {  // 待商户确认
                result.setState(MchApplyment.STATE_WAIT_SIGN);
                // 放置请求ID
                result.setChannelApplyNo(queryResponse.getAgentAppId());
                // 商户签约地址
                result.setApplyErrorInfo(queryResponse.getConfirmUrl());
            }else if ("MERCHANT_CONFIRM_SUCCESS".equals(queryResponse.getOrderStatus())) {  // 商户确认成功
                result.setState(MchApplyment.STATE_SUCCESS);

            }else if ("MERCHANT_AUDITING".equals(queryResponse.getOrderStatus())) {  // 审核中
                result.setState(MchApplyment.STATE_AUDITING);

            }else { // 异常失败
                result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                result.setApplyErrorInfo(queryResponse.getCode() + "[" + queryResponse.getMsg() + "]" + queryResponse.getSubCode() + "[" + queryResponse.getSubMsg() + "]" + "[" + queryResponse.getRejectReason() + "]");
            }

            // 封装支付参数
            AlipayIsvsubMchParams mchParams = new AlipayIsvsubMchParams();
            mchParams.setAppAuthToken(queryResponse.getMerchantPid());
            result.setSuccResParameter(JSON.toJSONString(mchParams));
            return result;
        }else{

            // 审核中
            result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            return result;

        }
    }

    @Override
    public ApplymentSignInfo signInfo(MchApplyment mchApplyment) {
        return null;
    }

    private MchApplyment toApplyOffline(AlipayApplymentInfo info, AlipayClientWrapper alipayClientWrapper) {
        // 创建返回对象
        MchApplyment result = new MchApplyment();
        String batchNo = "";
        try {
            /* 1.开启事务 */
            AlipayOpenAgentCreateRequest openRequest = new  AlipayOpenAgentCreateRequest();
            AlipayOpenAgentCreateModel openModel = new AlipayOpenAgentCreateModel();

            ContactModel contactModel = new ContactModel();
            contactModel.setContactName(info.getContactName());     // 联系人名称
            contactModel.setContactMobile(info.getContactPhone());  // 联系人手机号码
            contactModel.setContactEmail(info.getContactEmail());   // 联系人邮箱
            openModel.setContactInfo(contactModel);

            openModel.setAccount(info.getAccountNo());
            openRequest.setBizModel(openModel);

            AlipayOpenAgentCreateResponse response = alipayClientWrapper.execute(openRequest);
            log.info("【1】开启代商户签约，开启事务:code={}, msg={}", response.getCode(), response.getMsg());

            if (!response.isSuccess()) {
                result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                result.setApplyErrorInfo(response.getCode() + "[" + response.getMsg() + "]" + response.getSubCode() + "[" + response.getSubMsg() + "]");
                log.error("支付宝【当面付】进件开启事务失败；msg={}, subMsg={}", response.getMsg(), response.getSubMsg());
                return result;
            }
            if (!"init".equals(response.getBatchStatus())) {
                result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                result.setApplyErrorInfo(response.getCode() + "[" + response.getMsg() + "]" + response.getSubCode() + "[" + response.getSubMsg() + "]");
                log.error("支付宝【当面付】进件batchStatus状态不等于init，提交事务失败");
                return result;
            }
            batchNo = response.getBatchNo();

            // 放置请求ID
            result.setChannelApplyNo(batchNo);
            /* 2.发起待签约 */
            AlipayOpenAgentFacetofaceSignRequest offRequest = new AlipayOpenAgentFacetofaceSignRequest();

            offRequest.setBatchNo(batchNo); // 代商户操作事务编号

            offRequest.setMccCode(info.getMccCode()); // 所属经营类目编码

            // 特殊资质证书
            if (StringUtils.isNotEmpty(info.getSpecialLicenseImg())) {
                //下载文件 & 转换为byte数组格式
                byte[] imgFileByteArray = IOUtils.toByteArray(new URL(info.getSpecialLicenseImg()));
                offRequest.setSpecialLicensePic(new FileItem("1.png", imgFileByteArray));
            }

            // 服务费率
            offRequest.setRate(info.convertPaywayFeeList2String());

            // 营业执照编号
            offRequest.setBusinessLicenseNo(info.getLicenseNo());

            // 营业执照照片
            if (StringUtils.isNotEmpty(info.getLicenseImg())) {
                //下载文件 & 转换为byte数组格式
                byte[] imgFileByteArray = IOUtils.toByteArray(new URL(info.getLicenseImg()));
                offRequest.setBusinessLicensePic(new FileItem("1.png", imgFileByteArray));
            }
            // 营业期限
            if (StringUtils.isNotEmpty(info.getLicenseEffectEnd())) {
                if ("长期".equals(info.getLicenseEffectEnd())) {
                    offRequest.setLongTerm(true);
                }else {
                    offRequest.setDateLimitation(info.getLicenseEffectEnd());
                }
            }
            // 店铺门头照
            if (StringUtils.isNotEmpty(info.getStoreOuterImg())) {
                //下载文件 & 转换为byte数组格式
                byte[] imgFileByteArray = IOUtils.toByteArray(new URL(info.getStoreOuterImg()));
                offRequest.setShopSignBoardPic(new FileItem("1.png", imgFileByteArray));
            }
            // 门店名称
            offRequest.setShopName(info.getMchFullName());

            // 店铺内景照
            if (StringUtils.isNotEmpty(info.getStoreInnerImg())) {
                //下载文件 & 转换为byte数组格式
                byte[] imgFileByteArray = IOUtils.toByteArray(new URL(info.getStoreInnerImg()));
                offRequest.setShopScenePic(new FileItem("1.png", imgFileByteArray));
            }

            // 营业执照法人手机号
            offRequest.setBusinessLicenseMobile(info.getContactPhone());

            // 店铺地址
            SignAddressInfo addressInfo = new SignAddressInfo();
            addressInfo.setCountryCode("156");
            addressInfo.setProvinceCode(info.getAreaCode().getString(0));   // 省编码
            addressInfo.setCityCode(info.getAreaCode().getString(1));       // 市编码
            addressInfo.setDistrictCode(info.getAreaCode().getString(2));   // 区编码
            addressInfo.setDetailAddress(info.getAddress());                      // 详细地址
            offRequest.setShopAddress(addressInfo);

            AlipayOpenAgentFacetofaceSignResponse signResponse = alipayClientWrapper.execute(offRequest);
            log.info("【2】待签约当面付：code={}, msg={}, subCode={}, subMsg={}", signResponse.getCode(), signResponse.getMsg(), signResponse.getSubCode(), signResponse.getSubMsg());
            if (!signResponse.isSuccess()) {
                result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                result.setApplyErrorInfo(signResponse.getCode() + "[" + signResponse.getMsg() + "]" + signResponse.getSubCode() + "[" + signResponse.getSubMsg() + "]");
                log.error("发起待签约失败：code={}, msg={}, subCode={}, subMsg={}", signResponse.getCode(), signResponse.getMsg(), signResponse.getSubCode(), signResponse.getSubMsg());
                return result;
            }

            /* 3.提交待签约事务 */
            AlipayOpenAgentConfirmRequest confirmRequest = new AlipayOpenAgentConfirmRequest();
            AlipayOpenAgentConfirmModel confirmModel = new AlipayOpenAgentConfirmModel();
            confirmModel.setBatchNo(batchNo);
            confirmRequest.setBizModel(confirmModel);
            AlipayOpenAgentConfirmResponse confirmResponse = alipayClientWrapper.execute(confirmRequest);
            log.info("【3】提交待签约事务：code={}, msg={}, subCode={}, subMsg={}", confirmResponse.getCode(), confirmResponse.getMsg(), confirmResponse.getSubCode(), confirmResponse.getSubMsg());
            if (!confirmResponse.isSuccess()) {
                result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY); // 失败
                result.setApplyErrorInfo(confirmResponse.getCode() + "[" + confirmResponse.getMsg() + "]" + confirmResponse.getSubCode() + "[" + confirmResponse.getSubMsg() + "]");
                log.error("提交待签约事务失败：code={}, msg={}, subCode={}, subMsg={}", confirmResponse.getCode(), confirmResponse.getMsg(), confirmResponse.getSubCode(), confirmResponse.getSubMsg());
                return result;
            }
            result.setState(MchApplyment.STATE_AUDITING); // 审核中
        }catch (Exception e) {
            result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            result.setApplyErrorInfo("[" + e.getMessage() + "]");
            log.error("进件异常：{}", e.getMessage());
        }
        return result;
    }

}
