package com.czg.third.alipay;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.FileItem;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest;
import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest;
import com.alipay.api.request.AntMerchantExpandIndirectZftCreateRequest;
import com.alipay.api.request.AntMerchantExpandIndirectZftorderQueryRequest;
import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse;
import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse;
import com.alipay.api.response.AntMerchantExpandIndirectZftCreateResponse;
import com.alipay.api.response.AntMerchantExpandIndirectZftorderQueryResponse;
import com.alipay.v3.ApiClient;
import com.alipay.v3.ApiException;
import com.alipay.v3.Configuration;
import com.alipay.v3.api.AlipayOpenAgentApi;
import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse;
import com.alipay.v3.model.AlipayOpenAgentCreateModel;
import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel;
import com.alipay.v3.model.ContactModel;
import com.alipay.v3.util.model.AlipayConfig;
import com.czg.PayCst;
import com.czg.dto.req.*;
import com.czg.dto.resp.BankBranchDto;
import com.czg.dto.resp.EntryThirdRespDto;
import com.czg.dto.resp.QueryStatusResp;
import com.czg.exception.CzgException;
import com.czg.third.alipay.dto.config.AlipayConfigDto;
import com.czg.utils.UploadFileUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * 支付宝进件管理
 * <a href="https://opendocs.alipay.com/solution/9434dd99_ant.merchant.expand.indirect.zft.simplecreate?scene=bf5951260023430e944c2e9afdf7f9e2&pathHash=d3136936">...</a>
 *
 * @author yjjie
 * @date 2025/12/29 14:11
 */
@Slf4j
public class AlipayEntryManager {

    /**
     * 查询商户进件状态
     *
     * @param configDto    配置信息
     * @param merchantCode 自系统的商户编号
     * @return 进件状态
     */
    public static QueryStatusResp queryMerchantEntryStatus(AlipayConfigDto configDto, String merchantCode) {
        QueryStatusResp queryStatusResp = new QueryStatusResp();
        queryStatusResp.setPlatform(PayCst.Type.ALIPAY);
        queryStatusResp.setMerchantCode(merchantCode);

        AntMerchantExpandIndirectZftorderQueryRequest request = new AntMerchantExpandIndirectZftorderQueryRequest();

        AntMerchantExpandIndirectZftorderQueryModel model = new AntMerchantExpandIndirectZftorderQueryModel();
        model.setExternalId(merchantCode);

        request.setBizModel(model);

        try {
            DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
            AntMerchantExpandIndirectZftorderQueryResponse response = defaultAlipayClient.execute(request);
            log.info("支付宝查询进件状态结果：{}", response.getBody());

            if (response.isSuccess()) {
                List<ZftSubMerchantOrder> orders = response.getOrders();
                if (orders != null && !orders.isEmpty()) {
                    ZftSubMerchantOrder first = orders.getFirst();
                    queryStatusResp.setApplyId(first.getExternalId());

                    if ("99".equals(first.getStatus())) {
                        // 已完成
                        queryStatusResp.setStatus(PayCst.EntryStatus.FINISH);
                        queryStatusResp.setThirdMerchantId(first.getSmid());
                        queryStatusResp.setFailReason("");
                        return queryStatusResp;
                    }
                    if ("-1".equals(first.getStatus())) {
                        // 拒绝
                        queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
                        queryStatusResp.setFailReason(first.getReason());
                        return queryStatusResp;
                    }

                    if (StrUtil.isNotBlank(first.getFkAudit())) {
                        if ("REJECT".equals(first.getFkAudit())) {
                            // 风控拒绝
                            queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
                            queryStatusResp.setFailReason(first.getFkAuditMemo());
                            return queryStatusResp;
                        }

                        if ("CREATE".equals(first.getFkAudit())) {
                            queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT);
                            queryStatusResp.setFailReason(first.getFkAuditMemo());
                            return queryStatusResp;
                        }
                    }

                    if (StrUtil.isNotBlank(first.getKzAudit())) {
                        if ("REJECT".equals(first.getKzAudit())) {
                            // 风控拒绝
                            queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
                            queryStatusResp.setFailReason(first.getKzAuditMemo());
                            return queryStatusResp;
                        }

                        if ("CREATE".equals(first.getKzAudit())) {
                            queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT);
                            queryStatusResp.setFailReason(first.getKzAuditMemo());
                            return queryStatusResp;
                        }
                    }

                    if (StrUtil.isNotBlank(first.getSubConfirm()) && "FAIL".equals(first.getSubConfirm())) {
                        // 签约失败
                        queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
                        queryStatusResp.setFailReason("签约失败");
                        return queryStatusResp;
                    }

                    queryStatusResp.setStatus(PayCst.EntryStatus.SIGN);
                    queryStatusResp.setSignUrl(first.getSubSignQrCodeUrl());
                    return queryStatusResp;
                }
            } else {
                queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
                queryStatusResp.setFailReason(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("支付宝查询进件状态报错：{}", e.getMessage(), e);
            queryStatusResp.setStatus(PayCst.EntryStatus.INIT);
        }


        return queryStatusResp;
    }

    /**
     * 进件商户
     *
     * @param configDto 配置信息
     * @param reqDto    请求信息
     */
    public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) {
        AntMerchantExpandIndirectZftCreateModel entryReqDto = buildEntryParams(reqDto);
        EntryThirdRespDto respDto = new EntryThirdRespDto()
                .setPlatform(PayCst.Type.ALIPAY);

        try {
            AntMerchantExpandIndirectZftCreateRequest request = new AntMerchantExpandIndirectZftCreateRequest();
            DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
            request.setBizModel(entryReqDto);
            AntMerchantExpandIndirectZftCreateResponse response = defaultAlipayClient.execute(request);
            log.info("支付宝进件结果：{}", response.getBody());
            if (response.isSuccess()) {
                respDto.setStatus(PayCst.EntryStatus.INIT);
                respDto.setEntryId(response.getOrderId());
                respDto.setErrorMsg("");
            } else {
                respDto.setStatus(PayCst.EntryStatus.REJECTED);
                respDto.setEntryId("");
                respDto.setErrorMsg(response.getSubMsg());
            }
        } catch (Exception e) {
            log.error("支付宝进件报错：{}", e.getMessage(), e);
            respDto.setStatus(PayCst.EntryStatus.REJECTED);
            respDto.setEntryId("");
            respDto.setErrorMsg(e.getMessage());
        }

        return respDto;
    }

    /**
     * 上传图片
     *
     * @param configDto 配置信息
     * @param url       图片地址
     * @return 图片ID
     */
    public static String uploadImage(AlipayConfigDto configDto, String url) {
        try {
            byte[] bytes = UploadFileUtil.downloadImage(url);

            Path tempFile = Files.createTempFile("image_", ".png");

            // 写入数据
            Files.write(tempFile, bytes);

            File file = tempFile.toFile();

            AntMerchantExpandIndirectImageUploadRequest request = new AntMerchantExpandIndirectImageUploadRequest();
            request.setImageType(UploadFileUtil.extractImageExtension(url));

            // 设置图片内容
            FileItem imageContent = new FileItem(file);
            request.setImageContent(imageContent);

            DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
            AntMerchantExpandIndirectImageUploadResponse response = defaultAlipayClient.execute(request);

            return response.getImageId();
        } catch (Exception e) {
            log.error("支付宝上传图片报错，URL：{}，错误信息：{}", "url", e.getMessage(), e);
            return "";
        }
    }

    /**
     * 查询支行
     *
     * @param instId   顶级机构ID  CMB
     * @param province 省份 陕西省
     * @param city     城市 西安市
     */
    public static List<BankBranchDto> queryBankBranchList(AlipayConfigDto configDto, String instId, String province, String city) {
        try {
            AlipayFinancialnetAuthPbcnameQueryRequest request = new AlipayFinancialnetAuthPbcnameQueryRequest();

            AlipayFinancialnetAuthPbcnameQueryModel model = new AlipayFinancialnetAuthPbcnameQueryModel();
            model.setInstId(instId);
            model.setProvice(province);
            model.setCity(city);

            request.setBizModel(model);
            DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
            AlipayFinancialnetAuthPbcnameQueryResponse response = defaultAlipayClient.execute(request);

            String data = response.getPbcQueryResult();
            return JSONArray.parseArray(data, BankBranchDto.class);
        } catch (Exception e) {
            log.error("支付宝查询支行报错，错误信息：{}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 构建进件参数
     *
     * @param reqDto 请求参数
     * @return 进件参数
     */
    private static AntMerchantExpandIndirectZftCreateModel buildEntryParams(AggregateMerchantDto reqDto) {
        AntMerchantExpandIndirectZftCreateModel entryParams = new AntMerchantExpandIndirectZftCreateModel();

        MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
        LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
        BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo();
        StoreInfoDto storeInfo = reqDto.getStoreInfo();
        SettlementInfoDto settlementInfo = reqDto.getSettlementInfo();

        entryParams.setExternalId(reqDto.getMerchantCode());
        if ("0".equals(baseInfo.getUserType())) {
            entryParams.setMerchantType("07");
        } else if ("1".equals(baseInfo.getUserType())) {
            switch (baseInfo.getCompanyChildType()) {
                case "1" -> entryParams.setMerchantType("01");
                case "2" -> entryParams.setMerchantType("02");
                case "3" -> entryParams.setMerchantType("05");
                case "4" -> entryParams.setMerchantType("04");
                default -> throw new CzgException("主体类型错误");
            }
        } else {
            throw new CzgException("用户类型错误");
        }
        entryParams.setName(businessLicenceInfo.getLicenceName());
        entryParams.setAliasName(baseInfo.getShortName());
        entryParams.setMcc(baseInfo.getMccCode());
        entryParams.setService(List.of("当面付", "jsapi支付", "小程序支付"));
        entryParams.setInDoorImages(List.of(storeInfo.getInsidePic().getAlipayId(), storeInfo.getCashierDeskPic().getAlipayId()));
        entryParams.setOutDoorImages(List.of(storeInfo.getDoorPic().getAlipayId()));

        // 证件类型（目前只支持个体和企业，所以都是营业执照）
        entryParams.setCertType("201");
        entryParams.setCertImage(businessLicenceInfo.getLicensePic().getAlipayId());
        entryParams.setCertNo(businessLicenceInfo.getLicenceNo());

        entryParams.setLegalName(legalPersonInfo.getLegalPersonName());
        entryParams.setLegalCertNo(legalPersonInfo.getLegalPersonId());
        entryParams.setLegalCertFrontImage(legalPersonInfo.getIdCardFrontPic().getAlipayId());
        entryParams.setLegalCertBackImage(legalPersonInfo.getIdCardBackPic().getAlipayId());

        entryParams.setServicePhone(PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType()) ? legalPersonInfo.getLegalPersonPhone() : baseInfo.getContactPhone());

        com.alipay.api.domain.AddressInfo addressInfo = new com.alipay.api.domain.AddressInfo();
        addressInfo.setCityCode(storeInfo.getMercCityCode());
        addressInfo.setDistrictCode(storeInfo.getMercAreaCode());
        addressInfo.setProvinceCode(storeInfo.getMercProvCode());
        addressInfo.setAddress(storeInfo.getBusinessAddress());
        entryParams.setBusinessAddress(addressInfo);

        com.alipay.api.domain.SettleCardInfo settleCardInfo = new com.alipay.api.domain.SettleCardInfo();
        settleCardInfo.setAccountHolderName(settlementInfo.getSettlementName());
        settleCardInfo.setAccountNo(settlementInfo.getSettlementCardNo());
        settleCardInfo.setAccountInstProvince(settlementInfo.getOpenAccProvince());
        settleCardInfo.setAccountInstCity(settlementInfo.getOpenAccCity());
        settlementInfo.setBankBranchName(settlementInfo.getBankBranchName());
        settleCardInfo.setUsageType("21".equals(settlementInfo.getSettlementCardType()) ? "01" : "02");
        settleCardInfo.setAccountType("DC");
        settleCardInfo.setAccountInstName(settlementInfo.getBankName());
        settleCardInfo.setAccountInstId(settlementInfo.getBankInstId());
        settleCardInfo.setBankCode(settlementInfo.getBankBranchCode());
        entryParams.setBizCards(List.of(settleCardInfo));

        com.alipay.api.domain.ContactInfo contactInfo = new com.alipay.api.domain.ContactInfo();
        if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) {
            contactInfo.setName(baseInfo.getContactName());
            contactInfo.setMobile(baseInfo.getContactPhone());
            contactInfo.setEmail(baseInfo.getContactEmail());
            contactInfo.setIdCardNo(baseInfo.getContactPersonId());
        } else if (PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) {
            contactInfo.setName(legalPersonInfo.getLegalPersonName());
            contactInfo.setMobile(legalPersonInfo.getLegalPersonPhone());
            contactInfo.setEmail(legalPersonInfo.getLegalPersonEmail());
            contactInfo.setIdCardNo(legalPersonInfo.getLegalPersonId());
        } else {
            throw new CzgException("联系人类型错误");
        }
        entryParams.setContactInfos(List.of(contactInfo));

        entryParams.setLicenseAuthLetterImage(businessLicenceInfo.getLicensePic().getAlipayId());

        // 小程序
        SiteInfo miniAppInfo = new SiteInfo();
        miniAppInfo.setSiteType("06");
        miniAppInfo.setSiteUrl("https://sxczgkj.cn");
        miniAppInfo.setSiteName("银收客");
        miniAppInfo.setTinyAppId("2021004145625815");
        entryParams.setSites(List.of(miniAppInfo));

        return entryParams;
    }

    public static void main(String[] args) throws ApiException {

        queryBankBranchList(null, "CMB", "陕西省", "西安市");
//        uploadImage(null, "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg");

//        test();
    }

    // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753  直付通
    public static void test() throws ApiException {
        ApiClient defaultClient = Configuration.getDefaultApiClient();
        // 初始化alipay参数（全局设置一次）
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com");
        alipayConfig.setAppId("2021006121646825");
        alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB");
        alipayConfig.setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi");
        defaultClient.setAlipayConfig(alipayConfig);
        log.info("dd: {}", JSONObject.toJSONString(alipayConfig));
        AlipayOpenAgentApi api = new AlipayOpenAgentApi();
        AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel();
        ContactModel contactInfo = new ContactModel();
        contactInfo.setContactEmail("zhangsan@alipy.com");
        contactInfo.setContactName("张三");
        contactInfo.setContactMobile("18866668888");
        data.setContactInfo(contactInfo);
//        data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00");
        data.setAccount("1157756119@qq.com");
        try {
            AlipayOpenAgentCreateResponseModel response = api.create(data);
            System.out.println(response);
        } catch (ApiException e) {
            AlipayOpenAgentCreateDefaultResponse errorObject = (AlipayOpenAgentCreateDefaultResponse) e.getErrorObject();
            System.out.println("调用失败:" + errorObject);
            System.out.println("调用失败:" + e.getMessage());
        }
    }
}
