package com.usky.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.common.datascope.context.DataScopeContextHolder;
import com.usky.common.core.bean.ApiResult;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.system.RemoteUserService;
import com.usky.system.domain.*;
import com.usky.system.mapper.MceReceiveMapper;
import com.usky.system.service.*;
import com.usky.common.mybatis.core.AbstractCrudService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 消息接收表 服务实现类
 * </p>
 *
 * @author han
 * @since 2024-05-09
 */
@Service
public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper, MceReceive> implements MceReceiveService {
    @Autowired
    private MceContentService mceContentService;

    @Autowired
    private MceMbuserService mceMbuserService;

    @Autowired
    private MceSettingService mceSettingService;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Override
    public CommonPage<Object> mceList(String infoTitle, String infoType, String startTime, String endTime, Integer id, Integer current, Integer size) {
        List<Object> list = new ArrayList<>();
        LambdaQueryWrapper<MceContent> lambdaQuery1 = Wrappers.lambdaQuery();
        lambdaQuery1.select(MceContent::getId, MceContent::getInfoTitle, MceContent::getInfoContent)
                .like(StringUtils.isNotBlank(infoTitle),MceContent::getInfoTitle,infoTitle)
                .eq(id != null,MceContent::getId,id);
        List<MceContent> list1 = mceContentService.list(lambdaQuery1);
        IPage<MceReceive> page = new Page<>(current, size);
        List<Integer> contentIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list1)){
            for(int i=0;i<list1.size();i++){
                contentIds.add(list1.get(i).getId());
            }
            Long userId = SecurityUtils.getUserId();
            LambdaQueryWrapper<MceReceive> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.select(MceReceive::getId, MceReceive::getInfoType,
                    MceReceive::getContentId, MceReceive::getReadFlag, MceReceive::getCreateTime,
                    MceReceive::getReceiverId,MceReceive::getModuleId)
                    .between(StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime),MceReceive::getCreateTime,
                            startTime,endTime)
                    .eq(StringUtils.isNotBlank(infoType),MceReceive::getInfoType, infoType)
                    .eq(MceReceive::getReceiverId, SecurityUtils.getUserId())
                    .in(CollectionUtils.isNotEmpty(contentIds),MceReceive::getContentId,contentIds)
                    .orderByDesc(MceReceive::getId);
//                .inSql(StringUtils.isNotBlank(infoTitle),MceReceive::getContentId,"SELECT id FROM mce_content WHERE " +
//                        "info_title like '%" + infoTitle + "%' AND tenant_id = "+SecurityUtils.getTenantId()+"");
            page = this.page(page,lambdaQuery);
            if (CollectionUtils.isNotEmpty(page.getRecords())) {
                for (int i = 0; i < page.getRecords().size(); i++) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", page.getRecords().get(i).getId());
                    map.put("infoType", page.getRecords().get(i).getInfoType());
                    map.put("readFlag", page.getRecords().get(i).getReadFlag());
                    map.put("moduleId", page.getRecords().get(i).getModuleId());
                    map.put("createTime", page.getRecords().get(i).getCreateTime());
                    if (CollectionUtils.isNotEmpty(list1)) {
                        for (int j = 0; j < list1.size(); j++) {
                            if (page.getRecords().get(i).getContentId().equals(list1.get(j).getId())) {
                                map.put("contentId",list1.get(j).getId());
                                map.put("infoTitle", list1.get(j).getInfoTitle());
                                map.put("infoContent", list1.get(j).getInfoContent());
                            }
                        }
                    }
                    list.add(map);
                }
            }
        }
        return new CommonPage<>(list,page.getTotal(),page.getCurrent(),page.getSize());
    }

    @Override
    @DataScope
    public CommonPage<Object> mceManageList(String infoTitle, String infoType, String startTime, String endTime, Integer current, Integer size) {
        List<Object> list = new ArrayList<>();
        IPage<MceContent> page = new Page<>(current, size);
        //查询消息内容
        LambdaQueryWrapper<MceContent> lambdaQuery1 = Wrappers.lambdaQuery();
        lambdaQuery1.select(MceContent::getId, MceContent::getInfoTitle, MceContent::getInfoContent, MceContent::getCreateTime,MceContent::getInfoType)
                .like(StringUtils.isNotBlank(infoTitle),MceContent::getInfoTitle,infoTitle)
                .between(StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime),MceContent::getCreateTime, startTime,endTime)
                .eq(StringUtils.isNotBlank(infoType),MceContent::getInfoType, infoType)
                .apply(DataScopeContextHolder.getDataScopeSql())
//              .eq(MceContent::getCreateBy,SecurityUtils.getUsername())
//              .eq(MceContent::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(MceContent::getId);
        page = mceContentService.page(page,lambdaQuery1);

        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            List<Integer> contentIds = new ArrayList<>();
            for (int i = 0; i < page.getRecords().size(); i++) {
                contentIds.add(page.getRecords().get(i).getId());
            }
            QueryWrapper<MceReceive> queryWrapper = Wrappers.query();
            queryWrapper.select("content_id AS contentId","COUNT(read_flag=0 or null) as notReadCount","COUNT" +
                    "(read_flag=1 or null) as readCount","issuer_name AS issuerName")
                    .in("content_id",contentIds)
                    .groupBy("content_id","issuer_name");
            List<Map<String,Object>> readStatisticList = this.listMaps(queryWrapper);
            for (int i = 0; i < page.getRecords().size(); i++) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", page.getRecords().get(i).getId());
                map.put("infoTitle", page.getRecords().get(i).getInfoTitle());
                map.put("infoContent", page.getRecords().get(i).getInfoContent());
                map.put("infoType", page.getRecords().get(i).getInfoType());
                map.put("createTime", page.getRecords().get(i).getCreateTime());
                for (int j = 0; j < readStatisticList.size(); j++) {
                    if (page.getRecords().get(i).getId().equals(readStatisticList.get(j).get("contentId"))){
                        map.put("notReadCount", readStatisticList.get(j).get("notReadCount"));
                        map.put("readCount", readStatisticList.get(j).get("readCount"));
                        map.put("userName", readStatisticList.get(j).get("issuerName"));
                    }
                }
                list.add(map);
            }
        }

        return new CommonPage<>(list,page.getTotal(),page.getCurrent(),page.getSize());
    }

    @Override
    public CommonPage<MceReceive> mceManageById(Integer id, Integer current, Integer size) {
        IPage<MceReceive> page = new Page<>(current, size);
        LambdaQueryWrapper<MceReceive> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(MceReceive::getContentId,id);
        page = this.page(page,lambdaQuery);
//        if (CollectionUtils.isNotEmpty(page.getRecords())) {
//            List<Integer> userIds = new ArrayList<>();
//            for (int i = 0; i < page.getRecords().size(); i++) {
//                userIds.add(page.getRecords().get(i).getReceiverId());
//            }
//            List<Integer> distinctUserIds = userIds.stream()
//                    .distinct()
//                    .collect(Collectors.toList());
//            ApiResult<List<SysUser>> userApi = remoteUserService.userByIdList(distinctUserIds);
//            List<SysUser> list1 = userApi.getData();
//            for (int j = 0; j < page.getRecords().size(); j++) {
//                if (CollectionUtils.isNotEmpty(list1)){
//                    for (int k = 0; k < list1.size(); k++) {
//                        long longValue = list1.get(k).getUserId();
//                        Integer intValue = (int) longValue;
//                        if (page.getRecords().get(j).getReceiverId().equals(intValue)){
//                            page.getRecords().get(j).setUpdateBy(list1.get(k).getUserName());
//                        }
//                    }
//                }
//            }
//        }
        return new CommonPage<>(page.getRecords(),page.getTotal(),page.getCurrent(),page.getSize());
    }

    @Override
    public Map<String, Object> mceReceiveStatic() {
        LocalDateTime currentDate = LocalDateTime.now();
        LocalDateTime oneYearAgo = currentDate.minusYears(1);
        LocalDateTime zeroTime = oneYearAgo.withHour(0).withMinute(0).withSecond(0);
        QueryWrapper<MceReceive> queryWrapper = Wrappers.query();
        queryWrapper.select("COUNT(read_flag=0 or null) as notReadCount","COUNT(read_flag=1 or null) as readCount"
                ,"info_type AS infoType")
                .eq("receiver_id",SecurityUtils.getUserId())
                .between("create_time",zeroTime,currentDate)
                .groupBy("info_type");
        List<Map<String,Object>> readStatisticList = this.listMaps(queryWrapper);
        LambdaQueryWrapper<MceReceive> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(MceReceive::getReceiverId,SecurityUtils.getUserId())
                .eq(MceReceive::getReadFlag,0);
        Integer notReadCount = this.count(lambdaQuery);
        Map<String, Object> map = new HashMap<>();
        map.put("notReadCount", notReadCount);
        map.put("infoTypeStatic", readStatisticList);
        return map;
    }

    @Override
    public void updateMceReceive(MceReceive mceReceive){
        LambdaUpdateWrapper<MceReceive> updateWrapper = new UpdateWrapper<MceReceive>().lambda();
        if (Objects.nonNull(mceReceive.getId())&&!mceReceive.getId().equals(0)){
            updateWrapper.eq(MceReceive::getId,mceReceive.getId())
                    .set(MceReceive::getReadFlag,1)
                    .set(MceReceive::getUpdateBy,SecurityUtils.getUsername())
                    .set(MceReceive::getUpdateTime,LocalDateTime.now());
        }else {
            updateWrapper.eq(MceReceive::getReceiverId,SecurityUtils.getUserId())
                    .eq(MceReceive::getReadFlag,0)
                    .set(MceReceive::getReadFlag,1)
                    .set(MceReceive::getUpdateBy,SecurityUtils.getUsername())
                    .set(MceReceive::getUpdateTime,LocalDateTime.now());
        }
        this.update(updateWrapper);
    }

    public static List<Integer> convertObjectToList(Object object) {
        if (object instanceof List<?>) {
            @SuppressWarnings("unchecked")
            List<Integer> tempList = (List<Integer>) object;
            return tempList;
        } else {
            throw new IllegalArgumentException("The object is not a List");
        }
    }

    @Override
    public void add(String mceReceive){
        JSONObject mceReceiveVO = JSONObject.parseObject(mceReceive);
        String infoTypeName = sysDictDataService.selectDictLabel("message_type",mceReceiveVO.get("infoType").toString());
        if (!mceReceiveVO.containsKey("infoTypeName")) {
            mceReceiveVO.put("infoTypeName",infoTypeName);
        }
        MceContent mceContent = new MceContent();
        mceContent.setInfoTitle(mceReceiveVO.get("infoTitle").toString());
        mceContent.setInfoContent(mceReceiveVO.get("infoContent").toString());
        mceContent.setInfoType(mceReceiveVO.get("infoType").toString());
        mceContent.setCreateBy(SecurityUtils.getUsername());
        mceContent.setCreateTime(LocalDateTime.now());
//        mceContent.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId().intValue());

        mceContent.setTenantId(SecurityUtils.getTenantId());
        mceContentService.save(mceContent);
        Integer contentId = mceContent.getId();
        List<SysUser> list = iSysUserService.userAllList();
        if (CollectionUtils.isNotEmpty(list)) {
            List<Integer> userIds = new ArrayList<>();
            for (int g = 0; g < list.size(); g++) {
                userIds.add(list.get(g).getUserId().intValue());
            }
            List<Integer> userIds1;
            if (mceReceiveVO.containsKey("userIds")) {
                userIds1 = convertObjectToList(mceReceiveVO.get("userIds"));
                userIds.retainAll(userIds1);
            }
            LambdaQueryWrapper<MceMbuser> lambdaQuery3 = Wrappers.lambdaQuery();
            lambdaQuery3.in(MceMbuser::getUserId,userIds);
            List<MceMbuser> list3 = mceMbuserService.list(lambdaQuery3);
            for (int i = 0; i < list.size(); i++) {
                if (CollectionUtils.isNotEmpty(list3)){
                    for (int j = 0; j < list3.size(); j++) {
                        if (list.get(i).getUserId().equals(list3.get(j).getUserId())){
                            MceReceive mceReceive1 = new MceReceive();
                            mceReceive1.setReceiverId(list.get(i).getUserId().intValue());
                            mceReceive1.setContentId(contentId);
                            mceReceive1.setReadFlag(0);
                            mceReceive1.setInfoType(mceReceiveVO.get("infoType").toString());
                            mceReceive1.setModuleId((int)mceReceiveVO.get("id"));
                            if (mceReceiveVO.containsKey("userName")) {
                                mceReceive1.setIssuerName(mceReceiveVO.get("userName").toString());
                            }
                            mceReceive1.setReceiverName(list.get(i).getUserName());
                            mceReceive1.setCreateBy(SecurityUtils.getUsername());
                            mceReceive1.setCreateTime(LocalDateTime.now());
                            mceReceive1.setTenantId(list.get(i).getTenantId());
//                mceReceive1.setDeptId(list.get(i).getDeptId().intValue());
                            this.save(mceReceive1);
                            Integer mceReceiveId = mceReceive1.getId();
                            LambdaQueryWrapper<MceSetting> lambdaQuery = Wrappers.lambdaQuery();
                            lambdaQuery.eq(MceSetting::getCreateBy,list.get(i).getUserName());
                            List<MceSetting> list1 = mceSettingService.list(lambdaQuery);
                            if (CollectionUtils.isNotEmpty(list1)){
                                JSONObject appMode = JSONObject.parseObject(list1.get(0).getAppMode());
                                JSONObject wcMode = JSONObject.parseObject(list1.get(0).getWcMode());
                                if (appMode.get(mceReceiveVO.get("infoType").toString()).equals(true)){
                                    if (list.get(i).getUserId().equals(list3.get(j).getUserId()) && StringUtils.isNotBlank(list3.get(j).getCids())){
                                        mceContentService.sendApp(mceReceiveVO,list3.get(j).getCids(),0,0);
                                    }
                                }
                                if (wcMode.get(mceReceiveVO.get("infoType").toString()).equals(true)){
                                    if (list.get(i).getUserId().equals(list3.get(j).getUserId()) && StringUtils.isNotBlank(list3.get(j).getOpenid())){
                                        mceContentService.sendApp(mceReceiveVO,list3.get(j).getOpenid(),mceReceiveId,1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean removeById(Integer id) {
        LambdaQueryWrapper<MceReceive> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(MceReceive::getContentId,id);
        this.remove(lambdaQuery);
        return mceContentService.removeById(id);
    }
}
