package com.ruoyi.cai.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.cache.DynamicTotalCache;
import com.ruoyi.cai.domain.Dynamic;
import com.ruoyi.cai.domain.DynamicImages;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.dto.admin.vo.DynamicAdminVo;
import com.ruoyi.cai.dto.app.query.DynamicAddReq;
import com.ruoyi.cai.dto.app.query.DynamicQuery;
import com.ruoyi.cai.dto.app.vo.DynamicImageVo;
import com.ruoyi.cai.dto.app.vo.DynamicListVo;
import com.ruoyi.cai.dto.app.vo.DynamicVo;
import com.ruoyi.cai.enums.AuditStatusEnum;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.InnerUserFilter;
import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.mapper.DynamicMapper;
import com.ruoyi.cai.notice.YunxinHttpService;
import com.ruoyi.cai.service.CitysService;
import com.ruoyi.cai.service.DynamicImagesService;
import com.ruoyi.cai.service.DynamicService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.cai.util.CaiFileUtils;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.BeanConvertUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 主播动态Service业务层处理
 *
 * @author 77
 * @date 2023-12-23
 */
@RequiredArgsConstructor
@Service
public class DynamicServiceImpl extends ServiceImpl<DynamicMapper, Dynamic> implements DynamicService {

    @Autowired
    private DynamicImagesService dynamicImagesService;
    @Autowired
    private DynamicTotalCache dynamicTotalCache;
    @Autowired
    private UserService userService;
    @Autowired
    private SystemConfigManager systemConfigManager;
    @Autowired
    private CitysService citysService;
    @Autowired
    private InnerUserFilter innerUserFilter;
    @Autowired
    private YunxinHttpService yunxinHttpService;

    @Override
    public void unTop(Long id){
        this.update(Wrappers.lambdaUpdate(Dynamic.class)
                .eq(Dynamic::getId,id)
                .set(Dynamic::getSort, null));
    }

    @Override
    public void top(Long id){
        this.update(Wrappers.lambdaUpdate(Dynamic.class)
                .eq(Dynamic::getId,id)
                .set(Dynamic::getSort, 1));
    }

    @Override
    public List<String> selectDynamicImageList(Long userId, Integer limit) {
        return baseMapper.selectDynamicImageList(userId,limit);
    }

    @Override
    public Page<DynamicListVo> pageApp(PageQuery pageQuery, DynamicQuery query) {
        // 1=最新（默认） 2=关注 3=同城
        Page<DynamicListVo> page = baseMapper.pageApp(pageQuery.build(),query);
        List<DynamicListVo> records = page.getRecords();
        List<Long> dynamicIds = records.stream().filter(i -> i.getIsAttach() == 1).map(DynamicVo::getId).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(dynamicIds)){
            List<DynamicImages> dynamicImages = dynamicImagesService.list(Wrappers.lambdaQuery(DynamicImages.class)
                    .in(DynamicImages::getDynamicId, dynamicIds));
            Map<Long, List<DynamicImages>> map =
                    dynamicImages.stream().collect(Collectors.groupingBy(DynamicImages::getDynamicId));
            for (DynamicVo re : records) {
                List<DynamicImages> images = map.get(re.getId());
                re.setImageList(BeanConvertUtil.convertListTo(images, DynamicImageVo::new));
            }
        }
        return page;
    }

    @Override
    public void saveDynamic(DynamicAddReq res) {
        if(StringUtils.isEmpty(res.getContent()) || CollectionUtils.isEmpty(res.getImageList())){
            throw new ServiceException("动态内容和图片必须上传");
        }
        if(res.getImageList() != null && res.getImageList().size() > 9){
            throw new ServiceException("最多只能发送9张照片哦");
        }
        User user = userService.getById(res.getUserId());
        if(user.getSendDynamic() == 0){
            throw new ServiceException("您已被禁止发送动态");
        }
        if(user.getIsAnchor() == null || user.getIsAnchor() != 1){
            throw new ServiceException("只有主播可以发布动态哦");
        }
        boolean inner = innerUserFilter.checkInner(res.getUserId());
        if(!inner){
            Integer maxNum = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.DAY_MAX_DYNAMIC);
            if(maxNum > 0){
                int alreadySendNum = dynamicTotalCache.get(res.getUserId());
                if(alreadySendNum > maxNum){
                    throw new ServiceException("每天最大可发送"+maxNum+"条动态");
                }
            }
        }
        Dynamic dynamic = BeanConvertUtil.convertTo(res, Dynamic::new);
        if(dynamic.getCityId() == null || dynamic.getCityId() == 0){
            dynamic.setCityId(user.getCityId());
            dynamic.setCity(user.getCity());
        } else {
            dynamic.setCity(citysService.getByCityId(dynamic.getCityId()));
        }
        if(CollectionUtil.isNotEmpty(res.getImageList())){
            dynamic.setIsAttach(1);
        }else{
            dynamic.setIsAttach(0);
        }
        dynamic.setAuditStatus(inner ? AuditStatusEnum.SUCCESS.getCode() : AuditStatusEnum.AUDITING.getCode());
        this.save(dynamic);
        List<DynamicImages> dynamicImages = new ArrayList<>();
        List<DynamicAddReq.DynamicImageAddReq> imageList = res.getImageList();
        if(CollectionUtil.isNotEmpty(imageList)){
            for (DynamicAddReq.DynamicImageAddReq imageVo : imageList) {
                CaiFileUtils.FileSize fileSize = CaiFileUtils.getFileSize(imageVo.getUrl());
                DynamicImages po = new DynamicImages();
                po.setUserId(dynamic.getUserId());
                po.setDynamicId(dynamic.getId());
                po.setUrl(imageVo.getUrl());
                po.setWidth(fileSize.getWidth());
                po.setHeight(fileSize.getHeight());
                po.setExts(fileSize.getSuffix());
                dynamicImages.add(po);
            }
            dynamicImagesService.saveBatch(dynamicImages);
        }
    }

    @Override
    public Page<DynamicAdminVo> pageAdmin(PageQuery pageQuery, DynamicAdminVo bo) {
        Page<DynamicAdminVo> page = baseMapper.pageAdmin(pageQuery.build(), bo);
        List<DynamicAdminVo> records = page.getRecords();
        List<Long> dynamicIds = records.stream().filter(i -> i.getIsAttach() == 1).map(DynamicAdminVo::getId).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(dynamicIds)){
            List<DynamicImages> dynamicImages = dynamicImagesService.list(Wrappers.lambdaQuery(DynamicImages.class)
                    .in(DynamicImages::getDynamicId, dynamicIds));
            Map<Long, List<DynamicImages>> map =
                    dynamicImages.stream().collect(Collectors.groupingBy(DynamicImages::getDynamicId));
            for (DynamicAdminVo re : records) {
                List<DynamicImages> images = map.get(re.getId());
                re.setDynamicImageList(images);
            }
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDynamic(Long id) {
        Dynamic dynamic = this.getById(id);
        if(dynamic == null){
            throw new ServiceException("动态不存在!");
        }
        Long userId = LoginHelper.getUserId();
        if(!dynamic.getUserId().equals(userId)){
            throw new ServiceException("只能删除自己的动态哦");
        }
        this.removeById(id);
        dynamicImagesService.removeByDynamicId(id);
    }


    @Override
    public void clearDynamic(Integer hours){
        int index = 0;
        LocalDateTime deleteTimeFlag = LocalDateTime.now().plusHours(-hours);
        while (true){
            List<Dynamic> list = this.list(Wrappers.lambdaUpdate(Dynamic.class)
                    .eq(Dynamic::getAuditStatus, AuditStatusEnum.AUDITING.getCode())
                    .lt(Dynamic::getCreateTime, deleteTimeFlag)
                    .isNull(Dynamic::getSort)
                    .last("limit 100"));
            if(index > 500 || CollectionUtils.isEmpty(list)){
                break;
            }
            index++;
            for (Dynamic dynamic : list) {
                DynamicService dynamicService = SpringUtil.getBean(DynamicService.class);
                dynamicService.deleteDynamic(dynamic.getId());
            }
        }
    }

    @Override
    public boolean auditSuccess(List<Long> ids) {
        return this.update(Wrappers.lambdaUpdate(Dynamic.class)
                .set(Dynamic::getAuditStatus,AuditStatusEnum.SUCCESS.getCode())
                .eq(Dynamic::getAuditStatus,AuditStatusEnum.AUDITING.getCode())
                .in(Dynamic::getId,ids));
    }

    @Override
    public boolean auditFail(Long id) {
        Dynamic dynamic = this.getById(id);
        if(dynamic == null){
            return false;
        }
        boolean update = this.update(Wrappers.lambdaUpdate(Dynamic.class)
                .set(Dynamic::getAuditStatus, AuditStatusEnum.FAIL.getCode())
                .eq(Dynamic::getAuditStatus, AuditStatusEnum.AUDITING.getCode())
                .eq(Dynamic::getId, id));
        if(update){
            yunxinHttpService.dynamicAuditMessage(dynamic.getUserId());
        }
        return update;
    }

}
