package com.jsowell.pile.service.impl;

import com.google.common.collect.Lists;
import com.jsowell.common.enums.DelFlagEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.SecurityUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.id.IdUtils;
import com.jsowell.pile.domain.MemberBasicInfo;
import com.jsowell.pile.domain.MemberGroup;
import com.jsowell.pile.domain.MemberGroupRelation;
import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.dto.MemberGroupDTO;
import com.jsowell.pile.dto.QueryOrderDTO;
import com.jsowell.pile.mapper.MemberGroupMapper;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.MemberGroupConsumptionVO;
import com.jsowell.pile.vo.base.MemberGroupStationVO;
import com.jsowell.pile.vo.uniapp.customer.MemberVO;
import com.jsowell.pile.vo.web.BillingTemplateVO;
import com.jsowell.pile.vo.web.MemberDiscountVO;
import com.jsowell.pile.vo.web.MemberGroupVO;
import com.jsowell.pile.vo.web.OrderListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员组Service业务层处理
 *
 * @author jsowell
 * @date 2023-12-26
 */
@Slf4j
@Service
public class MemberGroupServiceImpl implements MemberGroupService {
    @Autowired
    private MemberGroupMapper memberGroupMapper;

    @Autowired
    private MemberGroupRelationService memberGroupRelationService;

    @Autowired
    private MemberBasicInfoService memberBasicInfoService;

    @Autowired
    private PileMerchantInfoService pileMerchantInfoService;

    @Autowired
    private PileBillingTemplateService pileBillingTemplateService;

    @Autowired
    private OrderBasicInfoService orderBasicInfoService;

    /**
     * 查询会员组
     *
     * @param id 会员组主键
     * @return 会员组
     */
    @Override
    public MemberGroup selectMemberGroupById(Long id) {
        MemberGroup memberGroup = memberGroupMapper.selectMemberGroupById(id);
        if (memberGroup != null) {
            BigDecimal discount = memberGroup.getDiscount();
            // 返回给前端乘以10
            memberGroup.setDiscount(discount.multiply(BigDecimal.TEN));
        }
        return memberGroup;
    }

    /**
     * 查询会员组列表
     */
    @Override
    public List<MemberGroupVO> selectMemberGroupList(MemberGroupDTO dto) {
        List<MemberGroupVO> resultList = memberGroupMapper.queryMemberGroupList(dto);
        if (CollectionUtils.isEmpty(resultList)) {
            return Lists.newArrayList();
        }
        return resultList;
    }

    /**
     * 新增会员组
     *
     * @param memberGroup 会员组
     * @return 结果
     */
    @Override
    public int insertMemberGroup(MemberGroup memberGroup) {
        String merchantId = memberGroup.getMerchantId();
        MemberGroupVO memberGroupVO = queryByMerchantId(merchantId);
        if (memberGroupVO != null) {
            throw new BusinessException("", "该运营商已经创建过集团");
        }
        // 生成编号
        memberGroup.setGroupCode(generateGroupCode());
        memberGroup.setCreateTime(DateUtils.getNowDate());
        memberGroup.setDelFlag(DelFlagEnum.NORMAL.getValue());
        try {
            String createBy = SecurityUtils.getLoginUser().getUsername();
            memberGroup.setCreateBy(createBy);
        } catch (Exception e) {

        }
        return memberGroupMapper.insertMemberGroup(memberGroup);
    }

    private boolean isBetween(BigDecimal price) {
        BigDecimal start = BigDecimal.ZERO;
        BigDecimal end = BigDecimal.TEN;
        return isBetween(price, start, end);
    }

    private boolean isBetween(BigDecimal source, BigDecimal start, BigDecimal end) {
        return source.compareTo(start) > 0 && source.compareTo(end) < 0;
    }

    // 生成编号
    private String generateGroupCode() {
        while (true) {
            String groupCode = IdUtils.get16UUID("32");
            // 通过walletCode查询是否已经存在
            MemberGroup memberGroup = selectByGroupCode(groupCode);
            if (memberGroup == null) {
                return groupCode;
            }
        }
    }

    /**
     * 根据会员组编号查询
     *
     * @param groupCode
     * @return
     */
    public MemberGroup selectByGroupCode(String groupCode) {
        return memberGroupMapper.selectByGroupCode(groupCode);
    }

    /**
     * 修改会员组
     *
     * @param memberGroup 会员组
     * @return 结果
     */
    @Override
    public int updateMemberGroup(MemberGroup memberGroup) {
        memberGroup.setUpdateTime(DateUtils.getNowDate());
        return memberGroupMapper.updateMemberGroup(memberGroup);
    }

    /**
     * 批量删除会员组
     *
     * @param ids 需要删除的会员组主键
     * @return 结果
     */
    @Override
    public int deleteMemberGroupByIds(Long[] ids) {
        return memberGroupMapper.deleteMemberGroupByIds(ids);
    }

    /**
     * 删除会员组信息
     *
     * @param id 会员组主键
     * @return 结果
     */
    @Override
    public int deleteMemberGroupById(Long id) {
        return memberGroupMapper.deleteMemberGroupById(id);
    }

    /**
     * 查询会员折扣
     */
    @Override
    public MemberDiscountVO queryMemberDiscount(String merchantId, String stationId, String memberId) {
        MemberDiscountVO MemberDiscountVO = memberGroupMapper.queryMemberDiscount(merchantId, stationId, memberId);
        return MemberDiscountVO;
    }

    public MemberDiscountVO queryMemberDiscountV2(String merchantId, String stationId, String memberId) {
        String groupCode = memberGroupMapper.queryMemberGroupCode(merchantId, stationId, memberId);
        if (StringUtils.isBlank(groupCode)) {
            return null;
        }
        // 查询站点的集团会员计费模板
        BillingTemplateVO billingTemplate = pileBillingTemplateService.queryPreferentialBillingTemplate(stationId);
        if (billingTemplate == null) {
            return null;
        }
        MemberDiscountVO memberDiscountVOBuilder = MemberDiscountVO.builder()
                .merchantId(merchantId)
                .stationId(stationId)
                .groupCode(groupCode)
                .billingTemplateVO(billingTemplate)
                .build();
        return memberDiscountVOBuilder;
    }

    /**
     * 后管保存集团会员关系
     * @param dto
     * @return
     */
    @Override
    public int addMember(MemberGroupDTO dto) {
        String groupCode = dto.getGroupCode();
        if (StringUtils.isBlank(groupCode)) {
            return 0;
        }
        // 校验会员组是否存在
        MemberGroup memberGroup = selectByGroupCode(groupCode);
        if (memberGroup == null) {
            return 0;
        }
        // 查询会员id
        String firstLevelMerchantId = pileMerchantInfoService.getFirstLevelMerchantIdByMerchantId(memberGroup.getMerchantId());
        MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMobileNumber(dto.getPhoneNumber(), firstLevelMerchantId);
        if (memberBasicInfo == null) {
            return 0;
        }
        // 校验通过，关系存入数据库
        return saveMemberGroupRelation(memberBasicInfo.getMemberId(), groupCode);
    }

    /**
     * 订单保存集团会员关系
     * @param memberId 会员id
     * @param merchantId 运营商id
     * @return
     */
    @Override
    public int addMember2MemberGroup(String memberId, String merchantId) {
        log.info("添加会员id:{}, 到运营商:{}的集团中", memberId, merchantId);
        // 查询该站点有没有集团信息
        MemberGroupVO memberGroupVO = queryByMerchantId(merchantId);
        if (memberGroupVO == null) {
            return 0;
        }
        // 检查memberId是否在集团中
        MemberGroupVO groupVO = memberGroupMapper.queryByGroupCodeAndMemberId(memberGroupVO.getGroupCode(), memberId);
        if (groupVO == null) {
            // 校验通过，关系存入数据库 加入到集团
            return saveMemberGroupRelation(memberId, memberGroupVO.getGroupCode());
        }
        return 0;
    }

    @Override
    public List<MemberGroupStationVO> queryStationList(MemberGroupDTO dto) {
        return memberGroupMapper.queryStationList(dto);
    }

    @Override
    public int removeStationFromMemberGroup(MemberGroupDTO dto) {
        int result = 0;
        String stationId = dto.getStationId();
        String groupCode = dto.getGroupCode();
        if (StringUtils.isBlank(stationId) || StringUtils.isBlank(groupCode)) {
            return result;
        }
        MemberGroup memberGroup = memberGroupMapper.selectByGroupCode(groupCode);
        if (Objects.isNull(memberGroup)) {
            return result;
        }
        List<String> stationIds = Lists.newArrayList(StringUtils.split(memberGroup.getStationId(), ","));
        if (CollectionUtils.isNotEmpty(stationIds)) {
            stationIds.remove(stationId);
            memberGroup.setStationId(StringUtils.join(stationIds, ","));
            result = memberGroupMapper.updateMemberGroup(memberGroup);
        }

        // 删除该站点的会员优惠计费模板
        int i = pileBillingTemplateService.deletePreferentialBillingTemplate(stationId);
        if (i > 0) {
            result = result + i;
        }
        return result;
    }

    @Override
    public int removeMemberFromMemberGroup(MemberGroupDTO dto) {
        return memberGroupRelationService.deleteRelationByGroupCodeAndMemberId(dto.getGroupCode(), dto.getMemberId());
    }

    @Override
    public List<MemberGroupConsumptionVO> queryMemberGroupConsumptionList(String groupCode) {
        List<MemberGroupConsumptionVO> resultList = Lists.newArrayList();
        List<OrderBasicInfo> orderList = orderBasicInfoService.queryOrderListByGroupCode(groupCode);
        if (CollectionUtils.isEmpty(orderList)) {
            return resultList;
        }
        // key:会员id，value:订单列表
        Map<String, List<OrderBasicInfo>> listMap = orderList.stream().collect(Collectors.groupingBy(OrderBasicInfo::getMemberId));
        MemberGroupConsumptionVO vo = null;
        for (Map.Entry<String, List<OrderBasicInfo>> entry : listMap.entrySet()) {
            if (CollectionUtils.isEmpty(entry.getValue())) {
                continue;
            }
            // 订单根据结算时间倒序，结算时间为null的排在最后(null在前，结算日期正序，之后整个list反转)
            List<OrderBasicInfo> orderBasicInfoList = entry.getValue().stream()
                    .sorted(Comparator.comparing(OrderBasicInfo::getSettlementTime, Comparator.nullsLast(Comparator.reverseOrder())))
                    .collect(Collectors.toList());
            vo = new MemberGroupConsumptionVO();

            String vinCode = null;
            String licensePlateNumber = null;
            BigDecimal totalConsumptionAmount = BigDecimal.ZERO;
            Date date = DateUtils.getNowDate();
            for (int i = 0; i < orderBasicInfoList.size(); i++) {
                OrderBasicInfo orderBasicInfo = orderBasicInfoList.get(i);
                if (i == 0) {
                    vinCode = orderBasicInfo.getVinCode();
                    licensePlateNumber = orderBasicInfo.getPlateNumber();
                    date = orderBasicInfo.getSettlementTime();
                }

                // 订单消费金额
                BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
                // 优惠金额
                BigDecimal discountAmount = orderBasicInfo.getDiscountAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getDiscountAmount();
                // 汇总消费金额
                totalConsumptionAmount = totalConsumptionAmount.add(orderAmount.subtract(discountAmount));
            }

            vo.setMemberId(entry.getKey());
            vo.setVinCode(vinCode);
            vo.setLicensePlateNumber(licensePlateNumber);
            vo.setTotalConsumptionAmount(totalConsumptionAmount.toString());
            vo.setLastDate(DateUtils.formatDateTime(date));
        }
        return resultList;
    }

    @Override
    public List<OrderListVO> queryConsumptionDetailListByVinCode(String groupCode, String vinCode) {
        QueryOrderDTO dto = new QueryOrderDTO();
        dto.setGroupCode(groupCode);
        dto.setVinCode(vinCode);
        List<OrderListVO> orderListVOS = orderBasicInfoService.selectOrderBasicInfoList(dto);
        return orderListVOS;
    }

    /**
     * 会员与集团的关系保存到数据库
     * @param memberId 会员id
     * @param groupCode 集团编号
     * @return
     */
    private int saveMemberGroupRelation(String memberId, String groupCode) {
        if (StringUtils.isBlank(memberId) || StringUtils.isBlank(groupCode)) {
            return 0;
        }
        // 校验通过，关系存入数据库 加入到集团
        MemberGroupRelation relation = new MemberGroupRelation();
        relation.setMemberId(memberId);
        relation.setGroupCode(groupCode);
        relation.setCreateTime(DateUtils.getNowDate());
        relation.setDelFlag(DelFlagEnum.NORMAL.getValue());
        return memberGroupRelationService.batchInsert(Lists.newArrayList(relation));
    }

    @Override
    public List<MemberVO> queryMemberList(MemberGroupDTO dto) {
        List<MemberVO> list = memberGroupMapper.queryMemberList(dto.getGroupCode());
        return list;
    }

    /**
     * 根据运营商id查询会员组
     * @param merchantId 运营商id
     * @return 会员组VO
     */
    @Override
    public MemberGroupVO queryByMerchantId(String merchantId) {
        return memberGroupMapper.queryByMerchantId(merchantId);
    }

    @Override
    public MemberGroupVO queryByGroupCode(String groupCode) {
        MemberGroupVO result = null;
        MemberGroup memberGroup = memberGroupMapper.selectByGroupCode(groupCode);
        if (memberGroup != null) {
            result = new MemberGroupVO();
            BeanUtils.copyProperties(memberGroup, result);
        }
        return result;
    }

    /**
     * 根据站点id查询会员组
     * @param stationId 站点id
     * @return 会员组VO
     */
    @Override
    public MemberGroupVO queryByStationId(String stationId) {
        return memberGroupMapper.queryByStationId(stationId);
    }

}
