package cn.iocoder.yudao.module.custom.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.custom.entity.*;
import cn.iocoder.yudao.module.custom.mapper.CustomerActiveMapper;
import cn.iocoder.yudao.module.custom.service.*;
import cn.iocoder.yudao.module.custom.vo.CustomerActivePageReqVO;
import cn.iocoder.yudao.module.custom.vo.CustomerActiveSaveReqVO;
import cn.iocoder.yudao.module.custom.vo.CustomerMainRespVO;
import cn.iocoder.yudao.module.member.entity.ActiveMain;
import cn.iocoder.yudao.module.member.entity.ActiveRule;
import cn.iocoder.yudao.module.member.entity.MemberCoupon;
import cn.iocoder.yudao.module.member.service.ActiveMainService;
import cn.iocoder.yudao.module.member.service.MemberCouponService;
import cn.iocoder.yudao.module.member.vo.ActiveMainPageReqVO;
import cn.iocoder.yudao.module.member.vo.ActiveMainRespVO;
import cn.iocoder.yudao.module.order.entity.RepairOrderInfo;
import cn.iocoder.yudao.module.order.service.RepairOrderInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mzt.logapi.service.IFunctionService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.common.BaseConstants.*;
import static cn.iocoder.yudao.common.ErrorCodeConstants.CUSTOMER_ACTIVE_NO_RULE;
import static cn.iocoder.yudao.common.ErrorCodeConstants.CUSTOMER_ACTIVE_ONE_COUPON;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 用户参与活动记录 Service 实现类
 *
 * @author pqz
 */
@Service
@Validated
public class CustomerActiveServiceImpl extends ServiceImpl<CustomerActiveMapper, CustomerActive> implements CustomerActiveService {

    @Resource
    private CustomerActiveMapper customerActiveMapper;
    @Resource
    private ActiveMainService activeMainService;
    @Resource
    private CustomerMainService customerMainService;
    @Resource
    private MemberCouponService couponService;
    @Resource
    private CustomerBalanceChangeService changeService;
    @Resource
    private CustomerCouponService customerCouponService;
    @Resource
    @Lazy
    private RepairOrderInfoService repairOrderInfoService;


    /**
     * 参与活动（临时保留后续作废）
     *
     * @param saveReqVO CustomerActiveSaveReqVO实体
     * @author PQZ
     * @date 9:57 2024/9/21
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RepairOrderInfo attendActive(CustomerActiveSaveReqVO saveReqVO) {
        /*1、基础数据初始化*/
        //当前客户信息
        CustomerMainRespVO customer = customerMainService.getCustomerById(saveReqVO.getCusId());
        //获取当前活动信息
        ActiveMainRespVO active = activeMainService.getActiveMain(saveReqVO.getActiveId(), true);
        //需要保存的变动日志集合
        List<CustomerBalanceChange> changeList = new ArrayList<>();
        //需要保存的参与活动日志
        CustomerActive customerActive = new CustomerActive();
        //需保保存的用户卡券领取内容
        List<CustomerCoupon> customerCouponList = null;
        //需保保存的用户积分余额信息
        CustomerBalance balance;
        //要返回的订单数据
        RepairOrderInfo resultOrder = null;

        /*2、活动关联卡券处理*/
        if (GENERAL_YES.equals(active.getIsCoupon())) {
            //注册有礼情况直接领取
            if (GENERAL_YES.equals(active.getIsPack())) {
                if ("zcyl".equals(active.getType())) {
                    /*2.1 打包领取情况*/
                    List<MemberCoupon> couponList = active.getCouponList();
                    //转换卡券信息
                    customerCouponList = customerCouponService.transCoupon(active.getId(), customer.getId(), customer.getUserId(), couponList);
                    //转换日志信息
                    changeList = changeService.transChange(customer.getId(), customer.getUserId(), active.getName(), couponList);
                }
            } else {
                /*2.2 非打包领取情况*/
                //选中卡券校验
                if (null == saveReqVO.getSelectCoupon() || saveReqVO.getSelectCoupon().isEmpty()) {
                    throw exception(CUSTOMER_ACTIVE_ONE_COUPON);
                }
                //查询出当前选中的卡券及附属卡券
                List<String> ids = saveReqVO.getSelectCoupon().stream().map(MemberCoupon::getId).collect(Collectors.toList());
                //查询选中卡片信息
                List<MemberCoupon> couponList = couponService.listByIds(ids, false);
                if (CollectionUtil.isNotEmpty(couponList)) {
                    MemberCoupon item = couponList.get(0);
                    RepairOrderInfo orderInfo = new RepairOrderInfo();
                    orderInfo.setOrderNo(System.currentTimeMillis() + Math.abs(item.getId().hashCode() % 1000) + "");
                    orderInfo.setGoodsId(item.getId());
                    orderInfo.setActiveId(active.getId());
                    orderInfo.setGoodsTitle(item.getName());
                    orderInfo.setTenantName(ORDER_TENANT_NAME);
                    orderInfo.setGoodsType(ORDER_KKYL);
                    orderInfo.setUserId(customer.getUserId());
                    orderInfo.setCusId(customer.getId());
                    orderInfo.setCusName(customer.getCusName());
                    orderInfo.setCusPhone(customer.getPhoneNumber());
                    orderInfo.setGoodsPrice(item.getAmount());
                    orderInfo.setPayMoney(item.getAmount());
                    orderInfo.setOrderTime(LocalDateTime.now());
                    orderInfo.setIsOnline("01");
                    orderInfo.setOrderStatus("0");
                    orderInfo.setPayType(saveReqVO.getAccountType());
                    repairOrderInfoService.save(orderInfo);
                    resultOrder = repairOrderInfoService.getById(orderInfo.getId());
                }

//                couponList.forEach(item -> {
//
//                });
                //转换卡券信息
//                customerCouponList = transCoupon(active.getId(), customer.getId(), customer.getUserId(), couponList);
                //转换日志信息
//                changeList = transChange(customer.getId(), customer.getUserId(), active.getName(), couponList);
            }
            //保存用户卡券
            if (null != customerCouponList) {
                customerCouponService.saveBatch(customerCouponList);
            }
        }

        /*3、活动关联充值规则处理*/
        if (GENERAL_YES.equals(active.getIsRechRule())) {
            //校验是否存在充值规则
            if (null == active.getRuleList() || active.getRuleList().isEmpty()) {
                throw exception(CUSTOMER_ACTIVE_NO_RULE);
            }
//            List<ActiveRule> ruleList = active.getRuleList();
            //转换余额信息
//            balance = transBalance(customer, saveReqVO.getTopUpAmount(), ruleList);
            //记录日志
            CustomerBalanceChange change = changeService.initChange(customer.getId(),
                    customer.getUserId(), null, BALANCE_CHANGE_TYPE_CZ, BALANCE_CHANGE_MAIN_YE,
                    null, saveReqVO.getTopUpAmount(), new BigDecimal(0), "参加" + active.getName() + "活动充值" + saveReqVO.getTopUpAmount() + "元");
            changeService.save(change);
            RepairOrderInfo orderInfo = new RepairOrderInfo();
            orderInfo.setOrderNo(System.currentTimeMillis() + Math.abs(change.getId().hashCode() % 1000) + "");
            orderInfo.setGoodsId(change.getId());
            orderInfo.setActiveId(active.getId());
            orderInfo.setGoodsTitle(active.getName());
            orderInfo.setTenantName(ORDER_TENANT_NAME);
            orderInfo.setGoodsType(ORDER_HYCZ);
            orderInfo.setUserId(customer.getUserId());
            orderInfo.setCusId(customer.getId());
            orderInfo.setCusName(customer.getCusName());
            orderInfo.setCusPhone(customer.getPhoneNumber());
            orderInfo.setGoodsPrice(saveReqVO.getTopUpAmount());
            orderInfo.setPayMoney(saveReqVO.getTopUpAmount());
            orderInfo.setOrderTime(LocalDateTime.now());
            orderInfo.setIsOnline("01");
            orderInfo.setOrderStatus("0");
            orderInfo.setPayType(saveReqVO.getAccountType());
            repairOrderInfoService.save(orderInfo);
            resultOrder = repairOrderInfoService.getById(orderInfo.getId());
            //保存余额信息
//            balanceService.updateByCusId(balance);
        }

        /*4、保存参与活动信息*/
        customerActive.setActiveId(active.getId());
        customerActive.setUserId(customer.getUserId());
        customerActive.setCusId(customer.getId());
        customerActive.setActiveName(active.getName());
        customerActive.setActiveType(active.getType());
        customerActive.setRemark(active.getRemark());
        save(customerActive);

        /*5、保存变动日志*/
        //保存变动日志
        changeService.saveBatch(changeList);
        return resultOrder;
    }

    /**
     * 新版参与活动方法
     *
     * @param saveReqVO CustomerActiveSaveReqVO
     * @return cn.iocoder.yudao.module.order.entity.RepairOrderInfo
     * @author PQZ
     * @date 11:38 2024/9/28
     **/
    @Override
    public RepairOrderInfo attendActiveOrder(CustomerActiveSaveReqVO saveReqVO) {
        /*1、基础数据初始化*/
        //当前客户信息
        CustomerMainRespVO customer = customerMainService.getCustomerById(saveReqVO.getCusId());
        //获取当前活动信息
        ActiveMainRespVO active = activeMainService.getActiveMain(saveReqVO.getActiveId(), true);
        //需要保存的变动日志集合
        List<CustomerBalanceChange> changeList = new ArrayList<>();
        //需要保存的参与活动日志
        CustomerActive customerActive = new CustomerActive();
        //需保保存的用户卡券领取内容
        List<CustomerCoupon> customerCouponList = null;
        //需保保存的用户积分余额信息
        CustomerBalance balance;
        //要返回的订单数据
        RepairOrderInfo resultOrder = null;

        /*2、各类型活动处理*/
        if ("zcyl".equals(active.getType())) {
            //注册有礼
            List<MemberCoupon> couponList = active.getCouponList();
            //转换卡券信息
            customerCouponList = customerCouponService.transCoupon(active.getId(), customer.getId(), customer.getUserId(), couponList);
            //转换日志信息
            changeList = changeService.transChange(customer.getId(), customer.getUserId(), active.getName(), couponList);
        } else if ("kkyl".equals(active.getType())) {
            //开卡有礼
            if (null == saveReqVO.getSelectCoupon() || saveReqVO.getSelectCoupon().isEmpty()) {
                throw exception(CUSTOMER_ACTIVE_ONE_COUPON);
            }
            //查询出当前选中的卡券及附属卡券
            List<String> ids = saveReqVO.getSelectCoupon().stream().map(MemberCoupon::getId).collect(Collectors.toList());
            //查询选中卡片信息
            List<MemberCoupon> couponList = couponService.listByIds(ids, false);
            if (CollectionUtil.isNotEmpty(couponList)) {
                //选择的开卡内容设定为单选
                MemberCoupon item = couponList.get(0);
                RepairOrderInfo orderInfo = new RepairOrderInfo();
                orderInfo.setOrderNo(System.currentTimeMillis() + Math.abs(item.getId().hashCode() % 1000) + "");
                orderInfo.setGoodsId(item.getId());
                orderInfo.setActiveId(active.getId());
                orderInfo.setGoodsTitle(item.getName());
                orderInfo.setTenantName(ORDER_TENANT_NAME);
                orderInfo.setGoodsType(ORDER_KKYL);
                orderInfo.setUserId(customer.getUserId());
                orderInfo.setCusId(customer.getId());
                orderInfo.setCusName(customer.getCusName());
                orderInfo.setCusPhone(customer.getPhoneNumber());
                orderInfo.setGoodsPrice(item.getAmount());
                orderInfo.setPayMoney(item.getAmount());
                orderInfo.setOrderTime(LocalDateTime.now());
                orderInfo.setOrderStatus("0");
                orderInfo.setPayType(saveReqVO.getAccountType());
                repairOrderInfoService.save(orderInfo);
                resultOrder = repairOrderInfoService.getById(orderInfo.getId());
            }
        } else if ("czyl".equals(active.getType())) {
            // 充值有礼
            if (null == active.getRuleList() || active.getRuleList().isEmpty()) {
                //校验是否存在充值规则
                throw exception(CUSTOMER_ACTIVE_NO_RULE);
            }
            //记录日志
            CustomerBalanceChange change = changeService.initChange(customer.getId(),
                    customer.getUserId(), null, BALANCE_CHANGE_TYPE_CZ, BALANCE_CHANGE_MAIN_YE,
                    null, saveReqVO.getTopUpAmount(), new BigDecimal(0), "参加" + active.getName() + "活动充值" + saveReqVO.getTopUpAmount() + "元");
            changeService.save(change);
            RepairOrderInfo orderInfo = new RepairOrderInfo();
            orderInfo.setOrderNo(System.currentTimeMillis() + Math.abs(change.getId().hashCode() % 1000) + "");
            orderInfo.setGoodsId(change.getId());
            orderInfo.setActiveId(active.getId());
            orderInfo.setGoodsTitle(active.getName());
            orderInfo.setTenantName(ORDER_TENANT_NAME);
            orderInfo.setGoodsType(ORDER_HYCZ);
            orderInfo.setUserId(customer.getUserId());
            orderInfo.setCusId(customer.getId());
            orderInfo.setCusName(customer.getCusName());
            orderInfo.setCusPhone(customer.getPhoneNumber());
            orderInfo.setGoodsPrice(saveReqVO.getTopUpAmount());
            orderInfo.setPayMoney(saveReqVO.getTopUpAmount());
            orderInfo.setOrderTime(LocalDateTime.now());
            orderInfo.setOrderStatus("0");
            orderInfo.setPayType(saveReqVO.getAccountType());
            repairOrderInfoService.save(orderInfo);
            resultOrder = repairOrderInfoService.getById(orderInfo.getId());
        }

        //保存用户卡券
        if (null != customerCouponList) {
            customerCouponService.saveBatch(customerCouponList);
        }
        /*4、保存参与活动信息*/
        customerActive.setActiveId(active.getId());
        customerActive.setUserId(customer.getUserId());
        customerActive.setCusId(customer.getId());
        customerActive.setActiveName(active.getName());
        customerActive.setActiveType(active.getType());
        customerActive.setRemark(active.getRemark());
        save(customerActive);

        /*5、保存变动日志*/
        //保存变动日志
        changeService.saveBatch(changeList);
        return resultOrder;
    }

    /**
     * 充值
     *
     * @param saveReqVO CustomerActiveSaveReqVO 实体
     * @return cn.iocoder.yudao.module.order.entity.RepairOrderInfo
     * @author PQZ
     * @date 16:25 2024/9/28
     **/
    @Override
    public RepairOrderInfo recharge(CustomerActiveSaveReqVO saveReqVO) {
        //当前客户信息
        CustomerMainRespVO customer = customerMainService.getCustomerById(saveReqVO.getCusId());
        //变更信息
        CustomerBalanceChange change = changeService.initChange(customer.getId(),
                customer.getUserId(), null, BALANCE_CHANGE_TYPE_CZ, BALANCE_CHANGE_MAIN_YE,
                null, saveReqVO.getTopUpAmount(), new BigDecimal(0), "充值" + saveReqVO.getTopUpAmount() + "元");

        RepairOrderInfo orderInfo = new RepairOrderInfo();
        orderInfo.setOrderNo(System.currentTimeMillis() + Math.abs(change.getId().hashCode() % 1000) + "");
        orderInfo.setGoodsId(change.getId());
        orderInfo.setActiveId(null);
        orderInfo.setGoodsTitle("用户充值");
        orderInfo.setTenantName(ORDER_TENANT_NAME);
        orderInfo.setGoodsType(ORDER_HYCZ);
        orderInfo.setUserId(customer.getUserId());
        orderInfo.setCusId(customer.getId());
        orderInfo.setCusName(customer.getCusName());
        orderInfo.setCusPhone(customer.getPhoneNumber());
        orderInfo.setGoodsPrice(saveReqVO.getTopUpAmount());
        orderInfo.setPayMoney(saveReqVO.getTopUpAmount());
        orderInfo.setOrderTime(LocalDateTime.now());
        orderInfo.setIsOnline("01");
        orderInfo.setOrderStatus("0");
        orderInfo.setPayType(saveReqVO.getAccountType());
        //保存变更日志
        changeService.save(change);
        //保存订单信息
        repairOrderInfoService.save(orderInfo);
        return repairOrderInfoService.getById(orderInfo.getId());
    }





    /**
     * 转换余额
     *
     * @param customer 用户信息
     * @param amount   实际充值金额
     * @param ruleList 规则
     * @return cn.iocoder.yudao.module.custom.entity.CustomerBalance
     * @author PQZ
     * @date 11:30 2024/9/21
     **/
    CustomerBalance transBalance(CustomerMainRespVO customer, BigDecimal amount, List<ActiveRule> ruleList) {
        CustomerBalance result = new CustomerBalance();
        result.setCusId(customer.getId());
        result.setUserId(customer.getUserId());
        List<ActiveRule> sortList = ruleList.stream().sorted(Comparator.comparing(ActiveRule::getRechAmount).reversed()).collect(Collectors.toList());
        BigDecimal nowChange = amount;
        for (ActiveRule item : sortList) {
            //如果规则匹配
            if (amount.compareTo(item.getRechAmount()) >= 0) {
                nowChange = amount.add(item.getGiveAmount());
                break;
            }
        }
        //余额
        result.setBalance(customer.getBalance().add(nowChange));
        //累计充值金额
        result.setAllBalance(customer.getBalance().add(nowChange));
        //本次变动金额
        result.setNowChange(nowChange);
        return result;
    }


    @Override
    public void deleteCustomerActive(String id) {
        // 删除
        customerActiveMapper.deleteById(id);
    }


    @Override
    public CustomerActive getCustomerActive(String id) {
        return customerActiveMapper.selectById(id);
    }

    @Override
    public PageResult<CustomerActive> getCustomerActivePage(CustomerActivePageReqVO pageReqVO) {
        return null;
    }

    /**
     * 可参与营销活动
     *
     * @param pageReqVO ActiveMainPageReqVO 实体
     * @return java.util.List<cn.iocoder.yudao.module.member.vo.ActiveMainRespVO>
     * @author PQZ
     * @date 16:18 2024/9/23
     **/
    @Override
    public List<ActiveMainRespVO> isJoinActive(ActiveMainPageReqVO pageReqVO) {
        LambdaQueryWrapper<CustomerActive> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BaseDO::getDeleted, 0).eq(CustomerActive::getCusId, pageReqVO.getCusId());
        List<CustomerActive> myList = list(lambdaQueryWrapper);
        //活动id集合
        List<String> activeIds = myList.stream().map(CustomerActive::getActiveId).distinct().collect(Collectors.toList());
        List<ActiveMainRespVO> list = activeMainService.listActive(pageReqVO);
        //排除已参与的
        list.forEach(item -> {
            if (activeIds.contains(item.getId())) {
                item.setIsJoin(GENERAL_YES);
            }
        });
        return list;
    }

}