package org.dromara.system.service.impl.notice;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;

import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.mybatis.helper.DataBaseHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.FormalParentsStudent;
import org.dromara.system.domain.FormalTeacherClass;
import org.dromara.system.domain.notice.XiaoyuanNotice;
import org.dromara.system.domain.notice.bo.XiaoyuanNoticeBo;
import org.dromara.system.domain.notice.vo.XiaoyuanNoticeVo;
import org.dromara.system.domain.vo.FormalTeacherClassVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.FormalParentsStudentMapper;
import org.dromara.system.mapper.FormalTeacherClassMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.mapper.notice.XiaoyuanNoticeMapper;
import org.dromara.system.service.notice.IXiaoyuanNoticeService;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 校园新闻Service业务层处理
 *
 * @author boman
 * @date 2023-08-16
 */
@RequiredArgsConstructor
@Service
public class XiaoyuanNoticeServiceImpl implements IXiaoyuanNoticeService {

    private final XiaoyuanNoticeMapper baseMapper;

    private final FormalTeacherClassMapper formalTeacherClassMapper;


    private final FormalParentsStudentMapper formalParentsStudentMapper;

    private final SysUserMapper sysUserMapper;

    /**
     * 查询校园新闻
     */
    @Override
    public XiaoyuanNoticeVo queryById(Long noticeId) {
        return baseMapper.selectVoById(noticeId);
    }

    /**
     * 查询校园新闻列表
     */
    @Override
    public TableDataInfo<XiaoyuanNoticeVo> queryPageList(XiaoyuanNoticeBo bo, PageQuery pageQuery) {

        Page<XiaoyuanNoticeVo> result = new Page<>();
        Map<String, Object> params = bo.getParams();
        String role = "admin";
        if (params != null && params.size() > 0) {
            role = (String) params.get("role");
        }
        StringBuilder classId = new StringBuilder("0,");
        if ("teacher".equals(role)) {
            FormalTeacherClass formalTeacherClass = new FormalTeacherClass();
            formalTeacherClass.setTeacherId(LoginHelper.getUserId());
            List<FormalTeacherClassVo> formalTeacherClasses = formalTeacherClassMapper.selectFormalTeacherClassList(formalTeacherClass);
            if (formalTeacherClasses != null && formalTeacherClasses.size() > 0) {
                for (FormalTeacherClassVo teacherClass : formalTeacherClasses) {
                    classId.append(teacherClass.getClassId()).append(",");
                }
            }
            if (StringUtils.isNotBlank(classId.toString())) {
                classId = new StringBuilder(classId.substring(0, classId.length() - 1));
            }
            //查询出所有班级id
            bo.setSenderDept(classId.toString());
            bo.setSenderId(String.valueOf(LoginHelper.getUserId()));
            LambdaQueryWrapper<XiaoyuanNotice> lqw = buildListWrapper(bo);
            result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        } else if ("parents".equals(role)) {
            FormalParentsStudent formalParentsStudent = new FormalParentsStudent();
            formalParentsStudent.setParentsId(LoginHelper.getUserId());
            List<FormalParentsStudent> formalParentsStudents = formalParentsStudentMapper.selectFormalParentsStudentList(formalParentsStudent);
            for (FormalParentsStudent parentsStudent : formalParentsStudents) {
                classId.append(parentsStudent.getClassId()).append(",");
            }
            if (StringUtils.isNotBlank(classId.toString())) {
                classId = new StringBuilder(classId.substring(0, classId.length() - 1));
            }
            //查询出所有班级id
            bo.setSenderDept(classId.toString());
            bo.setSenderId(String.valueOf(LoginHelper.getUserId()));
            LambdaQueryWrapper<XiaoyuanNotice> lqw = buildListWrapper(bo);
            result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        } else if ("admin".equals(role)) {
            LambdaQueryWrapper<XiaoyuanNotice> lqw = Wrappers.lambdaQuery();
            lqw.orderByDesc(XiaoyuanNotice::getCreateTime);
            result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        }
        return TableDataInfo.build(result);
    }

    private LambdaQueryWrapper<XiaoyuanNotice> buildListWrapper(XiaoyuanNoticeBo bo) {
        LambdaQueryWrapper<XiaoyuanNotice> lqw = Wrappers.lambdaQuery();
        lqw.eq(XiaoyuanNotice::getType, "0")
            .or(i -> i.eq(XiaoyuanNotice::getType, "3").eq(XiaoyuanNotice::getSenderId, bo.getSenderId()))
            .or(i -> i.eq(XiaoyuanNotice::getType, "1").apply("find_in_set_multiple('" + bo.getSenderDept() + "',class_id_ke_jian)"))
            .or(i -> i.eq(XiaoyuanNotice::getType, "2").apply("!find_in_set_multiple('" + bo.getSenderDept() + "',class_id_bu_ke_jian)"));
        lqw.orderByDesc(XiaoyuanNotice::getCreateTime);
        return lqw;
    }

    /**
     * 我的校园新闻列表
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public List<XiaoyuanNoticeVo> selectXiaoyuanNoticeMyList(XiaoyuanNoticeBo bo, PageQuery pageQuery) {
        bo.setSenderId(String.valueOf(LoginHelper.getUserId()));
        LambdaQueryWrapper<XiaoyuanNotice> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询校园新闻列表
     */
    @Override
    public List<XiaoyuanNoticeVo> queryList(XiaoyuanNoticeBo bo) {
        bo.setSenderId(String.valueOf(LoginHelper.getUserId()));
        LambdaQueryWrapper<XiaoyuanNotice> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<XiaoyuanNotice> buildQueryWrapper(XiaoyuanNoticeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<XiaoyuanNotice> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getImage()), XiaoyuanNotice::getImage, bo.getImage());
        lqw.eq(StringUtils.isNotBlank(bo.getNoticeTitle()), XiaoyuanNotice::getNoticeTitle, bo.getNoticeTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getNoticeType()), XiaoyuanNotice::getNoticeType, bo.getNoticeType());
        lqw.eq(StringUtils.isNotBlank(bo.getNoticeContent()), XiaoyuanNotice::getNoticeContent, bo.getNoticeContent());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XiaoyuanNotice::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), XiaoyuanNotice::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getClassIdKeJian()), XiaoyuanNotice::getClassIdKeJian, bo.getClassIdKeJian());
        lqw.eq(StringUtils.isNotBlank(bo.getClassIdBuKeJian()), XiaoyuanNotice::getClassIdBuKeJian, bo.getClassIdBuKeJian());
        lqw.eq(StringUtils.isNotBlank(bo.getSenderId()), XiaoyuanNotice::getSenderId, bo.getSenderId());
        lqw.like(StringUtils.isNotBlank(bo.getSenderName()), XiaoyuanNotice::getSenderName, bo.getSenderName());
        lqw.eq(StringUtils.isNotBlank(bo.getSenderDept()), XiaoyuanNotice::getSenderDept, bo.getSenderDept());
        lqw.like(StringUtils.isNotBlank(bo.getSchoolName()), XiaoyuanNotice::getSchoolName, bo.getSchoolName());
        lqw.eq(StringUtils.isNotBlank(bo.getComment()), XiaoyuanNotice::getComment, bo.getComment());
        lqw.eq(StringUtils.isNotBlank(bo.getPrised()), XiaoyuanNotice::getPrised, bo.getPrised());
        lqw.eq(StringUtils.isNotBlank(bo.getCollect()), XiaoyuanNotice::getCollect, bo.getCollect());
        return lqw;
    }

    /**
     * 新增校园新闻
     */
    @Override
    public Boolean insertByBo(XiaoyuanNoticeBo bo) {
        XiaoyuanNotice add = MapstructUtils.convert(bo, XiaoyuanNotice.class);
        validEntityBeforeSave(add);
        add.setSenderId(String.valueOf(LoginHelper.getUserId()));
        add.setSenderName(LoginHelper.getLoginUser().getNickname());
        SysUserVo sysUserVo = sysUserMapper.selectUserById(LoginHelper.getUserId());
        add.setAvatar(sysUserVo.getAvatar());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setNoticeId(add.getNoticeId());
        }
        return flag;
    }

    /**
     * 修改校园新闻
     */
    @Override
    public Boolean updateByBo(XiaoyuanNoticeBo xiaoyuanNotice) {

        //修改之前去查询
        XiaoyuanNoticeVo xiaoyuanNoticeUpdate = baseMapper.selectVoById(xiaoyuanNotice.getNoticeId());
        List<JSONObject> map = new ArrayList<>();
        //判断是评论还是点赞还是收藏
        UUID uuid = UUID.randomUUID();
        String deleteId = xiaoyuanNotice.getDeleteId();
        if (Constants.ONE.equals(xiaoyuanNotice.getUpdateType())) {
            String comment = xiaoyuanNotice.getComment();
            if (StringUtils.isNotBlank(comment)) {
                String updateComment = xiaoyuanNoticeUpdate.getComment();
                JSONObject jsonObject = JSONObject.parseObject(comment);
                //没有id就是新增
                if (StringUtils.isEmpty(deleteId)) {
                    //给新增参数增加id
                    jsonObject.put("id", uuid);
                    map.add(jsonObject);
                    xiaoyuanNotice.setComment(map.toString());
                    //如果数据库中原始数据不为空
                    if (StringUtils.isNotBlank(updateComment)) {
                        updateComment = updateComment.replace("[", "").replace("]", "");
                        ArrayList<Object> arr = new ArrayList<>(updateComment.length());
                        Collections.addAll(arr, updateComment);
                        arr.add(jsonObject);
                        xiaoyuanNotice.setComment(arr.toString());
                    }
                } else {
                    //删除原始数据
                    JSONArray jsonArray = JSONArray.parseArray(updateComment);
                    jsonArray.removeIf(object -> xiaoyuanNotice.getDeleteId().equals(((JSONObject) object).get("id")));
                    xiaoyuanNotice.setComment("");
                    if (jsonArray.size() > 0) {
                        xiaoyuanNotice.setComment(jsonArray.toString());
                    }
                }
            }
        } else if ("2".equals(xiaoyuanNotice.getUpdateType())) {
            String prised = xiaoyuanNotice.getPrised();
            String updatePrised = xiaoyuanNoticeUpdate.getPrised();
            if (StringUtils.isNotBlank(prised)) {
                JSONObject jsonObject = JSONObject.parseObject(prised);
                //给新增参数增加id
                //没有id就是新增
                if (StringUtils.isEmpty(deleteId)) {
                    jsonObject.put("id", uuid);
                    map.add(jsonObject);
                    xiaoyuanNotice.setPrised(map.toString());
                    //如果数据库中原始数据不为空
                    if (StringUtils.isNotBlank(updatePrised)) {
                        updatePrised = updatePrised.replace("[", "").replace("]", "");
                        ArrayList<Object> arr = new ArrayList<>(updatePrised.length());
                        Collections.addAll(arr, updatePrised);
                        arr.add(jsonObject);
                        xiaoyuanNotice.setPrised(arr.toString());
                    }
                } else {

                    //删除原始数据
                    JSONArray jsonArray = JSONArray.parseArray(updatePrised);
                    jsonArray.removeIf(object -> xiaoyuanNotice.getDeleteId().equals(((JSONObject) object).get("id")));
                    xiaoyuanNotice.setPrised("");
                    if (jsonArray.size() > 0) {
                        xiaoyuanNotice.setPrised(jsonArray.toString());
                    }
                }
            }
        } else if ("3".equals(xiaoyuanNotice.getUpdateType())) {
            String collect = xiaoyuanNotice.getCollect();
            String updateCollect = xiaoyuanNoticeUpdate.getCollect();
            if (StringUtils.isNotBlank(collect)) {
                JSONObject jsonObject = JSONObject.parseObject(collect);

                //给新增参数增加id
                //没有id就是新增
                if (StringUtils.isEmpty(deleteId)) {
                    jsonObject.put("id", uuid);
                    map.add(jsonObject);
                    xiaoyuanNotice.setCollect(map.toString());
                    //如果数据库中原始数据不为空
                    if (StringUtils.isNotBlank(updateCollect)) {
                        updateCollect = updateCollect.replace("[", "").replace("]", "");
                        ArrayList<Object> arr = new ArrayList<>(updateCollect.length());
                        Collections.addAll(arr, updateCollect);
                        arr.add(jsonObject);
                        xiaoyuanNotice.setCollect(arr.toString());
                    }
                } else {
                    //删除原始数据
                    JSONArray jsonArray = JSONArray.parseArray(updateCollect);
                    jsonArray.removeIf(object -> xiaoyuanNotice.getDeleteId().equals(((JSONObject) object).get("id")));
                    xiaoyuanNotice.setCollect("");
                    if (jsonArray.size() > 0) {
                        xiaoyuanNotice.setCollect(jsonArray.toString());
                    }
                }
            }
        }

        xiaoyuanNotice.setUpdateTime(DateUtils.getNowDate());
        XiaoyuanNotice update = MapstructUtils.convert(xiaoyuanNotice, XiaoyuanNotice.class);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(XiaoyuanNotice entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除校园新闻
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 我的收藏
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<XiaoyuanNoticeVo> myCollect(XiaoyuanNoticeBo bo, PageQuery pageQuery) {
        bo.setCollect("\"userId\":\"" + LoginHelper.getUserId()+"\"");
        Page<XiaoyuanNoticeVo> xiaoyuanNoticePage = baseMapper.selectXiaoyuanNoticeByMyCollect(pageQuery.build(), this.buildQueryWrapperCollect(bo));
        return TableDataInfo.build(xiaoyuanNoticePage);
    }

    private Wrapper<XiaoyuanNoticeBo> buildQueryWrapperCollect(XiaoyuanNoticeBo bo) {

        QueryWrapper<XiaoyuanNoticeBo> wrapper = Wrappers.query();
        wrapper
            .like(StringUtils.isNotBlank(bo.getCollect()), "collect", bo.getCollect());
        return wrapper;
    }
}
