package cn.superdesk.uniorder.dubbo.provider.operationCenter.payment;

import cn.hutool.core.collection.CollectionUtil;
import cn.superdesk.data.extract.enums.opCenter.OpCenterBizPlatformEnum;
import cn.superdesk.uniorder.common.exception.UnifiedOrderRuntimeException;
import cn.superdesk.uniorder.common.exception.constants.ExceptionMsg;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.dao.entity.operationCenter.OperationCenterPayment;
import cn.superdesk.uniorder.dao.entity.operationCenter.OperationCenterPaymentBiz;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedPaymentCustomer;
import cn.superdesk.uniorder.dto.param.operationCenter.operators.OperationCenterPaymentCustomerParam;
import cn.superdesk.uniorder.dto.param.operationCenter.payment.OperationCenterPayParam;
import cn.superdesk.uniorder.dto.param.operationCenter.payment.OperationCenterPaymentBizParam;
import cn.superdesk.uniorder.dto.param.operationCenter.payment.OperationCenterPaymentParam;
import cn.superdesk.uniorder.dto.vo.operationCenter.base.OperationCenterVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OperationCenterPaymentCustomerVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.payment.OperationCenterPaymentVo;
import cn.superdesk.uniorder.dubbo.facade.operationCenter.payment.DubboOperationCenterPaymentService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterCustomerService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterPaymentBizService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterPaymentService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author : zx
 * @Create : 2023/3/29 12:50
 * Description :
 */
@Slf4j
@Service(version = "1.0.0", retries = -1, timeout = 10000)
public class DubboOperationCenterPaymentServiceImpl implements DubboOperationCenterPaymentService {

    @Autowired
    private OperationCenterPaymentService operationCenterPaymentService;
    @Autowired
    private OperationCenterPaymentBizService operationCenterPaymentBizService;
    @Autowired
    private OperationCenterCustomerService operationCenterCustomerService;
    @Autowired
    private cn.superdesk.uniorder.service.operationCenter.OperationCenterPaymentCustomerService OperationCenterPaymentCustomerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> addOrUpdateOperationCenterPayment(OperationCenterPaymentParam param, Long userId) {

        /**
         * 添加平台支付方式
         */
        OperationCenterPayment paymentEntity = new OperationCenterPayment();
        paymentEntity.setName(param.getPayName());
        paymentEntity.setIsCombined(param.getIsCombined().byteValue());
        paymentEntity.setAssociateType((byte) 0);//新增 初始值为0
        paymentEntity.setEnabled(param.getEnabled().byteValue());
        Map<String, Object> conditions = new HashMap<>();
        if (param.getId() == null) { //新增
            conditions.put("payName", param.getPayName());
            //支付方式名称不能重复，不包含删除
            OperationCenterPayment payment = operationCenterPaymentService.getPaymentByPayName(conditions);
            if (null != payment) {
                return new R<>("500", "该平台支付方式名称已存在，请重新输入", false);
            }
            if (CollectionUtil.isNotEmpty(param.getOperationCenterPaymentBizParamList())) {
                //业务平台+业务支付方式id 不允许在其他平台支付方式中存在（不含当前）
                List<OperationCenterPaymentBiz> paymentBizList = operationCenterPaymentBizService.getPaymentBizListByPayment(param.getOperationCenterPaymentBizParamList(), null);
                if (CollectionUtils.isNotEmpty(paymentBizList)) {
                    return new R<>("500", "业务平台（" + paymentBizList.get(0).getBizPlatformName()
                            + "）&业务支付方式id（" + paymentBizList.get(0).getBizPayTypeId()
                            + "），在其他平台支付方式中已存在，请勿重复添加", false);
                }

            }
            paymentEntity.setCreateTime(new Date());
            paymentEntity.setCreateUserId(userId);
            paymentEntity.setUpdateTime(new Date());
            paymentEntity.setUpdateUserId(userId);
            operationCenterPaymentService.insertSelective(paymentEntity);
        } else { //修改
            conditions.put("payName", param.getPayName());
            conditions.put("notContain", param.getId());
            //支付方式名称不能重复，不包含删除
            OperationCenterPayment payment = operationCenterPaymentService.getPaymentByPayName(conditions);
            if (null != payment) {
                return new R<>("500", "该平台支付方式名称已存在，请重新输入", false);
            }

            if (CollectionUtil.isNotEmpty(param.getOperationCenterPaymentBizParamList())) {
                //业务平台+业务支付方式id 不允许在其他平台支付方式中存在（不含当前）
                List<OperationCenterPaymentBiz> paymentBizList = operationCenterPaymentBizService.getPaymentBizListByPayment(param.getOperationCenterPaymentBizParamList(), param.getId());
                if (CollectionUtils.isNotEmpty(paymentBizList)) {
                    return new R<>("500", "业务平台（" + paymentBizList.get(0).getBizPlatformName()
                            + "）&业务支付方式id（" + paymentBizList.get(0).getBizPayTypeId()
                            + "），在其他平台支付方式中已存在，请勿重复添加", false);
                }
            }


            OperationCenterPayment entity = operationCenterPaymentService.findById(param.getId());
            if (null == entity) {
                return new R<>("500", "修改失败,为查询到支付方式", false);
            }
            paymentEntity.setAssociateType(entity.getAssociateType());//修改时 按照表中
            paymentEntity.setId(param.getId());
            paymentEntity.setUpdateTime(new Date());
            paymentEntity.setUpdateUserId(userId);
            operationCenterPaymentService.updateByPrimaryKeySelective(paymentEntity);
            //删除 所有业务支付方式
            operationCenterPaymentBizService.deleteByPaymentId(param.getId());
        }


        /**
         * 平台支付方式 - 业务方支付方式 映射关系
         */
        if (CollectionUtil.isNotEmpty(param.getOperationCenterPaymentBizParamList())) {
            for (OperationCenterPaymentBizParam vo : param.getOperationCenterPaymentBizParamList()) {
                OperationCenterPaymentBiz paymentBizEntity = new OperationCenterPaymentBiz();
                paymentBizEntity.setPaymentId(paymentEntity.getId());
                paymentBizEntity.setBizPlatformCode(vo.getBizPlatformCode());
                paymentBizEntity.setBizPlatformName(OpCenterBizPlatformEnum.getDescByCode(vo.getBizPlatformCode()));
                paymentBizEntity.setBizPayTypeId(vo.getBizPayTypeId());
                paymentBizEntity.setBizPayTypeName(vo.getBizPayTypeName());
                paymentBizEntity.setCreateTime(new Date());
                paymentBizEntity.setCreateUser(userId);
                operationCenterPaymentBizService.insertSelective(paymentBizEntity);
            }
        }
        return new R<>("成功！id:" + paymentEntity.getId());
    }

    @Override
    public R<List<OperationCenterPaymentVo>> getOperationCenterPaymentList(OperationCenterPayParam param) {
        List<OperationCenterPaymentVo> operationCenterPaymentVoList = operationCenterPaymentService.getOperationCenterPaymentList(param);

        return new R<List<OperationCenterPaymentVo>>(param.getPageNumber(), param.getPageSize(), operationCenterPaymentVoList.size(),  listToPage(param.getPageNumber(), param.getPageSize(), operationCenterPaymentVoList));
    }

    @Override
    public OperationCenterPaymentParam
    getPaymentById(Long id) {

        OperationCenterPayment paymentEntity = operationCenterPaymentService.findById(id);
        OperationCenterPaymentParam paymentVo = new OperationCenterPaymentParam();
        if (null == paymentEntity) {
            return paymentVo;
        }
        paymentVo.setId(paymentEntity.getId());
        paymentVo.setPayName(paymentEntity.getName());
        paymentVo.setEnabled(paymentEntity.getEnabled().intValue());
        paymentVo.setIsCombined(paymentEntity.getIsCombined().intValue());

        List<OperationCenterPaymentBizParam> paymentBizVoList = new ArrayList<>();

        List<OperationCenterPaymentBiz> paymentBizList = operationCenterPaymentBizService.getPaymentBizListByPaymentId(paymentEntity.getId());

        for (OperationCenterPaymentBiz vo : paymentBizList) {
            OperationCenterPaymentBizParam paymentBizVo = new OperationCenterPaymentBizParam();
            paymentBizVo.setBizPayTypeId(vo.getBizPayTypeId());
            paymentBizVo.setBizPlatformCode(vo.getBizPlatformCode());
            paymentBizVo.setBizPayTypeName(vo.getBizPayTypeName());
            paymentBizVoList.add(paymentBizVo);
        }

        paymentVo.setOperationCenterPaymentBizParamList(paymentBizVoList);

        return paymentVo;
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public void linkCustomer(OperationCenterPaymentCustomerParam param, Long userId) {
        OperationCenterPayment entity = operationCenterPaymentService.findById(param.getPaymentId());
        if (null == userId) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "关联客户失败!编辑人为空！" );
        }
        if (null == entity) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "关联客户失败!为查询到支付方式" + param.getPaymentId());
        }

        //判断 关联客户
        if (1 == param.getAssociateType()) {
            //不关联 -- 删除所有关联的客户 修改关联客户方式
            OperationCenterPaymentCustomerService.deleteByPaymentId(param.getPaymentId());

            OperationCenterPayment payment = new OperationCenterPayment();
            payment.setId(param.getPaymentId());
            payment.setAssociateType(param.getAssociateType().byteValue());
            payment.setUpdateUserId(userId);
            payment.setUpdateTime(new Date());
            operationCenterPaymentService.updateByPrimaryKeySelective(payment);
            return;
        }
        if (2 == param.getAssociateType()) {
            //关联所有客户 --删除所有关联的客户 修改关联客户方式
            OperationCenterPaymentCustomerService.deleteByPaymentId(param.getPaymentId());

            //查询所有客户
            List<OperationCenterVo> list = operationCenterCustomerService.selectAllCustomerIdAndName();

            if (CollectionUtils.isEmpty(list)) {
                throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "关联客户失败!--未查询到客户");
            }

            /** 当支付方式关联所有客户时
             *  1.0 将所有支付方式存一遍
             *  1.1 存一条客户id存null
             */

//            for (OperationCenterVo vo : list) {
//                UnifiedPaymentCustomer payOpCenterEntity = new UnifiedPaymentCustomer();
//                payOpCenterEntity.setPaymentId(param.getPaymentId());
//                payOpCenterEntity.setCustomerId(Long.parseLong(vo.getCode()));
//                payOpCenterEntity.setCreateTime(new Date());
//                payOpCenterEntity.setCreateUser(userId);
//                OperationCenterPaymentCustomerService.insertSelective(payOpCenterEntity);
//            }

            UnifiedPaymentCustomer payOpCenterEntity = new UnifiedPaymentCustomer();
            payOpCenterEntity.setPaymentId(param.getPaymentId());
            payOpCenterEntity.setCreateTime(new Date());
            payOpCenterEntity.setCreateUser(userId);
            OperationCenterPaymentCustomerService.insertSelective(payOpCenterEntity);



            OperationCenterPayment payment = new OperationCenterPayment();
            payment.setId(param.getPaymentId());
            payment.setAssociateType(param.getAssociateType().byteValue());
            payment.setUpdateUserId(userId);
            payment.setUpdateTime(new Date());
            operationCenterPaymentService.updateByPrimaryKeySelective(payment);
            return;
        }
        if (3 == param.getAssociateType()) {
            //指定客户 --入参 不能为空
            if (CollectionUtils.isEmpty(param.getOperationCenterPaymentCustomerVos())) {
                throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "关联客户失败!--未查询到客户！");
            }

            //关联指定客户 --删除所有关联的客户 修改关联客户方式
            OperationCenterPaymentCustomerService.deleteByPaymentId(param.getPaymentId());

            for (OperationCenterPaymentCustomerVo vo : param.getOperationCenterPaymentCustomerVos()) {
                UnifiedPaymentCustomer payOpCenterEntity = new UnifiedPaymentCustomer();
                payOpCenterEntity.setPaymentId(param.getPaymentId());
                payOpCenterEntity.setCustomerId(vo.getId());
                payOpCenterEntity.setCreateTime(new Date());
                payOpCenterEntity.setCreateUser(userId);
                OperationCenterPaymentCustomerService.insertSelective(payOpCenterEntity);
            }
            OperationCenterPayment payment = new OperationCenterPayment();
            payment.setId(param.getPaymentId());
            payment.setAssociateType(param.getAssociateType().byteValue());
            payment.setUpdateUserId(userId);
            payment.setUpdateTime(new Date());
            operationCenterPaymentService.updateByPrimaryKeySelective(payment);
            return;
        }
        log.info("===关联失败！=====param->AssociateType:--{}", param.getAssociateType());
        throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "关联客户失败!" + param.getAssociateType());

    }

    /**
     * 获取客户关联的平台支付方式
     */
    @Override
    public List<OperationCenterVo> getPaymentByCustomerId(Long customerId) {
        return operationCenterPaymentService.getPaymentByCustomerId(customerId);
    }

    @Override
    public R<OperationCenterPaymentCustomerParam> linkCustomerByPaymentId(String paymentId) throws UnifiedOrderRuntimeException{
        OperationCenterPaymentCustomerParam vo = new OperationCenterPaymentCustomerParam();
        //根据支付方式id查询
        OperationCenterPayment payment = operationCenterPaymentService.findById(Long.valueOf(paymentId));
        if (null == payment) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "未查询到该支付方式!+支付方式id为：" + paymentId);
        }
        //不是指定客户
        if (3 != payment.getAssociateType()) {
            vo.setPaymentId(payment.getId());
            vo.setPaymentName(payment.getName());
            vo.setAssociateType(payment.getAssociateType().intValue());
            return new R<>(vo);
        }

        //直接联表查询-关联
        vo = operationCenterPaymentService.linkCustomerByPaymentId(paymentId);
        return new R<>(vo);
    }


    /**
     * 将list手动进行分页
     */
    private List listToPage(int pageNo, int pageSize, List list) {
        List result = new ArrayList();
        if (list != null && list.size() > 0) {
            int allCount = list.size();
            int pageCount = (allCount + pageSize - 1) / pageSize;
            if (pageNo > pageCount) {
                pageNo = pageCount;
            }
            int start = (pageNo - 1) * pageSize;
            int end = pageNo * pageSize;
            if (end >= allCount) {
                end = allCount;
            }
            for (int i = start; i < end; i++) {
                result.add(list.get(i));
            }
        }

        return result;
    }

}
