package com.ruoyi.model.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyl.h5.pojo.vo.H5OrderVO;
import com.cyl.h5.service.H5MemberService;
import com.cyl.manager.oms.domain.OmsOrderService;
import com.cyl.manager.oms.domain.Order;
import com.cyl.manager.oms.domain.OrderItem;
import com.cyl.manager.oms.mapper.OmsOrderServiceMapper;
import com.cyl.manager.oms.mapper.OrderItemMapper;
import com.cyl.manager.oms.mapper.OrderMapper;
import com.cyl.manager.oms.service.OmsOrderServiceService;
import com.cyl.manager.ums.domain.Member;
import com.cyl.manager.ums.domain.Pet;
import com.cyl.manager.ums.mapper.MemberMapper;
import com.cyl.manager.ums.mapper.PetMapper;
import com.cyl.manager.ums.service.MemberService;
import com.cyl.manager.ums.service.PetService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.model.domain.*;
import com.ruoyi.model.mapper.AppletOrderItemMapper;
import com.ruoyi.model.service.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.model.mapper.AppletOrderDateFrequencyMapper;
import org.springframework.transaction.annotation.Transactional;

import static org.apache.ibatis.ognl.OgnlOps.in;

/**
 * 日订单Service业务层处理
 *
 * @author daixiande
 */
@Service
@Log4j2
public class AppletOrderDateFrequencyServiceImpl extends ServiceImpl<AppletOrderDateFrequencyMapper, AppletOrderDateFrequency> implements IAppletOrderDateFrequencyService {

    @Autowired
    private AppletOrderDateFrequencyMapper appletOrderDateFrequencyMapper;

    @Autowired
    private PetMapper petMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OmsOrderServiceMapper omsOrderServiceMapper;

    @Autowired
    private IAppUsersService appUsersService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private IAppletOrderItemDateLogService appletOrderItemDateLogService;

    @Autowired
    private AppletOrderItemMapper appletOrderItemMapper;

    @Autowired
    private IAppletAmountLogService appletAmountLogService;

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private IAppletConfigService appletConfigService;

    /**
     * 查询日订单
     *
     * @param id 日订单主键
     * @return 日订单
     */
    @Override
    public AppletOrderDateFrequency selectAppletOrderDateFrequencyById(Long id) {
        AppletOrderDateFrequency appletOrderDateFrequency = appletOrderDateFrequencyMapper.selectById(id);
        buildPetData(appletOrderDateFrequency);
        return appletOrderDateFrequency;
    }

    /**
     * 查询日订单列表
     *
     * @param frequency 日订单
     * @return 日订单
     */
    @Override
    public List<AppletOrderDateFrequency> selectAppletOrderDateFrequencyList(AppletOrderDateFrequency frequency) {

        LambdaQueryChainWrapper<AppletOrderDateFrequency> qw = lambdaQuery()
                .eq(frequency.getOrderId() != null, AppletOrderDateFrequency::getOrderId, frequency.getOrderId())
                .eq(frequency.getMasterId() != null, AppletOrderDateFrequency::getMasterId, frequency.getMasterId())//伴宠师
                .eq(frequency.getUserId() != null, AppletOrderDateFrequency::getUserId, frequency.getUserId())//下单用户
                .eq(frequency.getServiceDate() != null, AppletOrderDateFrequency::getServiceDate, frequency.getServiceDate())//下单用户

                // 当前条件默认asc，传desc则desc
                .orderBy(true, !"desc".equals(frequency.getOrderByDate()), AppletOrderDateFrequency::getServiceDate);

        if (frequency.getStatus() != null){
            qw.in(AppletOrderDateFrequency::getStatus,
                    Arrays.asList(frequency.getStatus().split(",")));
        }

        List<AppletOrderDateFrequency> list = qw.list();

        list.forEach(this::buildPetData);

        return list;
    }

    @Override
    public void buildPetData(AppletOrderDateFrequency frequency){

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");


        String[] split = frequency.getPetId().split(",");

        List<Pet> pets = petMapper.selectList(Wrappers.<Pet>lambdaQuery()
                .in(Pet::getId, split));

        frequency.setPets(pets);

        if(frequency.getProjectIds() == null){
            return;
        }

        pets.forEach(pet -> {

            LambdaQueryWrapper<OmsOrderService> omsOrderServiceQW = Wrappers.<OmsOrderService>lambdaQuery()
                    .eq(OmsOrderService::getPetId, pet.getId())
                    .eq(OmsOrderService::getOrderId, frequency.getOrderId())
                    .eq(OmsOrderService::getServiceDate, formatter.format(frequency.getServiceDate()))
                    .select(OmsOrderService::getId);

            List<Long> omsOrderServiceIds = omsOrderServiceMapper.selectList(omsOrderServiceQW).stream().map(n -> n.getId())
                    .collect(Collectors.toList());

            LambdaQueryWrapper<OrderItem> qw = Wrappers.<OrderItem>lambdaQuery()
                    .in(OrderItem::getOrderServiceId, omsOrderServiceIds)
                    .in(OrderItem::getId, Arrays.asList(frequency.getProjectIds().split(",")));

            List<OrderItem> orderItemList = orderItemMapper.selectList(qw);

            pet.setOrderItemList(orderItemList);

        });
    }

    /**
     * 新增日订单
     *
     * @param appletOrderDateFrequency 日订单
     * @return 结果
     */
    @Override
    public int insertAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency) {
        return appletOrderDateFrequencyMapper.insert(appletOrderDateFrequency);
    }

    /**
     * 修改日订单
     *
     * @param appletOrderDateFrequency 日订单
     * @return 结果
     */
    @Override
    public int updateAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency) {
        return appletOrderDateFrequencyMapper.updateById(appletOrderDateFrequency);
    }

    /**
     * 批量删除日订单
     *
     * @param ids 需要删除的日订单主键
     * @return 结果
     */
    @Override
    public int deleteAppletOrderDateFrequencyByIds(Long[] ids) {
        return appletOrderDateFrequencyMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除日订单信息
     *
     * @param id 日订单主键
     * @return 结果
     */
    @Override
    public int deleteAppletOrderDateFrequencyById(Long id) {
        return appletOrderDateFrequencyMapper.deleteById(id);
    }
    /**
     * 接单生成日订单
     * 以下是新的日订单代码
     * @param masterId 伴宠师ID
     */
    @Override
    public void aceptOrdersGenerateDayOrdersByOrderVO(H5OrderVO h5OrderVO, Long masterId) {
        //生成按照次数完成打卡的日订单
        ArrayList<AppletOrderDateFrequency> frequencies = new ArrayList<>();

        //提取去重的日期列表。避免重复添加
        List<OmsOrderService> orderServiceSet = h5OrderVO.getOrderServiceList().stream()
                .filter(service -> service.getServiceDate() != null)
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(OmsOrderService::getServiceDate))),
                        ArrayList::new));

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");


        for (OmsOrderService service : orderServiceSet) {

            // 当前订单生成数
            int index = 0;
            // 订单最大生成数
            int maxIndex = 3;


            //找出符合当前日期时间的服务列表
            List<OmsOrderService> serviceList = h5OrderVO.getOrderServiceList().stream().
                    filter(n -> n.getServiceDate().equals(service.getServiceDate()))
                    .map(n -> {
                        n.setOrderItems(new ArrayList<>());
                        return n;
                    })
                    .collect(Collectors.toList());


            //取出当前日期所对应的项目
//            List<OrderItem> orderItemList = h5OrderVO.getOrderItemList().stream().
//                    filter(n -> {
//                        for (OmsOrderService omsOrderService : serviceList) {
//                            if(n.getOrderServiceId().equals(omsOrderService.getId())){
//                                omsOrderService.getOrderItems().add(n);
//                                return true;
//                            }
//                        }
//                        return false;
//                    }).collect(Collectors.toList());


            for (OmsOrderService omsOrderService : serviceList) {
                //给服务日期配上对应的项目
                for (OrderItem n : h5OrderVO.getOrderItemList()) {
                    if(n.getOrderServiceId().equals(omsOrderService.getId())){
                        omsOrderService.getOrderItems().add(n);
                    }
                }
                if (ObjectUtils.isNotEmpty(omsOrderService.getServiceFrequency())){
                    maxIndex = Integer.valueOf(omsOrderService.getServiceFrequency());
                }
            }


            // 根据次数生成
            while (index < maxIndex){

                //当前次数对应的项目
                HashSet<Long> projectIds = new HashSet<>();

                //当前次数对应的宠物
                HashSet<Integer> petIds = new HashSet<>();

                for (OmsOrderService omsOrderService : serviceList) {
                    //找出最大次数，最大次数符合的才能添加宠物
                    int oIndex = 0;
                    for (OrderItem orderItem : omsOrderService.getOrderItems()) {

                        oIndex = Math.max(oIndex, orderItem.getQuantity());

                        //找出符合次数的项目
                        if (orderItem.getQuantity() > index){
                            projectIds.add(orderItem.getId());
                        }
                    }

                    //最大次数符合当前次数内，添加宠物id
                    if (oIndex > index){
                        petIds.add(omsOrderService.getPetId());
                    }
                }

                //如果当前次数没有需要服务的宠物了，则直接跳过
                if (petIds.isEmpty()){
                    break;
                }

                Date serviceDate;

                try {
                    serviceDate = formatter.parse(service.getServiceDate());
                } catch (ParseException e) {
                    throw new RuntimeException("日期解析失败");
                }

                frequencies.add(AppletOrderDateFrequency.builder()
                        .serviceDate(serviceDate)
                        .receiverCity(h5OrderVO.getReceiverCity())
                        .receiverProvince(h5OrderVO.getReceiverProvince())
                        .receiverDistrict(h5OrderVO.getReceiverDistrict())
                        .receiverDetailAddress(h5OrderVO.getReceiverDetailAddress())
                        .userId(h5OrderVO.getMemberId())
                        .masterId(masterId)
                        .orderId(service.getOrderId())
                        .dayNumber(index + 1)
                        .petId(String.join(",", petIds.stream()
                                .map(String::valueOf).collect(Collectors.toList())))
                        .projectIds(String.join(",", projectIds.stream()
                                .map(String::valueOf).collect(Collectors.toList())))
                        .build());

                index++;
            }

        }

        if (frequencies.size() == 0){
            throw new ServiceException("生成日订单失败");
        }

        saveBatch(frequencies);
    }

    @Override
    public void buildUserData(AppletOrderDateFrequency frequency) {
        frequency.setMaster(appUsersService.selectAppUsersByUserId(frequency.getMasterId()));
        frequency.setUser(memberService.selectById(frequency.getUserId()));
    }

    @Override
    @Transactional
    public int check(AppletOrderItemDateLog dateLog) {

        AppletOrderDateFrequency byId = getById(dateLog.getItemDateId());

        if(byId == null){
            throw new RuntimeException("无效日订单");
        }

        byId.setStatus(String.valueOf(dateLog.getSubmitFlag()));

        if(dateLog.getSubmitFlag() == 2){
            byId.setCompletionTime(new Date());
        }

        updateById(byId);

        dateLog.setOrderId(byId.getOrderId());

        //当所有的日订单完成，就将订单状态修改完成
        Integer count = lambdaQuery()
                .eq(AppletOrderDateFrequency::getOrderId, byId.getOrderId())
                .in(AppletOrderDateFrequency::getStatus, Arrays.asList("0,1".split(",")))
                .count();

        //总订单 的复制体 个人订单的信息
        AppletOrderItem appletOrderItem = appletOrderItemMapper
                .selectAppletOrderItemByOrderIdUserId(byId.getOrderId(), byId.getMasterId());


        //下单端小程序的订单
        Order omsOrder = orderMapper.selectById(byId.getOrderId());

        if(omsOrder != null){
            //下单端订单
            omsOrder.setStatus(
                    count == 0 ?
                    Constants.H5OrderStatus.COMPLETED
                    : Constants.H5OrderStatus.SERVICE);
            orderMapper.updateById(omsOrder);
        }

        //订单完成
        if(count == 0){
            appletOrderItem.setOrderStatus(2);
            appletOrderItemMapper.updateAppletOrderItem(appletOrderItem);

            //根据订单中的用户id查询用户信息
            AppUsers user = appUsersService.selectAppUsersByUserId(appletOrderItem.getUserId());
            //增加伴宠师流水

            // 记录日志
            AppletAmountLog moneyLog = new AppletAmountLog();
            moneyLog.setUserId(user.getUserId());
            moneyLog.setTitle("伴宠师佣金");
            moneyLog.setAmount(appletOrderItem.getOrderGivePrice());
            moneyLog.setType(0); //收入
            moneyLog.setState(1); //到账
            moneyLog.setCreateTime(LocalDateTime.now());
            moneyLog.setMoneyType(1);//钱包类型
            int i = appletAmountLogService.insertAppletAmountLog(moneyLog);
            user.setPrice(user.getPrice().add(appletOrderItem.getOrderGivePrice()));
            appUsersService.updateAppUsers(user);


            //分成给合伙人
            if (omsOrder != null){
                Member member = memberMapper.selectById(omsOrder.getMemberId());

                if (member != null && StringUtils.isNotEmpty(member.getInviteCode())){
                    AppUsers users = appUsersService.lambdaQuery()
                            .eq(AppUsers::getInvitationCode, member.getInviteCode())
                            .one();

                    //平台预计收益比例
                    AppletConfig estimated_platform_revenue = appletConfigService.getByCode("estimated_platform_revenue");

                    //合伙人等级
                    AppletConfig petPaymentHh = appletConfigService.selectAppletConfigByClassAndNum("pet_payment_hh", users.getUserHhRole());

                    if (petPaymentHh != null && estimated_platform_revenue != null){
                        BigDecimal multiply = omsOrder.getPayAmount().multiply(new BigDecimal(estimated_platform_revenue.getParamValueText()))
                                .multiply(petPaymentHh.getParamValueNo());

                        log.info("合伙人分销 合伙人等级：{} 平台预计收益比例：{} 分销金额：{}", petPaymentHh, estimated_platform_revenue.getParamValueText(), multiply);

                        AppletAmountLog multiplyLog = new AppletAmountLog();
                        multiplyLog.setUserId(users.getUserId());
                        multiplyLog.setTitle("合伙人佣金");
                        multiplyLog.setAmount(multiply);
                        multiplyLog.setType(0); //收入
                        multiplyLog.setState(1); //到账
                        multiplyLog.setCreateTime(LocalDateTime.now());
                        multiplyLog.setMoneyType(0);//钱包类型
                        multiplyLog.setFormId(member.getId());//来源用户
                        multiplyLog.setOrderId(omsOrder.getId());//来源订单
                        appletAmountLogService.insertAppletAmountLog(multiplyLog);

                        users.setMoney(users.getMoney().add(multiply));
                        appUsersService.updateById(users);

                    }

                }
            }


        }else if (appletOrderItem.getOrderStatus() == 0){//修改成订单进行中
            appletOrderItem.setOrderStatus(1);
            appletOrderItemMapper.updateAppletOrderItem(appletOrderItem);

        }


        if(dateLog.getId() == null){
            return appletOrderItemDateLogService.insertAppletOrderItemDateLog(dateLog);
        }else {
            return appletOrderItemDateLogService.updateAppletOrderItemDateLog(dateLog);
        }
    }
}
