package com.mcwl.communityCenter.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.constant.HttpStatus;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.domain.R;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.page.PageDomain;
import com.mcwl.common.core.page.TableDataInfo;
import com.mcwl.common.core.redis.RedisCache;
import com.mcwl.common.exception.BusinessException;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.communityCenter.constant.AdviceConstant;
import com.mcwl.communityCenter.domain.*;
import com.mcwl.communityCenter.domain.dto.*;
import com.mcwl.communityCenter.domain.vo.CommentVo;
import com.mcwl.communityCenter.domain.vo.PersonHomeVo;
import com.mcwl.communityCenter.domain.vo.PublishVo;
import com.mcwl.communityCenter.mapper.*;
import com.mcwl.communityCenter.service.*;
import com.mcwl.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import nonapi.io.github.classgraph.concurrency.AutoCloseableExecutorService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.temporal.ValueRange;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

@Service
@RequiredArgsConstructor
public class PublishServiceImpl extends ServiceImpl<PublishMapper, Publish> implements PublishService {

    private final ISysUserService sysUserService;

    private final InviteMapper inviteMapper;

    private final CommunityMapper communityMapper;

    private final CommunityUserMapper communityUserMapper;

    private final PublishCollectService publishCollectService;

    private final PublishCommentService publishCommentService;

    private final PublishMapper publishMapper;

    private final PublishLikeMapper publishLikeMapper;

    private final CommunityAdviceMapper communityAdviceMapper;

    private final QuestionService questionService;

    private final PublishReportMapper publishReportMapper;

    private final RedisCache redisCache;


    @Override
    public PublishVo getDetail(PublishDetailRes publishDetailRes) {
        Long publishId = publishDetailRes.getPublishId();
        Long tenantId = publishDetailRes.getTenantId();
        Long communityId = publishDetailRes.getCommunityId();

        // 根据id和租户id和社区id查询发布信息
        Publish publish = baseMapper.selectByIdAndTenantIdAndCommunityId(publishId, tenantId, communityId);

        if (Objects.isNull(publish)) {
            return null;
        }
        PublishVo publishVo = new PublishVo();
        BeanUtil.copyProperties(publish, publishVo);
        Long userId = publish.getUserId();
        SysUser sysUser = sysUserService.selectUserById(userId);
        publishVo.setUserName(sysUser.getNickName());
        publishVo.setAvatar(sysUser.getAvatar());
        return publishVo;
    }

    @Override
    public R<Object> publish(PublishRes publishRes) {

        Long userId = SecurityUtils.getUserId();

        Community community = communityMapper.getByTenantIdAndCommunityId(publishRes.getTenantId(), publishRes.getCommunityId());

        if (Objects.isNull(community)) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "用户社区未创建");
        }

        CommunityUser communityUser = communityUserMapper.selectCommunityUser(publishRes.getTenantId(), publishRes.getCommunityId(), userId);


        if (Objects.isNull(communityUser)) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您不是该社区成员");
        }

        if ("1".equals(communityUser.getIsBlack())) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您已被拉黑");
        }

        Publish publish = new Publish();
        BeanUtil.copyProperties(publishRes, publish);
        publish.setUserId(userId);
        if (Objects.isNull(publish.getPublishTime())) {
            publish.setPublishTime(new Date());
        }
        baseMapper.insertPublish(publish);
        redisCache.deleteObject("communityPublishNumMap");

        return R.ok();
    }

    @Override
    public TableDataInfo getPublishList(PublishPageRes publishPageRes) {

        Page<Publish> page = this.initPage(publishPageRes);
        page.addOrder(new OrderItem("create_time", false));

        // 根据租户id和社区id查询分页数据
        baseMapper.selectByTenantIdAndCommunityIdPage(page, publishPageRes.getTenantId(), publishPageRes.getCommunityId());


        List<Publish> publishList = page.getRecords();
        List<PublishVo> publishVoList = new ArrayList<>();
        for (Publish publish : publishList) {
            PublishVo publishVo = new PublishVo();
            BeanUtil.copyProperties(publish, publishVo);
            Long userId = publish.getUserId();
            SysUser sysUser = sysUserService.selectUserById(userId);
            publishVo.setUserName(sysUser.getNickName());
            publishVo.setAvatar(sysUser.getAvatar());
            publishVoList.add(publishVo);
        }


        // 封装返回
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(publishVoList);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

    @Override
    public TableDataInfo publishImage(PublishPageRes publishPageRes) {

        Page<Publish> page = this.initPage(publishPageRes);
        page.addOrder(new OrderItem("create_time", false));

        // 根据租户id和社区id和fileUrl不为空查询分页数据
        baseMapper.selectByTenantIdAndCommunityIdAndNotNullFilePage(page, publishPageRes.getTenantId(), publishPageRes.getCommunityId());

        List<Publish> publishList = page.getRecords();
        List<PublishVo> publishVoList = new ArrayList<>();
        for (Publish publish : publishList) {
            PublishVo publishVo = new PublishVo();
            BeanUtil.copyProperties(publish, publishVo);
            Long userId = publish.getUserId();
            SysUser sysUser = sysUserService.selectUserById(userId);
            publishVo.setUserName(sysUser.getNickName());
            publishVo.setAvatar(sysUser.getAvatar());
            publishVoList.add(publishVo);
        }


        // 封装返回
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(publishVoList);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

    @Override
    public TableDataInfo publishFile(PublishPageRes publishPageRes) {
        Page<Publish> page = this.initPage(publishPageRes);
        page.addOrder(new OrderItem("create_time", false));

        // 根据租户id和社区id和imageUrl不为空查询分页数据
        baseMapper.selectByTenantIdAndCommunityIdAndNotNullFilePage(page, publishPageRes.getTenantId(), publishPageRes.getCommunityId());

        List<Publish> publishList = page.getRecords();
        List<PublishVo> publishVoList = new ArrayList<>();
        for (Publish publish : publishList) {
            PublishVo publishVo = new PublishVo();
            BeanUtil.copyProperties(publish, publishVo);
            Long userId = publish.getUserId();
            SysUser sysUser = sysUserService.selectUserById(userId);
            publishVo.setUserName(sysUser.getNickName());
            publishVo.setAvatar(sysUser.getAvatar());
            publishVoList.add(publishVo);
        }


        // 封装返回
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(publishVoList);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

    @Override
    public R<Object> elitePublish(Long tenantId, Long communityId, Long publishId) {

        CommunityUser communityUser = communityUserMapper.selectCommunityUser(tenantId, communityId, SecurityUtils.getUserId());
        if (Objects.isNull(communityUser)) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您不是该社区成员");
        }
        if ("1".equals(communityUser.getIsBlack())) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您已被拉黑");
        }
        if (communityUser.getUserType() != 2) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您不是群主");
        }
        baseMapper.elitePublish(tenantId, communityId, publishId);
        return R.ok();
    }

    @Override
    public TableDataInfo publishList(PublishPageRes publishPageRes) {
        Page<Publish> page = this.initPage(publishPageRes);

        List<PublishVo> publishVoList = baseMapper.publishList(page, publishPageRes);

        for (PublishVo publishVo : publishVoList) {

            CommentDetailRes commentDetailRes = new CommentDetailRes();
            commentDetailRes.setTenantId(publishVo.getTenantId());
            commentDetailRes.setCommunityId(publishVo.getCommunityId());
            commentDetailRes.setPublishId(publishVo.getId());

            List<CommentVo> commentList = publishCommentService.getComment(commentDetailRes).getData();


            PublishLikeRes publishLikeRes = new PublishLikeRes(publishVo.getTenantId(), publishVo.getCommunityId(), publishVo.getId());
            PublishLike publishLike = publishLikeMapper.selectPublishLike(publishLikeRes, SecurityUtils.getUserId());
            if (Objects.nonNull(publishLike)) {
                String delFlag = publishLike.getDelFlag();
                if ("0".equals(delFlag)) {
                    publishVo.setIsLike(1);
                } else {
                    publishVo.setIsLike(0);
                }
            } else {
                publishVo.setIsLike(0);
            }

            PublishCollectRes publishCollectRes = new PublishCollectRes(publishVo.getTenantId(), publishVo.getCommunityId(), publishVo.getId());
            PublishCollect publishCollect = publishCollectService.getPublishCollect(publishCollectRes, SecurityUtils.getUserId());
            if (Objects.nonNull(publishCollect)) {
                String delFlag = publishCollect.getDelFlag();
                if ("0".equals(delFlag)) {
                    publishVo.setIsCollect(1);
                } else {
                    publishVo.setIsCollect(0);
                }
            } else {
                publishVo.setIsCollect(0);
            }


            publishVo.setCommentList(commentList);
        }


        // 封装返回
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(publishVoList);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

    @Override
    public TableDataInfo myPublishList(MyPublishPageRes myPublishPageRes) {
        Page<Publish> page = this.initPage(myPublishPageRes);
        page.addOrder(new OrderItem("p.create_time", false));

        List<PublishVo> publishVoList = baseMapper.myPublishList(page, myPublishPageRes, SecurityUtils.getUserId());

        List<PersonHomeVo> personHomeVoList = new ArrayList<>();

        for (PublishVo publishVo : publishVoList) {
            PersonHomeVo personHomeVo = BeanUtil.toBean(publishVo, PersonHomeVo.class);

            CommentDetailRes commentDetailRes = new CommentDetailRes();
            commentDetailRes.setTenantId(myPublishPageRes.getTenantId());
            commentDetailRes.setCommunityId(myPublishPageRes.getCommunityId());
            commentDetailRes.setPublishId(publishVo.getId());

            List<CommentVo> commentVoList = publishCommentService.getComment(commentDetailRes).getData();
            personHomeVo.setCommentList(commentVoList);
            personHomeVoList.add(personHomeVo);
        }

        // 封装返回
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(personHomeVoList);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void collectPublish(PublishCollectRes publishCollectRes) {
        Long tenantId = publishCollectRes.getTenantId();
        Long communityId = publishCollectRes.getCommunityId();
        Long publishId = publishCollectRes.getPublishId();
        Long userId = SecurityUtils.getUserId();


        Publish publish = publishMapper.selectByIdAndTenantIdAndCommunityId(publishId, tenantId, communityId);
        if (Objects.isNull(publish)) {
            throw new ServiceException("该内容不存在", HttpStatus.SHOW_ERROR_MSG);
        }

        PublishCollect publishCollect = publishCollectService.getPublishCollect(publishCollectRes, userId);

        if (Objects.isNull(publishCollect)) {
            publishCollect = new PublishCollect();
            publishCollect.setTenantId(tenantId);
            publishCollect.setCommunityId(communityId);
            publishCollect.setPublishId(publishId);
            publishCollect.setUserId(userId);
            publishCollectService.savePublishCollect(publishCollect);
            this.addCollectAdvice(publish);
            return;
        }

        if ("0".equals(publishCollect.getDelFlag())) {
            publishCollect.setDelFlag("2");
        } else {
            publishCollect.setDelFlag("0");
        }
        publishCollectService.updatePublishCollect(publishCollect);
        this.addCollectAdvice(publish);


    }

    private void addCollectAdvice(Publish publish) {
        CommunityAdvice communityAdvice = new CommunityAdvice();

        communityAdvice.setTenantId(publish.getTenantId());
        communityAdvice.setCommunityId(publish.getCommunityId());
        communityAdvice.setSendUserId(SecurityUtils.getUserId());
        communityAdvice.setAdviceType(AdviceConstant.LIKE);
        communityAdvice.setUserId(publish.getUserId());
        communityAdvice.setContent(StringUtils.format("{}收藏了你发布的{}",
                SecurityUtils.getLoginUser().getUser().getNickName(), publish.getContent()));

        communityAdviceMapper.insert(communityAdvice);
    }

    @Override
    public TableDataInfo getPersonHomeList(PersonHomePageRes personHomePageRes) {
        Integer type = personHomePageRes.getType();
        switch (type) {
            case 1:
                return questionService.myQuestionList(BeanUtil.toBean(personHomePageRes, QuestionPageRes.class));
            case 2:
                return publishCollectService.myCollectList(BeanUtil.toBean(personHomePageRes, MyPublishCollectPageRes.class));
            default:
                return this.myPublishList(BeanUtil.toBean(personHomePageRes, MyPublishPageRes.class));
        }
    }

    @Override
    public void reportPublish(PublishReportRes publishReportRes) {
        Long tenantId = publishReportRes.getTenantId();
        Long communityId = publishReportRes.getCommunityId();
        Long publishId = publishReportRes.getPublishId();

        CommunityUser communityUser = communityUserMapper.selectCommunityUser(tenantId, communityId, SecurityUtils.getUserId());
        if (Objects.isNull(communityUser)) {
            throw new ServiceException("您不是该社区成员", HttpStatus.SHOW_ERROR_MSG);
        }

        if ("1".equals(communityUser.getIsBlack())) {
            throw new ServiceException("您已被拉黑", HttpStatus.SHOW_ERROR_MSG);
        }

        Publish publish = publishMapper.selectByIdAndTenantIdAndCommunityId(publishId, tenantId, communityId);

        if (Objects.isNull(publish)) {
            throw new ServiceException("该内容不存在", HttpStatus.SHOW_ERROR_MSG);
        }

        PublishReport publishReport = BeanUtil.toBean(publishReportRes, PublishReport.class);
        publishReport.setUserId(SecurityUtils.getUserId());

        publishReportMapper.insertReport(publishReport);

    }

    @Override
    public Publish getLastPublish(Long tenantId, Long communityId) {
        return baseMapper.getLastPublish(tenantId, communityId);
    }

    @Override
    public R<Object> removePublish(PublishRemoveRes publishRemoveRes) {
        Long tenantId = publishRemoveRes.getTenantId();
        Long communityId = publishRemoveRes.getCommunityId();
        Long publishId = publishRemoveRes.getPublishId();

        Long currentUserId = SecurityUtils.getUserId();
        CommunityUser communityUser = communityUserMapper.selectCommunityUser(tenantId, communityId, currentUserId);
        if (Objects.isNull(communityUser)) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您不是该社区成员");
        }

        Publish publish = publishMapper.selectByIdAndTenantIdAndCommunityId(publishId, tenantId, communityId);
        if (Objects.isNull(publish)) {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "该内容不存在");
        }

        if (publish.getUserId().equals(currentUserId) || publish.getUserId().equals(tenantId)) {
            publishMapper.removePublish(publishRemoveRes);
        } else {
            return R.fail(HttpStatus.SHOW_ERROR_MSG, "您没有权限删除该内容");
        }
        return R.ok(HttpStatus.SHOW_ERROR_MSG, "删除成功");
    }

    private Page<Publish> initPage(PageDomain pageDomain) {
        return new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
    }
}
