package com.czg.third.alipay;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.v3.ApiException;
import com.alipay.v3.api.*;
import com.alipay.v3.model.*;
import com.czg.PayCst;
import com.czg.dto.req.*;
import com.czg.dto.resp.EntryThirdRespDto;
import com.czg.dto.resp.QueryStatusResp;
import com.czg.exception.CzgException;
import com.czg.pay.AlipayAuthInfoDto;
import com.czg.third.alipay.dto.config.AlipayConfigDto;
import com.czg.utils.UploadFileUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;

/**
 * 支付宝服务商进件管理
 * <a href="https://opendocs.alipay.com/open-v3/b4c46445_alipay.open.agent.create?scene=common&pathHash=d7084b4b">...</a>
 * @author yjjie
 * @date 2026/1/8 13:34
 */
@Slf4j
public class AlipayIsvEntryManager {

    public static QueryStatusResp queryMerchantBatchStatus(AlipayConfigDto configDto, String batchNo) {
        if (configDto == null) {
            configDto = AlipayConfigDto.getThirdDefaultConfig();
        }
        QueryStatusResp respDto = new QueryStatusResp()
                .setPlatform(PayCst.Type.ALIPAY);
        AlipayClient.setApiClient(configDto);

        try {
            AlipayOpenAgentOrderApi api = new AlipayOpenAgentOrderApi();
            AlipayOpenAgentOrderQueryResponseModel response = api.query(batchNo);

            log.info("支付宝查询进件状态: 响应={}", response);
            respDto.setApplyId(batchNo);

            switch (response.getOrderStatus()) {
                case "MERCHANT_INFO_HOLD" -> {
                    respDto.setStatus(PayCst.EntryStatus.REJECTED);
                    respDto.setFailReason("三方异常，请重新提交");
                    return respDto;
                }
                case "MERCHANT_CONFIRM_TIME_OUT" -> {
                    respDto.setStatus(PayCst.EntryStatus.REJECTED);
                    respDto.setFailReason("商户确认超时，请重新提交");
                    return respDto;
                }
                case "MERCHANT_AUDITING" -> {
                    respDto.setStatus(PayCst.EntryStatus.AUDIT);
                    respDto.setFailReason("");
                    return respDto;
                }
                case "MERCHANT_CONFIRM" -> {
                    respDto.setStatus(PayCst.EntryStatus.SIGN);
                    respDto.setFailReason("");
                    respDto.setSignUrl(response.getConfirmUrl());
                    return respDto;
                }
                case "MERCHANT_APPLY_ORDER_CANCELED" -> {
                    respDto.setStatus(PayCst.EntryStatus.REJECTED);
                    respDto.setFailReason(response.getRejectReason());
                    return respDto;
                }
                case "MERCHANT_CONFIRM_SUCCESS" -> {
                    respDto.setStatus(PayCst.EntryStatus.FINISH);
                    respDto.setFailReason("");
                    respDto.setThirdMerchantId(response.getMerchantPid());
                    return respDto;
                }
                case null -> {
                    respDto.setStatus(PayCst.EntryStatus.REJECTED);
                    respDto.setFailReason("查询失败");
                    return respDto;
                }
                default -> {
                    return respDto;
                }
            }

        } catch (ApiException e) {
            String body = e.getResponseBody();
            log.error("支付宝查询进件状态异常: {}", body);
            JSONObject object = JSONObject.parseObject(body);
            respDto.setStatus(PayCst.EntryStatus.REJECTED);
            respDto.setFailReason(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY));
            return respDto;
        }
    }

    /**
     * 创建商户
     * @param configDto 配置信息
     * @param reqDto 请求信息
     */
    public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) {
        if (configDto == null) {
            configDto = AlipayConfigDto.getThirdDefaultConfig();
        }
        AlipayClient.setApiClient(configDto);
        EntryThirdRespDto respDto = new EntryThirdRespDto()
                .setPlatform(PayCst.Type.ALIPAY);
        try {
            String batchNo = createRequest(configDto, reqDto);
            respDto.setEntryId(batchNo);

            AlipayOpenAgentFacetofaceSignModel signModel = buildFaceToFaceModel(reqDto, batchNo);
            File businessLicensePic = null;
            if (reqDto.getBusinessLicenceInfo() != null && reqDto.getBusinessLicenceInfo().getLicensePic() != null && StrUtil.isNotBlank(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl())) {
                businessLicensePic = UploadFileUtil.getFileByUrl(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl());
            }
            File shopScenePic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getInsidePic().getUrl());
            File shopSignBoardPic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getDoorPic().getUrl());

            log.info("支付宝开启代商户签约: 请求={}", JSONObject.toJSONString(signModel));

            // 构造请求参数以调用接口
            AlipayOpenAgentFacetofaceApi api = new AlipayOpenAgentFacetofaceApi();
            Object response = api.sign(null, businessLicensePic, signModel, shopScenePic, shopSignBoardPic, null);
            log.info("支付宝开启代商户签约: 响应={}", JSONObject.toJSONString(response));

            try {
                String authInfo = confirmRequest(configDto, batchNo);
                respDto.setAlipayAuthInfo(authInfo);
                respDto.setStatus(PayCst.EntryStatus.INIT);
                respDto.setErrorMsg("");
                return respDto;
            } catch (CzgException e) {
                respDto.setStatus(PayCst.EntryStatus.REJECTED);
                respDto.setErrorMsg(e.getMessage());
                return respDto;
            }
        } catch (ApiException e) {
            String body = e.getResponseBody();
            log.error("支付宝开启代商户签约，创建应用事务异常: {}", body);
            JSONObject object = JSONObject.parseObject(body);
            respDto.setStatus(PayCst.EntryStatus.REJECTED);
            respDto.setErrorMsg(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY));
            return respDto;
        } catch (Exception e) {
            log.error("支付宝开启代商户签约，创建应用事务异常2", e);
            respDto.setStatus(PayCst.EntryStatus.REJECTED);
            respDto.setErrorMsg(e.getMessage());
            return respDto;
        }
    }

    /**
     * 开启代商户签约、创建应用事务
     * @param reqDto 请求信息
     * @return 请求ID
     */
    public static String createRequest(AlipayConfigDto configDto, AggregateMerchantDto reqDto) {
        if (configDto == null) {
            configDto = AlipayConfigDto.getThirdDefaultConfig();
        }
        AlipayClient.setApiClient(configDto);
        AlipayOpenAgentApi api = new AlipayOpenAgentApi();
        AlipayOpenAgentCreateModel openModel = new AlipayOpenAgentCreateModel();

        MerchantBaseInfoDto info = reqDto.getMerchantBaseInfo();
        LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
        String contactPersonType = info.getContactPersonType();
        boolean isSuper = PayCst.ContactPersonType.SUPER.equals(contactPersonType);

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

        openModel.setAccount(reqDto.getMerchantBaseInfo().getAlipayAccount());

        try {
            AlipayOpenAgentCreateResponseModel responseModel = api.create(openModel);
            log.info("支付宝开启代商户签约，开启事务: 结果={}, batchNo={}", responseModel.getBatchStatus(), responseModel.getBatchNo());
            return responseModel.getBatchNo();
        } catch (ApiException e) {
            String body = e.getResponseBody();
            log.error("支付宝开启代商户签约，开启事务异常: {}", body);
            JSONObject object = JSONObject.parseObject(body);
            throw new CzgException("支付宝开启代商户签约，开启事务异常: " + object.getString(PayCst.ALIPAY_ERROR_MSG_KEY));
        }
    }

    public static String confirmRequest(AlipayConfigDto configDto, String batchNo) {
        if (configDto == null) {
            configDto = AlipayConfigDto.getThirdDefaultConfig();
        }
        AlipayClient.setApiClient(configDto);
        // 构造请求参数以调用接口
        AlipayOpenAgentApi api = new AlipayOpenAgentApi();
        AlipayOpenAgentConfirmModel data = new AlipayOpenAgentConfirmModel();

        // 设置ISV 代商户操作事务编号
        data.setBatchNo(batchNo);
        try {
            AlipayOpenAgentConfirmResponseModel response = api.confirm(data);
            log.info("支付宝开启代商户签约，确认事务: 响应={}", response);

            AlipayAuthInfoDto authInfoDto = new AlipayAuthInfoDto()
                    .setUserId(response.getUserId())
                    .setOpenId(response.getOpenId())
                    .setAuthAppId(response.getAuthAppId())
                    .setAppAuthToken(response.getAppAuthToken())
                    .setExpiresIn(response.getExpiresIn())
                    .setAppRefreshToken(response.getAppRefreshToken())
                    .setReExpiresIn(response.getReExpiresIn())
                    .setOrderNo(response.getOrderNo());
            return JSONObject.toJSONString(authInfoDto);
        } catch (ApiException e) {
            String body = e.getResponseBody();
            log.error("支付宝开启代商户签约，确认事务异常: {}", body);
            JSONObject object = JSONObject.parseObject(body);
            throw new CzgException(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY));
        }
    }

    /**
     * 构建 当面付参数
     */
    public static AlipayOpenAgentFacetofaceSignModel buildFaceToFaceModel(AggregateMerchantDto reqDto, String batchNo) {
        AlipayOpenAgentFacetofaceSignModel signModel = new AlipayOpenAgentFacetofaceSignModel();
        signModel.setBatchNo(batchNo);

        MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
        LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
        BusinessLicenceInfoDto licenceInfo = reqDto.getBusinessLicenceInfo();
        StoreInfoDto storeInfo = reqDto.getStoreInfo();

        signModel.setMccCode(baseInfo.getMccCode());
        signModel.setRate("0.38");
        signModel.setSignAndAuth(true);

        if (licenceInfo != null) {
            signModel.setBusinessLicenseNo(licenceInfo.getLicenceNo());
            signModel.setBusinessLicenseMobile(legalPersonInfo.getLegalPersonPhone());
            signModel.setLongTerm(PayCst.LONG_TERM_DATE.equals(licenceInfo.getLicenceEndDate()));
            signModel.setDateLimitation(licenceInfo.getLicenceStartDate());
        }

        signModel.setShopName(baseInfo.getShortName());

        // 设置店铺地址
        SignAddressInfo shopAddress = new SignAddressInfo();
        shopAddress.setCountryCode("156");
        shopAddress.setDistrictCode(storeInfo.getMercAreaCode());
        shopAddress.setDetailAddress(storeInfo.getBusinessAddress());
        shopAddress.setProvinceCode(storeInfo.getMercProvCode());
        shopAddress.setCityCode(storeInfo.getMercCityCode());
        signModel.setShopAddress(shopAddress);

        return signModel;
    }

    public static void main(String[] args) {
//        confirmRequest("2026010815384505500018243");
        queryMerchantBatchStatus(null, "2026012310512107600067177");

//        AggregateMerchantDto merchantDto = new AggregateMerchantDto();
//        merchantDto.setMerchantCode("CZG20260112151202099");
//
//        MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto();
//        baseInfoDto.setUserType("3");
//        baseInfoDto.setShortName("巩奕杰_商户");
//        baseInfoDto.setMccCode("A0001_B0199");
//        baseInfoDto.setAlipayAccount("15596653310");
//        baseInfoDto.setContactPersonType("SUPER");
//        baseInfoDto.setContactName("巩奕杰");
//        baseInfoDto.setCertType("0");
//        baseInfoDto.setContactPhone("15596653310");
//        baseInfoDto.setContactEmail("sankejuzi@163.com");
//        merchantDto.setMerchantBaseInfo(baseInfoDto);
//
//        StoreInfoDto storeInfoDto = new StoreInfoDto();
//        storeInfoDto.setBusinessAddress("陕西省西安市浐灞欧亚国际");
//        storeInfoDto.setMercAreaCode("610113");
//        storeInfoDto.setMercProvCode("610000");
//        storeInfoDto.setMercCityCode("610100");
//        storeInfoDto.setDoorPic(new ImageDto().setUrl("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/2c207c6f4a764ad18e501ed10fbfad59.png"));
//        storeInfoDto.setInsidePic(new ImageDto().setUrl("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/394b4834698a47e9b75419a5fd7f7de7.jpg"));
//        merchantDto.setStoreInfo(storeInfoDto);
//
//        entryMerchant(null, merchantDto);
    }
}
