package com.gic.haoban.manage.service.service.chat.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.BusinessException;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.content.api.enums.activity.ContentActivityStatusEnum;
import com.gic.haoban.manage.api.dto.chat.GroupChatActivityDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatActivityJoinDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatActivityRewardBaseDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatActivityRewardDTO;
import com.gic.haoban.manage.api.enums.chat.ChatActivityJoinEnum;
import com.gic.haoban.manage.api.enums.chat.ChatActivityStatusEnum;
import com.gic.haoban.manage.api.qdto.chat.GroupChatActivityHmQDTO;
import com.gic.haoban.manage.api.qdto.chat.GroupChatActivityJoinQDTO;
import com.gic.haoban.manage.api.qdto.chat.GroupChatActivityQDTO;
import com.gic.haoban.manage.api.qdto.chat.GroupChatActivitySearchQDTO;
import com.gic.haoban.manage.service.context.chat.BusinessManager;
import com.gic.haoban.manage.service.context.chat.JoinRuleManager;
import com.gic.haoban.manage.service.dao.mapper.chat.GroupChatActivityMapper;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatActivity;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatActivityJoin;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatActivityReward;
import com.gic.haoban.manage.service.pojo.bo.chat.GroupChatHmBO;
import com.gic.haoban.manage.service.service.chat.GroupChatActivityJoinService;
import com.gic.haoban.manage.service.service.chat.GroupChatActivityRewardService;
import com.gic.haoban.manage.service.service.chat.GroupChatActivityService;
import com.gic.redis.data.util.RedisUtil;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 社群邀请有礼表(TabHaobanGroupChatActivity)表服务实现类
 *
 * @author makejava
 * @since 2024-09-27 16:09:51
 */
@Service("groupChatActivityService")
public class GroupChatActivityServiceImpl implements GroupChatActivityService {

    private static final Logger logger = LogManager.getLogger(GroupChatActivityService.class);

    private static final String ACTIVITY_KEY = "haoban-manage3:group_chat:activity:";

    @Resource
    private GroupChatActivityMapper groupChatActivityMapper;
    @Autowired
    private GroupChatActivityRewardService groupChatActivityRewardService;
    @Autowired
    private GroupChatActivityJoinService groupChatActivityJoinService;
    @Autowired
    private BusinessManager businessManager;
    @Autowired
    private JoinRuleManager joinRuleManager;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveActivity(GroupChatActivityQDTO qdto) throws BusinessException {
        logger.info("保存社群活动:{}", JSON.toJSONString(qdto));
        boolean save = false;
        Long contentActivityId = qdto.getChatActivityId();
        String enterpriseId = qdto.getEnterpriseId();
        String wxEnterpriseId = qdto.getWxEnterpriseId();
        GroupChatActivityDTO activityDTO = null;
        if (contentActivityId == null) {
            save = true;
        }else {
            activityDTO = getActivityDetail(enterpriseId, contentActivityId);
        }
        //校验活动参数
        checkActivity(save, qdto,activityDTO);
        TabGroupChatActivity activity = EntityUtil.changeEntity(TabGroupChatActivity.class, qdto);
        if (contentActivityId == null) {
            activity.setChatActivityId(UniqueIdUtils.uniqueLong());
            groupChatActivityMapper.insert(activity);
        }else {
            groupChatActivityMapper.update(activity);
        }
        Map<Integer, List<GroupChatActivityRewardDTO>> rewardMap = qdto.getRewardMap();
        List<GroupChatActivityRewardBaseDTO> rewardList = GroupChatActivityRewardBaseDTO.mapConvert(rewardMap);
        List<TabGroupChatActivityReward> activityRewards = EntityUtil.changeEntityListNew(TabGroupChatActivityReward.class, rewardList);
        activityRewards.forEach(rule->{
            rule.setEnterpriseId(enterpriseId);
            rule.setWxEnterpriseId(wxEnterpriseId);
            rule.setChatActivityId(activity.getChatActivityId());
        });
        //保存活动奖励规则
        groupChatActivityRewardService.saveActivityReward(activity.getChatActivityId(),activityRewards);
        List<GroupChatActivityJoinQDTO> joinList = qdto.getJoinList();
        if (CollectionUtils.isNotEmpty(joinList)) {
            List<TabGroupChatActivityJoin> activityJoins = EntityUtil.changeEntityListNew(TabGroupChatActivityJoin.class, joinList);
            activityJoins.forEach(rule->{
                rule.setEnterpriseId(enterpriseId);
                rule.setWxEnterpriseId(wxEnterpriseId);
                rule.setChatActivityId(activity.getChatActivityId());
            });
            //保存活动入群规则
            groupChatActivityJoinService.saveActivityJoin(activity,activityJoins);
        }
        activityDTO = getActivityDetail(enterpriseId, activity.getChatActivityId());
        //处理卡券异常通知
        businessManager.dealCouponAlarmByActivity(activityDTO,false);
        return activity.getChatActivityId();
    }

    private void checkActivity(boolean save, GroupChatActivityQDTO qdto,GroupChatActivityDTO activity) throws BusinessException {
        Long chatActivityId = qdto.getChatActivityId();
        String enterpriseId = qdto.getEnterpriseId();
        qdto.setEndDate(DateUtil.endOfDay(qdto.getEndDate()));
        Date startDate = qdto.getStartDate();
        Map<Integer, List<GroupChatActivityRewardDTO>> rewardMap = qdto.getRewardMap();
        if (MapUtils.isEmpty(rewardMap)) {
            throw new BusinessException("500", "奖励规则不能为空");
        }
        List<GroupChatActivityJoinQDTO> joinList = qdto.getJoinList();
        Integer joinType = qdto.getJoinType();
        if (Objects.equals(joinType, ChatActivityJoinEnum.ORIENTED.value) && CollectionUtils.isEmpty(joinList)) {
            throw new BusinessException("500", "入群规则不能为空");
        }
        DateTime now = DateUtil.date();
        if (!save) {
            if (activity == null) {
                throw new BusinessException("500", "营销活动不存在");
            }
            Integer status = activity.getStatus();
            if (Objects.equals(ChatActivityStatusEnum.STOP.value, status)) {
                throw new BusinessException("500", "活动已终止，不支持编辑");
            }
            if (Objects.equals(ChatActivityStatusEnum.END.value, status)) {
                throw new BusinessException("500", "活动已结束，不支持编辑");
            }
            if (Objects.equals(ChatActivityStatusEnum.START.value, status)) {
                if (!Objects.equals(qdto.getStartDate(), activity.getStartDate())) {
                    throw new BusinessException("500", "活动已开始，活动开始时间不支持编辑");
                }
                if (DateUtil.compare(activity.getEndDate(), qdto.getEndDate()) > 0) {
                    throw new BusinessException("500", "活动已开始，活动结束时间不允许小于之前的时间");
                }
                String labelJson = activity.getLabelJson();
                Integer labelFlag = activity.getLabelFlag();
                if (!Objects.equals(qdto.getLabelFlag(), labelFlag) || !Objects.equals(qdto.getLabelJson(), labelJson)) {
                    throw new BusinessException("500", "活动已开始，客户标签不支持编辑");
                }
                Integer inviteMemberType = activity.getInviteMemberType();
                if (!Objects.equals(qdto.getInviteMemberType(), inviteMemberType)) {
                    throw new BusinessException("500", "活动已开始，限制入群客户不支持编辑");
                }
                Integer inviteType = activity.getInviteType();
                if (!Objects.equals(qdto.getInviteType(), inviteType)) {
                    throw new BusinessException("500", "活动已开始，有效邀请限制不支持编辑");
                }
                Integer inviteRewardType = activity.getInviteRewardType();
                if (!Objects.equals(qdto.getInviteRewardType(), inviteRewardType)) {
                    throw new BusinessException("500", "活动已开始，奖励类型不支持编辑");
                }
                Map<Integer, List<GroupChatActivityRewardDTO>> oldRewardMap = activity.getRewardMap();
                if (Objects.equals(oldRewardMap.size(), rewardMap.size())) {
                    throw new BusinessException("500", "活动已开始，奖励规则不支持编辑");
                }
                for(Map.Entry<Integer, List<GroupChatActivityRewardDTO>> entry : rewardMap.entrySet()){
                    if (!CollectionUtil.isEqualList(entry.getValue(), oldRewardMap.get(entry.getKey()))) {
                        throw new BusinessException("500", "活动已开始，奖励规则不支持编辑");
                    }
                }
                if (!Objects.equals(qdto.getJoinType(), activity.getJoinType())) {
                    throw new BusinessException("500", "活动已开始，入群方式不支持编辑");
                }
                if (!Objects.equals(qdto.getJoinRule(), activity.getJoinRule())) {
                    throw new BusinessException("500", "活动已开始，入群方式层级规则不支持编辑");
                }
                List<GroupChatActivityJoinDTO> oldJoinList = activity.getJoinList();
                if (!CollUtil.isEqualList(oldJoinList, EntityUtil.changeEntityListNew(GroupChatActivityJoinDTO.class, joinList))) {
                    throw new BusinessException("500", "活动已开始，入群规则不支持编辑");
                }


            }
        }else {
            if (DateUtil.compare(
                    DateUtil.beginOfDay(now),
                    startDate) > 0) {
                throw new BusinessException("500", "活动仅支持选择当前日期及之后的日期");
            }
        }
        Date endDate = qdto.getEndDate();
        if (DateUtil.compare(now, endDate) > 0 ||
                DateUtil.compare(startDate, endDate) > 0) {
            throw new BusinessException("500", "活动仅支持选择当前日期及之后的日期，结束时间必须晚于开始日期");
        }
        if (DateUtil.compare(now, startDate) > 0) {
            qdto.setStatus(ChatActivityStatusEnum.START.value);
        } else if (DateUtil.compare(startDate, now) >= 0) {
            qdto.setStatus(ChatActivityStatusEnum.NOT_START.value);
        }
    }

    @Override
    public GroupChatActivityDTO getActivityDetail(String enterpriseId, Long chatActivityId) {
        TabGroupChatActivity chatActivity = groupChatActivityMapper.queryById(chatActivityId);
        if (chatActivity == null) {
            return null;
        }
        GroupChatActivityDTO chatActivityDTO = EntityUtil.changeEntityNew(GroupChatActivityDTO.class, chatActivity);

        //组装奖励规则
        List<TabGroupChatActivityReward> activityRewards = groupChatActivityRewardService.listByActivityId(chatActivityId);
        List<GroupChatActivityRewardBaseDTO> rewardList = EntityUtil.changeEntityListNew(GroupChatActivityRewardBaseDTO.class, activityRewards);
        chatActivityDTO.setRewardMap(GroupChatActivityRewardBaseDTO.reverseMapConvert(rewardList));
        //组装奖励规则
        List<TabGroupChatActivityJoin> activityJoins = groupChatActivityJoinService.listByActivityId(chatActivityId);
        List<GroupChatActivityJoinDTO> joinList = EntityUtil.changeEntityListNew(GroupChatActivityJoinDTO.class, activityJoins);
        chatActivityDTO.setJoinList(joinList);
        return chatActivityDTO;
    }

    @Override
    public void delActivityDetailCache(String enterpriseId, Long chatActivityId) {
        String activityKey = ACTIVITY_KEY + chatActivityId;
        RedisUtil.delCache(activityKey);
    }

    @Override
    public GroupChatActivityDTO getActivityDetailCache(String enterpriseId, Long chatActivityId) {
        String activityKey = ACTIVITY_KEY + chatActivityId;
        GroupChatActivityDTO cache = RedisUtil.getCache(activityKey, GroupChatActivityDTO.class);
        if (cache != null) {
            return cache;
        }
        GroupChatActivityDTO activityDetail = getActivityDetail(enterpriseId, chatActivityId);
        if (activityDetail == null) {
            return null;
        }
        RedisUtil.setCache(activityKey,activityDetail,1L, TimeUnit.HOURS);
        return activityDetail;
    }

    @Override
    public List<TabGroupChatActivity> listByActivityIds(String enterpriseId, List<Long> chatActivityIdList) {
        List<TabGroupChatActivity> chatActivities = groupChatActivityMapper.queryByIds(chatActivityIdList);
        return chatActivities;
    }

    @Override
    public List<TabGroupChatActivity> listByActivityIdsDel(String enterpriseId, List<Long> chatActivityIdList) {
        List<TabGroupChatActivity> chatActivities = groupChatActivityMapper.queryByIdsDel(chatActivityIdList);
        return chatActivities;
    }

    @Override
    public Page<GroupChatActivityDTO> pageActivity(String enterpriseId, GroupChatActivitySearchQDTO searchQDTO, BasePageInfo pageInfo) {
        PageHelper.startPage(pageInfo);
        List<TabGroupChatActivity> list = groupChatActivityMapper.listActivity(enterpriseId, searchQDTO);
        Page<GroupChatActivityDTO> page = PageHelperUtils.changePageHelperToCurrentPage(list, GroupChatActivityDTO.class);
        List<GroupChatActivityDTO> result = page.getResult();
        if (CollectionUtil.isNotEmpty(result)) {
            List<Long> activityIdList = result.stream().map(GroupChatActivityDTO::getChatActivityId).collect(Collectors.toList());
            Map<Long, List<TabGroupChatActivityReward>> rewardMap = groupChatActivityRewardService.listByActivityIdList(activityIdList);
            if (MapUtils.isNotEmpty(rewardMap)) {
                result.forEach(activity->{
                    List<TabGroupChatActivityReward> activityRewards = rewardMap.get(activity.getChatActivityId());
                    if (CollectionUtils.isNotEmpty(activityRewards)) {
                        List<GroupChatActivityRewardBaseDTO> rewardList = EntityUtil.changeEntityListNew(GroupChatActivityRewardBaseDTO.class, activityRewards);
                        activity.setRewardMap(GroupChatActivityRewardBaseDTO.reverseMapConvert(rewardList));
                    }
                });
            }
        }
        return page;
    }

    @Override
    public GroupChatActivityDTO stopActivity(String enterpriseId, Long chatActivityId) throws BusinessException {
        GroupChatActivityDTO detail = getActivityDetail(enterpriseId, chatActivityId);
        if (detail == null) {
            return null;
        }
        Integer status = detail.getStatus();
        if (Objects.equals(status, ChatActivityStatusEnum.STOP.value) ||
                Objects.equals(status, ChatActivityStatusEnum.END.value)) {
            throw new BusinessException("500", "已终止或已结束的活动无法终止");
        }
        TabGroupChatActivity chatActivity = new TabGroupChatActivity();
        chatActivity.setChatActivityId(chatActivityId);
        chatActivity.setStatus(ChatActivityStatusEnum.STOP.value);
        chatActivity.setLimitDate(DateUtil.date());
        groupChatActivityMapper.update(chatActivity);
        detail.setStatus(ChatActivityStatusEnum.STOP.value);
        //处理会员分组
        businessManager.dealMemberTagByActivity(EntityUtil.changeEntityNew(TabGroupChatActivity.class,detail),null,true);
        //处理卡券异常通知
        businessManager.dealCouponAlarmByActivity(detail,true);
        return detail;
    }

    @Override
    public void delActivity(String enterpriseId, Long chatActivityId) throws BusinessException {
        int update = groupChatActivityMapper.deleteById(enterpriseId, chatActivityId);
        if (update <= 0) {
            throw new BusinessException("500","活动已删除");
        }
    }

    @Override
    public void updateStatusActivity(String enterpriseId, Long chatActivityId, Integer status) {
        TabGroupChatActivity chatActivity = new TabGroupChatActivity();
        chatActivity.setChatActivityId(chatActivityId);
        chatActivity.setStatus(status);
        groupChatActivityMapper.update(chatActivity);
        delActivityDetailCache(enterpriseId, chatActivityId);
    }

    @Override
    public List<TabGroupChatActivity> listEffectiveActivity(String enterpriseId) {
        GroupChatActivitySearchQDTO searchQDTO = new GroupChatActivitySearchQDTO();
        searchQDTO.setStatus(ChatActivityStatusEnum.START.value);
        List<TabGroupChatActivity> list = groupChatActivityMapper.listActivity(enterpriseId, searchQDTO);
        return list;
    }

    @Override
    public void activityQuartzUpdateStatus() {
        Date now = DateUtil.date();
        logger.info("处理活动状态:{}",now);
        TabGroupChatActivity startSearchQDTO = new TabGroupChatActivity();
        startSearchQDTO.setStatus(ChatActivityStatusEnum.NOT_START.value);
        startSearchQDTO.setStartDate(now);
        List<TabGroupChatActivity> startList = groupChatActivityMapper.listActivityByDate(startSearchQDTO);
        if (CollectionUtils.isNotEmpty(startList)) {
            for (TabGroupChatActivity activity : startList) {
                try {
                    updateStatusActivity(activity.getEnterpriseId(),activity.getChatActivityId(),ContentActivityStatusEnum.START.value);
                } catch (Exception e) {
                    logger.info("处理活动状态异常",e);
                }
            }
        }
        TabGroupChatActivity endSearchQDTO = new TabGroupChatActivity();
        endSearchQDTO.setStatus(ChatActivityStatusEnum.START.value);
        endSearchQDTO.setEndDate(now);
        List<TabGroupChatActivity> endList = groupChatActivityMapper.listActivityByDate(endSearchQDTO);
        if (CollectionUtils.isNotEmpty(endList)) {
            for (TabGroupChatActivity activity : endList) {
                try {
                    updateStatusActivity(activity.getEnterpriseId(),activity.getChatActivityId(),ContentActivityStatusEnum.END.value);
                    //处理会员分组
                    businessManager.dealMemberTagByActivity(activity,null,true);
                    GroupChatActivityDTO activityDTO = EntityUtil.changeEntityNew(GroupChatActivityDTO.class, activity);
                    //处理卡券异常通知
                    businessManager.dealCouponAlarmByActivity(activityDTO,true);
                } catch (Exception e) {
                    logger.info("处理活动状态异常",e);
                }
            }
        }
    }

    @Override
    public List<GroupChatHmBO> listGroupChatHm(GroupChatActivityHmQDTO activityHmQDTO) throws BusinessException{
        Long chatActivityId = activityHmQDTO.getChatActivityId();
        String enterpriseId = activityHmQDTO.getEnterpriseId();
        GroupChatActivityDTO chatActivity = getActivityDetailCache(enterpriseId,chatActivityId);
        if (chatActivity == null) {
            return Collections.emptyList();
        }
        activityHmQDTO.setChatActivity(chatActivity);
        return joinRuleManager.listGroupHm(activityHmQDTO);
    }
}
