package com.zhongshu.card.server.core.service.paySetting;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.net.ResultMessage;
import com.github.microservice.pay.client.model.AccountModel;
import com.github.microservice.pay.client.product.miniApp.weChat.conf.WeChatMiniAppConf;
import com.github.microservice.pay.client.product.senseless.chinaumsSenseless.conf.ChinaumsSenselessConf;
import com.github.microservice.pay.client.ret.ResultState;
import com.github.microservice.pay.client.service.PayProductAccountService;
import com.github.microservice.pay.client.type.PayProductChannelType;
import com.github.microservice.types.payment.PayFieldType;
import com.github.microservice.types.payment.PaymentType;
import com.zhongshu.card.client.model.org.BelongOigParam;
import com.zhongshu.card.client.model.paySetting.payConfig.FrictionlessUnionConfigModel;
import com.zhongshu.card.client.model.paySetting.payConfig.FrictionlessUnionConfigParam;
import com.zhongshu.card.client.model.paySetting.payConfig.LaKaLaCollectionConfig;
import com.zhongshu.card.client.model.paySetting.payConfig.LaKaLaCollectionConfigParam;
import com.zhongshu.card.client.model.paySetting.paySetting.*;
import com.zhongshu.card.client.model.paySetting.withdrawal.OrgWithdrawalModel;
import com.zhongshu.card.client.model.paySetting.withdrawal.OrgWithdrawalParam;
import com.zhongshu.card.client.model.payment.PaymentTypeParam;
import com.zhongshu.card.client.model.projectAbout.PayChannelSimpleModel;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dao.projectAbout.PayChannelConfigDao;
import com.zhongshu.card.server.core.dao.projectAbout.ProjectMainPaySettingDao;
import com.zhongshu.card.server.core.dao.projectAbout.ProjectOrgPaySettingInfoDao;
import com.zhongshu.card.server.core.dao.projectAbout.ProjectPaySettingDao;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.domain.paySetting.PayChannelConfig;
import com.zhongshu.card.server.core.domain.paySetting.ProjectMainPaySetting;
import com.zhongshu.card.server.core.domain.paySetting.ProjectOrgPaySettingInfo;
import com.zhongshu.card.server.core.domain.paySetting.ProjectPaySetting;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.pay.WithdrawService;
import com.zhongshu.card.server.core.service.payment.PayCallService;
import com.zhongshu.card.server.core.util.AesUtils;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.server.core.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目支付设置
 *
 * @author TRX
 * @date 2024/7/26
 */
@Slf4j
@Service
public class ProjectPaySettingServiceImpl extends SuperService {

    @Autowired
    private ProjectPaySettingDao projectPaySettingDao;

    @Autowired
    private ProjectOrgPaySettingInfoDao projectPaySettingInfoDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private GridFsTemplate gridFsTemplate;

    @Autowired
    private PayChannelConfigDao payChannelConfigDao;

    @Autowired
    private PayProductAccountService payProductAccountService;

    @Autowired
    private OrgPayAccountService orgPayAccountService;

    @Autowired
    private ProjectChannelConfigService projectChannelConfigService;

    @Autowired
    private ProjectMainPaySettingDao projectMainPaySettingDao;

    @Autowired
    private PayCallService payCallService;

    @Autowired
    private ProjectMainPaySettingService projectMainPaySettingService;

    @Autowired
    private WithdrawService withdrawService;

    /**
     * 关联支付渠道
     *
     * @return
     */
    public ResultContent savePayChannel(ProjectPaySettingParam param) {
        String projectOid = param.getProjectOid();
        if (StringUtils.isEmpty(projectOid)) {
            return ResultContent.buildFail("projectOid不能为空");
        }
        Organization project = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(project)) {
            return ResultContent.buildFail("项目不存在");
        }
        PayChannelConfig payChannelConfig = payChannelConfigDao.findTopById(param.getId());
        if (ObjectUtils.isEmpty(payChannelConfig)) {
            return ResultContent.buildFail("支付产品不存在");
        }
        PaymentType paymentType = payChannelConfig.getPaymentType();

        ProjectPaySetting projectPaySetting = projectPaySettingDao.findTopByProjectOidAndChannelType(projectOid, paymentType);
        if (ObjectUtils.isNotEmpty(projectPaySetting)) {
            return ResultContent.buildFail(String.format("%s已存在", paymentType.getRemark()));
        }
        projectPaySetting = new ProjectPaySetting();
        initEntityNoCheckOid(projectPaySetting);
        projectPaySetting.setProjectOid(projectOid);
        projectPaySetting.setProjectInfo(project);
        projectPaySetting.setProjectCode(project.getCode());
        projectPaySetting.setProjectName(project.getName());
        projectPaySetting.setChannelType(paymentType);
        projectPaySetting.setPaymentChannelType(payChannelConfig.getPaymentChannelType());

        projectPaySetting.setState(DataState.Disable);
        projectPaySettingDao.save(projectPaySetting);
        return ResultContent.buildSuccess();
    }

    /**
     * 项目得到所有的支付渠道配置
     *
     * @param projectOid
     * @return
     */
    public ResultContent<List<ProjectPaySettingModel>> getAllProjectPaySetting(String projectOid) {
        List<ProjectPaySetting> list = projectPaySettingDao.findByProjectOid(projectOid);
        List<ProjectPaySettingModel> models = new ArrayList<>(list.size());
        if (ObjectUtils.isNotEmpty(list)) {
            models = list.stream().map(this::toModel).collect(Collectors.toUnmodifiableList());
        }
        return ResultContent.buildSuccess(models);
    }

    public ResultContent deleteInfo(String id) {
        ProjectPaySetting paySetting = projectPaySettingDao.findTopById(id);
        if (ObjectUtils.isEmpty(paySetting)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        // 判断是否可以删除
        if (paySetting.getState() != null && paySetting.getState() == DataState.Enable) {
            return ResultContent.buildFail(String.format("%s已启用，不能删除！", paySetting.getChannelType().getRemark()));
        }
        projectPaySettingDao.delete(paySetting);
        // 维护支付中心的账户信息
        return ResultContent.buildSuccess();
    }

    public ResultContent changeState(String id, DataState state) {
        ProjectPaySetting paySetting = projectPaySettingDao.findTopById(id);
        if (ObjectUtils.isEmpty(paySetting)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        //TODO  检查是否可以启用
        if (state != null && state == DataState.Enable) {
            ProjectMainPaySetting mainPaySetting = projectMainPaySettingDao.findTopByProjectOidAndChannelType(paySetting.getProjectOid(), paySetting.getChannelType());
            if (ObjectUtils.isEmpty(mainPaySetting)) {
                return ResultContent.buildFail("未配置主账户信息或结算规则等，不能启用!");
            }
        }
        paySetting.setState(state);
        projectPaySettingDao.save(paySetting);

        // 更新支付中心的账号信息
        upsertPayAccount(paySetting.getProjectOid(), paySetting.getChannelType());
        return ResultContent.buildSuccess();
    }

    /**
     * 得到项目可用的支付渠道
     *
     * @param projectOid
     * @return
     */
    public List<OrgPayShowSettingModel> getProjectEnablePay(String projectOid) {
        List<ProjectPaySetting> list = projectPaySettingDao.findByProjectOidAndState(projectOid, DataState.Enable);
        List<OrgPayShowSettingModel> models = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(list)) {
            models = list.stream().map(it -> {
                OrgPayShowSettingModel model = new OrgPayShowSettingModel();
                model.setChannelType(payCallService.turnPaymentType(it.getChannelType()));

                // 支付产品信息
                PayChannelSimpleModel payChannelConfigModel = projectChannelConfigService.getProjectPayChannelSimpleModel(it.getChannelType());
                model.setPayChannelConfigModel(payChannelConfigModel);
                if (ObjectUtils.isNotEmpty(payChannelConfigModel)) {
                    model.setPaymentType(payChannelConfigModel.getPaymentType());
                }
                return model;
            }).collect(Collectors.toUnmodifiableList());
        }
        return models;
    }

    //-----------------------------通用配置方法 start----------------------------

    /**
     * 机构配置分页查询
     *
     * @param param
     * @param pageable
     * @return
     */
    public ResultContent<Page<ProjectPaySettingInfoModel>> page(ProjectPaySettingInfoSearch param, Pageable pageable) {
        Page<ProjectOrgPaySettingInfo> page = projectPaySettingInfoDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    /**
     * 得到项目的支付产品的所有 账户配置
     *
     * @param param
     * @return
     */
    public ResultContent<List<ProjectPaySettingInfoModel>> getOrgPaySettingInfo(BelongOigParam param) {
        List<ProjectPaySettingInfoModel> models = new ArrayList<>();
        List<ProjectOrgPaySettingInfo> list = projectPaySettingInfoDao.findByBelongOigAndProjectOid(param.getBelongOig(), param.getProjectOid());
        if (ObjectUtils.isNotEmpty(list)) {
            models = list.parallelStream().map(this::toModel).collect(Collectors.toUnmodifiableList());
        }
        return ResultContent.buildSuccess(models);
    }

    /**
     * 删除账户
     *
     * @param id
     * @return
     */
    public ResultContent deletePaySettingInfo(String id) {
        ProjectOrgPaySettingInfo entity = projectPaySettingInfoDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        // 判断是否可以删除
        int total = projectMainPaySettingDao.countByPaySettingInfo(entity);
        if (total > 0) {
            return ResultContent.buildFail("该账户已被项目引用，不能删除！");
        }
        projectPaySettingInfoDao.delete(entity);
        initChangeDefault(null, entity.getBelongOig(), entity.getProjectOid(), entity.getChannelType());
        return ResultContent.buildSuccess();
    }

    /**
     * 账户详情
     *
     * @param id
     * @return
     */
    public ResultContent getPaySettingInfo(String id) {
        ProjectOrgPaySettingInfo entity = projectPaySettingInfoDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        return ResultContent.buildSuccess(toModel(entity));
    }

    //-----------------------------微信支付的配置 start------------------

    /**
     * 保存项目的微信支付设置
     *
     * @param param
     * @return
     */
    public ResultContent saveWxPayConfig(WxPayConfigParam param) {
        // 机构初始支付产品对应的数据
        ResultContent<ProjectOrgPaySettingInfo> content = initProjectPayInfo(param);
        if (content.isFailed()) {
            return ResultContent.buildFail(content.getMsg());
        }
        ProjectOrgPaySettingInfo settingInfo = content.getContent();
        if (StringUtils.isEmpty(param.getNotifyUrl())) {
            param.setNotifyUrl(param.getNotifyUrl().trim());
        }
        //TODO 检查微信支付参数等
        WxPayConfigModel configModel = null;
        if (settingInfo.getPayConfig() != null) {
            configModel = (WxPayConfigModel) settingInfo.getPayConfig();
        }
        if (ObjectUtils.isEmpty(configModel)) {
            configModel = new WxPayConfigModel();
        }
        BeanUtils.copyProperties(param, configModel);

        // 证书文件
        MultipartFile privateKeyFile = param.getPrivateKeyFile();
        String privateKeyStr = AesUtils.turnMultipartFileToString(privateKeyFile);
        if (StringUtils.isNotEmpty(privateKeyStr)) {
            configModel.setPrivateKeyStr(privateKeyStr);
            configModel.setPrivateKeyFile(privateKeyFile.getOriginalFilename());
        }
        configModel.setPrivateKeyType("str");
        if (StringUtils.isEmpty(configModel.getPrivateKeyStr())) {
            return ResultContent.buildFail("证书文件为空");
        }
        settingInfo.setPayConfig(configModel);
        projectPaySettingInfoDao.save(settingInfo);

        // 如果当前设置为默认，把其他的取消默认
        initChangeDefault(settingInfo.getId(), settingInfo.getBelongOig(), settingInfo.getProjectOid(), settingInfo.getChannelType());

        upsertOrgAccount(settingInfo);
        return ResultContent.buildSuccess();
    }

    /**
     * 得到微信小程序支付的参数配置
     *
     * @param projectOid
     * @return
     */
    public ResultContent<WxPayConfigModel> getProjectWxConfig(String projectOid) {
        ResultContent<ProjectOrgPaySettingInfo> content = getProjectConfig(projectOid, PaymentType.WeChat);
        if (content.isFailed()) {
            return ResultContent.buildFail(content.getMsg());
        }
        WxPayConfigModel model = (WxPayConfigModel) content.getContent().getPayConfig();
        return ResultContent.buildSuccess(model);
    }

    //-----------------------------拉卡拉配置 start-------------------

    /**
     * 保存项目的微信支付设置
     *
     * @param param
     * @return
     */
    public ResultContent saveLaKaLaConfig(LaKaLaCollectionConfigParam param) {
        ResultContent<ProjectOrgPaySettingInfo> content = initProjectPayInfo(param);
        if (content.isFailed()) {
            return ResultContent.buildFail(content.getMsg());
        }
        ProjectOrgPaySettingInfo settingInfo = content.getContent();

        //TODO 检查支付参数等
        LaKaLaCollectionConfig laKaLaCollectionConfig = (LaKaLaCollectionConfig) settingInfo.getPayConfig();
        if (ObjectUtils.isEmpty(laKaLaCollectionConfig)) {
            laKaLaCollectionConfig = new LaKaLaCollectionConfig();
        }
        BeanUtils.copyProperties(param, laKaLaCollectionConfig);

        String priKeyBase64 = AesUtils.turnMultipartFileToBase64(param.getPriKeyFile());
        laKaLaCollectionConfig.setPriKeyBase64(priKeyBase64);

        String lklCerBase64 = AesUtils.turnMultipartFileToBase64(param.getLklCerFile());
        laKaLaCollectionConfig.setLklCerBase64(lklCerBase64);

        String lklNotifyCerBase64 = AesUtils.turnMultipartFileToBase64(param.getLklNotifyCerFile());
        laKaLaCollectionConfig.setLklNotifyCerBase64(lklNotifyCerBase64);

        settingInfo.setPayConfig(laKaLaCollectionConfig);
        projectPaySettingInfoDao.save(settingInfo);
        // 如果当前设置为默认，把其他的取消默认
        initChangeDefault(settingInfo.getId(), settingInfo.getBelongOig(), settingInfo.getProjectOid(), settingInfo.getChannelType());
        upsertOrgAccount(settingInfo);
        return ResultContent.buildSuccess();
    }

    /**
     * 银联云闪付参数配置
     *
     * @param param
     * @return
     */
    public ResultContent saveUnionPayConfig(FrictionlessUnionConfigParam param) {
        ResultContent<ProjectOrgPaySettingInfo> content = initProjectPayInfo(param);
        if (content.isFailed()) {
            return ResultContent.buildFail(content.getMsg());
        }
        ProjectOrgPaySettingInfo settingInfo = content.getContent();
        FrictionlessUnionConfigModel unionConfigModel = null;
        if (ObjectUtils.isNotEmpty(settingInfo) && settingInfo.getPayConfig() != null) {
            unionConfigModel = (FrictionlessUnionConfigModel) settingInfo.getPayConfig();
        }
        if (unionConfigModel == null) {
            unionConfigModel = new FrictionlessUnionConfigModel();
        }
        BeanUtils.copyProperties(param, unionConfigModel);

        settingInfo.setPayConfig(unionConfigModel);
        projectPaySettingInfoDao.save(settingInfo);

        // 如果当前设置为默认，把其他的取消默认
        initChangeDefault(settingInfo.getId(), settingInfo.getBelongOig(), settingInfo.getProjectOid(), settingInfo.getChannelType());
        upsertOrgAccount(settingInfo);
        return ResultContent.buildSuccess();
    }

    /**
     * @param param
     * @return
     */
    public ResultContent<ProjectOrgPaySettingInfo> initProjectPayInfo(PayConfigParam param) {
        // 所属项目
        Organization project = organizationDao.findTopByOid(param.getProjectOid());
        if (ObjectUtils.isEmpty(project)) {
            return ResultContent.buildFail("projectOid不存在");
        }
        // 所属机构
        Organization orgInfo = organizationDao.findTopByOid(param.getBelongOig());
        if (ObjectUtils.isEmpty(orgInfo)) {
            return ResultContent.buildFail(String.format("belongOig不存在"));
        }

        ProjectOrgPaySettingInfo temp = projectPaySettingInfoDao.findTopByBelongOigAndProjectOidAndChannelType(param.getBelongOig(), param.getProjectOid(), param.getChannelType());
        ProjectOrgPaySettingInfo projectPaySettingInfo = null;
        if (StringUtils.isNotEmpty(param.getId())) {
            // 编辑
            projectPaySettingInfo = projectPaySettingInfoDao.findTopById(param.getId());
            if (ObjectUtils.isEmpty(projectPaySettingInfo)) {
                return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, param.getId()));
            }
            // 支付渠道是否已存在
            if (ObjectUtils.isNotEmpty(temp) && !temp.getId().equals(projectPaySettingInfo.getId())) {
                return ResultContent.buildFail(String.format("支付渠道已存在：%s", param.getChannelType().getRemark()));
            }

            initUpdateEntity(projectPaySettingInfo);
        } else {
            // 新增
            PayChannelConfig channelConfig = payChannelConfigDao.findTopByPaymentType(param.getChannelType());
            if (ObjectUtils.isEmpty(channelConfig)) {
                return ResultContent.buildFail(String.format("支付渠道产品不存在：%s", param.getChannelType().getRemark()));
            }
            if (ObjectUtils.isNotEmpty(temp)) {
                return ResultContent.buildFail(String.format("支付渠道已存在：%s", param.getChannelType().getRemark()));
            }

            projectPaySettingInfo = new ProjectOrgPaySettingInfo();
            projectPaySettingInfo.setChannelType(channelConfig.getPaymentType());
            projectPaySettingInfo.setPaymentChannelType(channelConfig.getPaymentChannelType());

            // 项目信息
            projectPaySettingInfo.setProjectOid(project.getOid());
            projectPaySettingInfo.setProjectCode(project.getCode());

            // 机构信息
            projectPaySettingInfo.setBelongOig(orgInfo.getOid());
            projectPaySettingInfo.setOid(orgInfo.getOid());
            int total = projectPaySettingInfoDao.countByBelongOigAndProjectOidAndChannelType(orgInfo.getOid(), project.getOid(), param.getChannelType());
            if (total <= 0) {
                param.setIsDefault(Boolean.TRUE);
            }
        }
        projectPaySettingInfo.setProjectName(project.getName());
        projectPaySettingInfo.setBelongOrgName(orgInfo.getName());

        projectPaySettingInfo.setName(param.getName());
        projectPaySettingInfo.setIsDefault(param.getIsDefault());
        projectPaySettingInfo.setMchId(param.getMchId());
        projectPaySettingInfo.setBankAccountNumber(param.getBankAccountNumber());
        projectPaySettingInfo.setBankName(param.getBankName());
        projectPaySettingInfo.setBankSubName(param.getBankSubName());
        projectPaySettingInfo.setState(param.getState());

        return ResultContent.buildSuccess(projectPaySettingInfo);
    }

    /**
     * 得到机构在项目的支付配置
     *
     * @param projectOid
     * @param oid
     * @param paymentType
     */
    public OrgPayConfigModel getOrgPayConfig(String projectOid, String oid, PaymentType paymentType) {
        OrgPayConfigModel model = null;
        ProjectOrgPaySettingInfo temp = projectPaySettingInfoDao.findTopByBelongOigAndProjectOidAndChannelType(oid, projectOid, paymentType);
        if (ObjectUtils.isNotEmpty(temp)) {
            model = new OrgPayConfigModel();
            BeanUtils.copyProperties(temp, model);
        }
        return model;
    }

    /**
     * 项目中 机构提现 查询数据
     *
     * @param param
     * @return
     */
    public ResultContent<OrgWithdrawalModel> getOrgWithdrawal(OrgWithdrawalParam param) {
        if (param.getPaymentType() == null) {
            return ResultContent.buildFail("paymentType不能为空");
        }

        OrgWithdrawalModel model = new OrgWithdrawalModel();
        //1. 查询提现账号信息
        OrgPayConfigModel orgPayConfigModel = getOrgPayConfig(
                param.getProjectOid(), param.getOid(), param.getPaymentType(), Boolean.FALSE);
        model.setOrgPayConfigModel(orgPayConfigModel);

        // 查询项目的提现限制
        ProjectMainPaySetting projectMainPaySetting = projectMainPaySettingService.getProjectMainPaySetting(param.getProjectOid(), param.getPaymentType());
        if (projectMainPaySetting != null) {
            model.setWithdrawType(projectMainPaySetting.getWithdrawType());
            model.setWithdrawMethodType(projectMainPaySetting.getWithdrawMethodType());
            model.setMaxWithdraw(projectMainPaySetting.getMaxWithdraw());
            model.setMinWithdraw(projectMainPaySetting.getMinWithdraw());
        }
        // 查询提现余额
        com.github.microservice.net.ResultContent<Long> content = withdrawService.queryWithdrawAmount(param.getProjectOid(), param.getOid(), param.getPaymentType());
        if (content.getState() == com.github.microservice.net.ResultState.Success) {
            Long number = content.getContent();
            if (number != null) {
                model.setBalance(number);
                model.setWithdrawAmount(CommonUtil.turnLongMoney2Big(number));
            }
        }

        return ResultContent.buildSuccess(model);
    }

    /**
     * 查找结构在项目的支付配置参数
     *
     * @param projectOid
     * @param oid
     * @param paymentType
     * @param isMain
     * @return
     */
    public OrgPayConfigModel getOrgPayConfig(String projectOid, String oid, PaymentType paymentType, Boolean isMain) {
        OrgPayConfigModel model = null;
        ProjectOrgPaySettingInfo temp = projectPaySettingInfoDao.findTopByBelongOigAndProjectOidAndChannelTypeAndIsDefault(oid, projectOid, paymentType, isMain);
        if (ObjectUtils.isNotEmpty(temp)) {
            model = new OrgPayConfigModel();
            BeanUtils.copyProperties(temp, model);
        }
        return model;
    }

    public ResultContent initChangeDefault(String id, String belongOig, String projectOid, PaymentType paymentType) {
//        List<ProjectOrgPaySettingInfo> list = projectPaySettingInfoDao.findByBelongOigAndProjectOidAndChannelType(belongOig, projectOid, paymentType);
//        if (ObjectUtils.isNotEmpty(list)) {
//            List<ProjectOrgPaySettingInfo> _tempList = list.stream().filter(it -> it.getIsDefault() != null && it.getIsDefault()).collect(Collectors.toList());
//            if (ObjectUtils.isNotEmpty(_tempList)) {
//                if (_tempList.size() > 1 && StringUtils.isNotEmpty(id)) {
//                    // 其他的设置为  非默认
//                    _tempList.stream().forEach(it -> {
//                        if (!it.getId().equals(id)) {
//                            it.setIsDefault(Boolean.FALSE);
//                            projectPaySettingInfoDao.save(it);
//                        }
//                    });
//                }
//            } else {
//                ProjectOrgPaySettingInfo first = list.get(0);
//                first.setIsDefault(Boolean.TRUE);
//                projectPaySettingInfoDao.save(first);
//            }
//        }
        upsertPayAccount(projectOid, paymentType);
        return ResultContent.buildSuccess();
    }

    /**
     * 得到字段
     *
     * @param
     * @return
     */
    public ResultContent<PayConfigFieldModel> getFieldByConfigId(PaymentTypeParam param) {
        // 支付产品
        PayChannelConfig payChannelConfig = payChannelConfigDao.findTopByPaymentType(param.getPaymentType());
        if (ObjectUtils.isEmpty(payChannelConfig)) {
            return ResultContent.buildFail("支付产品数据不存在");
        }
        return getField(param.getPaymentType());
    }

    /**
     * 得到支付渠道 动态参数、动态字段
     *
     * @param paymentType
     * @return
     */
    public ResultContent<PayConfigFieldModel> getField(PaymentType paymentType) {
        PayConfigFieldModel model = new PayConfigFieldModel();
        if (paymentType == PaymentType.WeChat) {
            // 微信小程序支付
            model.setApiName("saveWxPayConfig");
            model.setFields(getWxConfig());
        } else if (paymentType == PaymentType.UnionFrictionlessPay) {
            // 银联云闪付
            model.setApiName("saveUnionPayConfig");
            model.setFields(getUnionPay());
            model.setType("json");
        }
        return ResultContent.buildSuccess(model);
    }

    /**
     * 得到微信支付需要的字段
     *
     * @return
     */
    public List<PayConfigField> getWxConfig() {
        List<PayConfigField> fields = new ArrayList<>(4);
        fields.add(PayConfigField.builder().name("appId").key("appId").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).build());
        fields.add(PayConfigField.builder().name("商户证书序列号").key("mchSerialNo").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).build());
        fields.add(PayConfigField.builder().name("V3密钥").key("apiV3Key").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).build());
        fields.add(PayConfigField.builder().name("证书文件").key("privateKeyFile").type(PayFieldType.File).isMust(Boolean.FALSE).build());
        fields.add(PayConfigField.builder().name("支付成功回调地址").key("notifyUrl").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(500).build());
        return fields;
    }

    /**
     * 银联云闪付字段
     *
     * @return
     */
    public List<PayConfigField> getUnionPay() {
        List<PayConfigField> fields = new ArrayList<>(4);

        List<Object> showMainAccount = new ArrayList<>();
        showMainAccount.add(Boolean.TRUE);
        PayShowField mainFiled = new PayShowField();
        mainFiled.setName("isDefault");
        mainFiled.setType(PayFieldType.Bool);
        mainFiled.setShowAccount(showMainAccount);

        fields.add(PayConfigField.builder().name("appId").key("appId").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("appKey").key("appKey").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("商户订单号开头").key("orderStart").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("终端号").key("tid").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).build());
        fields.add(PayConfigField.builder().name("协议模板id").key("planId").type(PayFieldType.Str).isMust(Boolean.TRUE).payShowField(mainFiled).maxLength(100).build());
        fields.add(PayConfigField.builder().name("密钥").key("notifySecret").type(PayFieldType.Str).isMust(Boolean.TRUE).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("来源系统Id").key("sysSource").type(PayFieldType.Str).isMust(Boolean.TRUE).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("来源编号").key("sysSourceNo").type(PayFieldType.Str).isMust(Boolean.TRUE).payShowField(mainFiled).build());

        fields.add(PayConfigField.builder().name("通知地址").key("notifyUrl").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(500).payShowField(mainFiled).build());

        // 提现
        fields.add(PayConfigField.builder().name("提现AppId").key("withdrawAppId").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("提现AppKey").key("withdrawAppKey").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("SysId").key("withdrawSysid").type(PayFieldType.Str).isMust(Boolean.TRUE).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("提现商户号").key("withdrawMid").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).build());
        fields.add(PayConfigField.builder().name("多应用类型").key("withdrawAppType").type(PayFieldType.Str).isMust(Boolean.TRUE).maxLength(100).payShowField(mainFiled).build());
        fields.add(PayConfigField.builder().name("提现通知地址").key("withdrawNotify").type(PayFieldType.Str).isMust(Boolean.FALSE).payShowField(mainFiled).build());


        return fields;
    }

    public ProjectPaySettingInfoModel toModel(ProjectOrgPaySettingInfo entity) {
        ProjectPaySettingInfoModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new ProjectPaySettingInfoModel();
            BeanUtils.copyProperties(entity, model);

            // 支付产品logo
            PayChannelConfig payChannelConfig = payChannelConfigDao.findTopByPaymentType(entity.getChannelType());
            if (ObjectUtils.isNotEmpty(payChannelConfig)) {
                model.setPayLogo(payChannelConfig.getLogo());
            }
            Organization organization = organizationDao.findTopByOid(entity.getBelongOig());
            if (ObjectUtils.isNotEmpty(organization)) {
                model.setBelongOrgName(organization.getName());
            }
        }
        return model;
    }

    /**
     * 得到项目的对应支付渠道的 参数配置 （验证是否一切正常）
     *
     * @param projectOid
     * @param paymentType
     * @return
     */
    public ResultContent<ProjectOrgPaySettingInfo> getProjectConfig(String projectOid, PaymentType paymentType) {
        if (paymentType == null) {
            return ResultContent.buildFail("PaymentType未指定");
        }
        // 平台的
        String payName = paymentType.getRemark();
        PayChannelConfig channelConfig = payChannelConfigDao.findTopByPaymentType(paymentType);
        if (ObjectUtils.isEmpty(channelConfig)) {
            return ResultContent.buildFail(String.format("平台不支持%s", payName));
        }
        if (channelConfig.getState() == null || channelConfig.getState() != DataState.Enable) {
            return ResultContent.buildFail(String.format("平台%s未启用", payName));
        }

        // 参数的配置 （默认状态的）
        ProjectOrgPaySettingInfo paySettingInfo = projectPaySettingInfoDao.findTopByProjectOidAndChannelTypeAndIsDefault(projectOid, paymentType, Boolean.TRUE);
        if (ObjectUtils.isEmpty(paySettingInfo)) {
            return ResultContent.buildFail(String.format("%s没有默认的支付配置", payName));
        }
        return ResultContent.buildSuccess(paySettingInfo);
    }

    public ResultContent<PaymentType> getProjectPayment(String projectOid) {
        ProjectPaySetting paySetting = projectPaySettingDao.findTopByProjectOidAndState(projectOid, DataState.Enable);
        if (ObjectUtils.isEmpty(paySetting)) {
            return ResultContent.buildFail(String.format("项目未设置可用的支付产品"));
        }
        PaymentType paymentType = null;
        if (paySetting.getChannelType() == PaymentType.WeChat) {
            paymentType = PaymentType.UserWallet;
        }
        return ResultContent.buildSuccess(paymentType);
    }

    /**
     * 更新/初始支付中心的数据
     *
     * @param projectOid
     * @param paymentType
     * @return
     */
    public ResultContent upsertPayAccount(String projectOid, PaymentType paymentType) {
        log.info("upsertPayAccount 维护项目支付中心的支付账号");
        ProjectMainPaySetting projectMainPaySetting = projectMainPaySettingDao.findTopByProjectOidAndChannelType(projectOid, paymentType);
        if (ObjectUtils.isEmpty(projectMainPaySetting)) {
            log.error("upsertPayAccount 项目未配置； {} {}", paymentType.getRemark(), projectOid);
            return ResultContent.buildFail("项目未配置");
        }
        ProjectOrgPaySettingInfo entity = projectMainPaySetting.getPaySettingInfo();
        if (ObjectUtils.isEmpty(entity)) {
            log.error("upsertPayAccount 关联机构支付配置为空");
            return ResultContent.buildFail("关联机构支付配置为空");
        }

        String payAccountName = orgPayAccountService.buildPayAccountName(projectOid, paymentType);

        AccountModel accountModel = new AccountModel();
        accountModel.setName(payAccountName);

        String remark = "";
        Boolean disable = Boolean.FALSE;
        if (ObjectUtils.isNotEmpty(entity)) {
            if (paymentType == PaymentType.WeChat) {
                // 微信支付
                accountModel.setProductChannelType(PayProductChannelType.WeChatMiniAppPay);
                WeChatMiniAppConf appConf = new WeChatMiniAppConf();
                WxPayConfigModel model = (WxPayConfigModel) entity.getPayConfig();
                appConf.setAppId(model.getAppId());
                appConf.setMchId(model.getMchId());
                appConf.setMchSerialNo(model.getMchSerialNo());
                appConf.setPriKeyPath(model.getPrivateKeyStr());
                appConf.setApiV3KeyPath(model.getApiV3Key());
                appConf.setNotifyUrl(model.getNotifyUrl());
                accountModel.setConf(appConf);
            } else if (paymentType == PaymentType.UnionFrictionlessPay) {
                // 银联无感支付
                accountModel.setProductChannelType(PayProductChannelType.ChinaumsSenseless);

                FrictionlessUnionConfigModel model = (FrictionlessUnionConfigModel) entity.getPayConfig();
                // 支付中心
                ChinaumsSenselessConf appConf = new ChinaumsSenselessConf();
                appConf.setAppId(model.getAppId());
                appConf.setAppKey(model.getAppKey());
                appConf.setOrderNoPrefix(model.getOrderStart());
                appConf.setMchId(model.getMchId());
                appConf.setTerminalNo(model.getTid());
                appConf.setPlanId(model.getPlanId());
                appConf.setSecretKey(model.getNotifySecret());
                appConf.setNotifyUrl(model.getNotifyUrl());
                appConf.setSysSource(model.getSysSource());
                appConf.setSysSourceNo(model.getSysSourceNo());

                // 提现
                appConf.setWithdrawAppId(model.getWithdrawAppId());
                appConf.setWithdrawAppKey(model.getWithdrawAppKey());
                appConf.setWithdrawSysId(model.getWithdrawSysid());
                appConf.setWithdrawMchId(model.getWithdrawMid());
                appConf.setAppType(model.getWithdrawAppType());

                accountModel.setConf(appConf);
            }

            if (!disable) {
                // 机构配置为开启
                if (entity.getState() == null || entity.getState() != DataState.Enable) {
                    disable = Boolean.TRUE;
                    remark = "机构配置未启用";
                }
            }

            if (!disable) {
                // 查看平台支付产品状态
                PayChannelConfig channelConfig = payChannelConfigDao.findTopByPaymentType(paymentType);
                if (ObjectUtils.isNotEmpty(channelConfig)) {
                    if (channelConfig.getState() != null && channelConfig.getState() == DataState.Enable) {
                        disable = Boolean.FALSE;
                    } else {
                        remark = "平台支付产品未启用";
                        disable = Boolean.TRUE;
                    }
                } else {
                    remark = "平台支付产品不存在";
                    disable = Boolean.TRUE;
                }
            }

            if (!disable) {
                // 项目配置 项目上没启用
                ProjectPaySetting projectPaySetting = projectPaySettingDao.findTopByProjectOidAndChannelType(projectOid, paymentType);
                if (projectPaySetting.getState() == null || projectPaySetting.getState() == DataState.Disable) {
                    disable = Boolean.TRUE;
                    remark = "项目上支付渠道未启用";
                }
            }
        } else {
            // 不可用
            disable = Boolean.TRUE;
            remark = "关联的主账户信息不存在";
        }
        accountModel.setDisable(disable);
        accountModel.setRemark(remark);
        com.github.microservice.pay.client.ret.ResultContent<Void> resultContent = payProductAccountService.upsert(accountModel);
        if (resultContent.getState() == ResultState.Success) {
            log.info("更新项目支付产品账户成功... disable {}", disable);
            orgPayAccountService.saveProjectAccount(projectOid, paymentType, accountModel.getProductChannelType());
        } else {
            log.error("更新项目支付产品账户出错： {}", resultContent.getMsg());
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 初始结构支付账户
     *
     * @param entity
     * @return
     */
    public ResultContent upsertOrgAccount(ProjectOrgPaySettingInfo entity) {
        log.info("维护机构的支付中心的支付账号");
        if (ObjectUtils.isEmpty(entity)) {
            log.error("upsertPayAccount 关联机构支付配置为空");
            return ResultContent.buildFail("关联机构支付配置为空");
        }

        String belongOig = entity.getBelongOig();
        PaymentType paymentType = entity.getChannelType();
        String payAccountName = orgPayAccountService.buildPayAccountName(belongOig, paymentType);

        AccountModel accountModel = new AccountModel();
        accountModel.setName(payAccountName);

        String remark = "";
        Boolean disable = Boolean.FALSE;
        if (ObjectUtils.isNotEmpty(entity)) {
            if (paymentType == PaymentType.WeChat) {
                // 微信支付
                accountModel.setProductChannelType(PayProductChannelType.WeChatMiniAppPay);

                WeChatMiniAppConf appConf = new WeChatMiniAppConf();
                WxPayConfigModel model = (WxPayConfigModel) entity.getPayConfig();
                appConf.setAppId(model.getAppId());
                appConf.setMchId(model.getMchId());
                appConf.setMchSerialNo(model.getMchSerialNo());
                appConf.setPriKeyPath(model.getPrivateKeyStr());
                appConf.setApiV3KeyPath(model.getApiV3Key());
                appConf.setNotifyUrl(model.getNotifyUrl());
                accountModel.setConf(appConf);
            } else if (paymentType == PaymentType.UnionFrictionlessPay) {
                // 银联无感支付
                accountModel.setProductChannelType(PayProductChannelType.ChinaumsSenseless);

                FrictionlessUnionConfigModel model = (FrictionlessUnionConfigModel) entity.getPayConfig();
                // 支付中心
                ChinaumsSenselessConf appConf = new ChinaumsSenselessConf();
                appConf.setAppId(model.getAppId());
                appConf.setAppKey(model.getAppKey());
                appConf.setOrderNoPrefix(model.getOrderStart());
                appConf.setMchId(model.getMchId());
                appConf.setTerminalNo(model.getTid());
                appConf.setPlanId(model.getPlanId());
                appConf.setSecretKey(model.getNotifySecret());
                appConf.setNotifyUrl(model.getNotifyUrl());
                appConf.setSysSource(model.getSysSource());
                appConf.setSysSourceNo(model.getSysSourceNo());

                // 提现参数
                appConf.setWithdrawAppId(model.getWithdrawAppId());
                appConf.setWithdrawAppKey(model.getWithdrawAppKey());
                appConf.setWithdrawSysId(model.getWithdrawSysid());
                appConf.setWithdrawMchId(model.getWithdrawMid());
                appConf.setAppType(model.getWithdrawAppType());

                accountModel.setConf(appConf);
            }

            if (!disable) {
                // 机构配置为开启
                if (entity.getState() == null || entity.getState() != DataState.Enable) {
                    disable = Boolean.TRUE;
                    remark = "机构配置未启用";
                }
            }
        } else {
            // 不可用
            disable = Boolean.TRUE;
            remark = "机构的账户信息不存在";
        }
        accountModel.setDisable(disable);
        accountModel.setRemark(remark);
        com.github.microservice.pay.client.ret.ResultContent<Void> resultContent = payProductAccountService.upsert(accountModel);
        if (resultContent.getState() == ResultState.Success) {
            log.info("更新机构支付产品账户成功... disable {}", disable);
            orgPayAccountService.saveProjectAccount(belongOig, paymentType, accountModel.getProductChannelType());
        } else {
            log.error("更新机构支付产品账户出错： {}", resultContent.getMsg());
        }
        return ResultContent.buildSuccess();
    }

    public ProjectPaySettingModel toModel(ProjectPaySetting entity) {
        ProjectPaySettingModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new ProjectPaySettingModel();
            BeanUtils.copyProperties(entity, model);
            // 关联的支付产品信息
            model.setPayChannelConfigModel(projectChannelConfigService.getProjectPayChannelModel(entity.getChannelType()));
            // 判断是否完成配置
            ProjectOrgPaySettingInfo settingInfo = projectPaySettingInfoDao.findTopByProjectOidAndChannelTypeAndIsDefault(entity.getProjectOid(), entity.getChannelType(), Boolean.TRUE);
            if (ObjectUtils.isNotEmpty(settingInfo)) {
                model.setIsConfig(Boolean.TRUE);
            }
        }
        return model;
    }
}
