package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
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.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.hygf.api.dto.TasksRole;
import com.yeejoin.amos.boot.module.hygf.api.dto.ToDoTasksDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.ToDoTasksPageDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.ToDoTasks;
import com.yeejoin.amos.boot.module.hygf.api.entity.UserMessage;
import com.yeejoin.amos.boot.module.hygf.api.mapper.ToDoTasksMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.UserMessageMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IToDoTasksService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 人员任务服务实现类
 *
 * @author system_generator
 * @date 2023-09-08
 */
@Service
public class ToDoTasksServiceImpl extends BaseService<ToDoTasksDto,ToDoTasks,ToDoTasksMapper> implements IToDoTasksService {

    @Autowired
    ToDoTasksMapper toDoTasksMapper;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    UserMessageMapper userMessageMapper;

    @Autowired
    protected EmqKeeper emqKeeper;
    @Autowired
    Sequence sequence;

    final static Logger log = LoggerFactory.getLogger(ToDoTasksServiceImpl.class);

    /**
     * 分页查询
     */
    public Page<ToDoTasksDto> queryForToDoTasksPage(Page<ToDoTasksDto> page)   {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<ToDoTasksDto> queryForToDoTasksList()   {
        return this.queryForList("" , false);
    }


    public IPage<ToDoTasks> queryToDoTasksPageDto(ToDoTasksPageDto dto)   {

        //列表数据组装
        QueryWrapper<ToDoTasks> qw = new QueryWrapper<>();
        qw.eq(StringUtils.isNotEmpty(dto.getType()), "type",dto.getType() );
        qw.eq(StringUtils.isNotEmpty(dto.getState()), "state",dto.getState() );
        qw.eq(StringUtils.isNotEmpty(dto.getAmosUserId()), "amos_user_id",dto.getAmosUserId() );

        qw.orderBy(Boolean.TRUE, Boolean.FALSE, "creation_time");
        IPage<ToDoTasks> toDoTasksPage = toDoTasksMapper.selectPage(dto, qw);
        return toDoTasksPage;
    }

    @Transactional
    public void completeToDoTasks(ToDoTasks toDoTasks,String meg) {
        try {
            LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ToDoTasks::getType, toDoTasks.getType());
            wrapper.eq(ToDoTasks::getState, "待办");
            wrapper.eq(ToDoTasks::getBusinessId, toDoTasks.getBusinessId());
            List<ToDoTasks> doTasks= toDoTasksMapper.selectList(wrapper);
            if(CollectionUtils.isNotEmpty(doTasks)){
                for (ToDoTasks doTask : doTasks) {
                    doTask.setState("已办");
                    doTask.setCompleteTime(new Date());
                    toDoTasksMapper.updateById(doTask);
                    emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(doTasks).getBytes(), 2 ,false);
                    UserMessage userMessage=  new UserMessage( doTask.getType(),  doTask.getBusinessId(),  doTask.getAmosUserId(),  new Date(),  doTask.getTaskName()+",此消息已确认."+meg,  doTask.getAmosOrgCode());
                    userMessageMapper.insert(userMessage);
                    emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);
                }
            }else {
                log.error("没有查询到待办,不进行更新和发送消息");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw  new BadRequest("任务更新失败！");
        }
    }

    /**
     *
     * 删除和业务关联的所有数据
     * @param businessIds
     */
    @Transactional
    public void deleteByBusinessIds(List<String> businessIds) {
        try {
            if(CollectionUtil.isNotEmpty(businessIds)){
                if(businessIds.size() < 1000){
                    LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
                    wrapper.in(ToDoTasks::getBusinessId,businessIds);
                    remove(wrapper);
                }else {
                    List<List<String>> lists = splitList(businessIds, 1000);
                    for (List<String> list : lists) {
                        LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
                        wrapper.in(ToDoTasks::getBusinessId,list);
                        remove(wrapper);
                    }
                }
            }else {
                log.error("业务Id为空，不进行删除");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw  new BadRequest("业务删除失败！");
        }
    }

    private  <T> List<List<T>> splitList(List<T> list, int chunkSize) {
        List<List<T>> splitLists = new ArrayList<>();
        int totalSize = list.size();

        for (int i = 0; i < totalSize; i += chunkSize) {
            // 计算结束索引，确保不超过列表的大小
            int end = Math.min(i + chunkSize, totalSize);
            // 使用 subList 方法获取子列表
            List<T> sublist = list.subList(i, end);
            splitLists.add(new ArrayList<>(sublist)); // 创建新的 ArrayList 以避免 ConcurrentModificationException
        }

        return splitLists;
    }

    @Transactional
    public void addToDoTasksByUserIds(List<String> userIds, ToDoTasks toDoTasks) {
        try {
            if(CollectionUtil.isNotEmpty(userIds)){
                for (String todoUserId : userIds) {
                    toDoTasks.setAmosUserId(todoUserId);
                    toDoTasks.setSequenceNbr(sequence.nextId());
                    toDoTasksMapper.insert(toDoTasks);
                    emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(toDoTasks).getBytes(), 2 ,false);
                    UserMessage userMessage=  new UserMessage( toDoTasks.getType(),  toDoTasks.getBusinessId(),  toDoTasks.getAmosUserId(),  new Date(),  toDoTasks.getTaskName(),  toDoTasks.getAmosOrgCode());
                    userMessageMapper.insert(userMessage);
                    emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);
                }
            }else {
                log.error("用户为空,不进行添加待办和发送消息");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw  new BadRequest("任务添加失败！");
        }
    }

    @Override
    @Transactional
    public void addToDoTasksByUserId(String userId, ToDoTasks toDoTasks,String meg) {
        try {


        LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ToDoTasks::getType, toDoTasks.getType());
        wrapper.eq(ToDoTasks::getState, "待办");
        wrapper.eq(ToDoTasks::getBusinessId, toDoTasks.getBusinessId());
        ToDoTasks doTasks= toDoTasksMapper.selectOne(wrapper);
        if(doTasks!=null){
            doTasks.setState("已办");
            doTasks.setCompleteTime(new Date());
            toDoTasksMapper.updateById(doTasks);
            emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(doTasks).getBytes(), 2 ,false);
            UserMessage userMessage=  new UserMessage( doTasks.getType(),  doTasks.getBusinessId(),  doTasks.getAmosUserId(),  new Date(),  doTasks.getTaskName()+"已完成."+meg,  doTasks.getAmosOrgCode());
            userMessageMapper.insert(userMessage);
            emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);
        }

        toDoTasks.setAmosUserId(userId);
        toDoTasksMapper.insert(toDoTasks);
            emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(toDoTasks).getBytes(), 2 ,false);
        UserMessage userMessage=  new UserMessage( toDoTasks.getType(),  toDoTasks.getBusinessId(),  toDoTasks.getAmosUserId(),  new Date(),  toDoTasks.getTaskName()+"待完成",  toDoTasks.getAmosOrgCode());
        userMessageMapper.insert(userMessage);
            emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);
        }catch (Exception e){
            e.printStackTrace();
            throw  new BadRequest("任务添加失败！");
        }
    }

    @Override
    @Async
    public void addToDoTasksByRole(String role, ToDoTasks toDoTasks,String meg) {
        //查询该角色的所有人员，按时间倒序排序。缓存，每次按顺序取一个，内存中删除一个，知道分配完，继续查询获取，重新分配。
        try {


            LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ToDoTasks::getType, toDoTasks.getType());
            wrapper.eq(ToDoTasks::getState, "待办");
            wrapper.eq(ToDoTasks::getBusinessId, toDoTasks.getBusinessId());
            ToDoTasks doTasks= toDoTasksMapper.selectOne(wrapper);
            if(doTasks!=null){
                doTasks.setState("已办");
                doTasks.setCompleteTime(new Date());
                toDoTasksMapper.updateById(doTasks);
                emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(doTasks).getBytes(), 2 ,false);

                UserMessage userMessage=  new UserMessage( doTasks.getType(),  doTasks.getBusinessId(),  doTasks.getAmosUserId(),  new Date(),  doTasks.getTaskName()+"已完成."+meg,  doTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);
                emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);


            }

            synchronized (this) {
                if (redisUtils.hasKey("TAKS_" + role)) {
                    String id = redisUtils.get("TAKS_" + role).toString();
                    System.out.println(role+"角色人员"+id);
                    List<TasksRole> listd = toDoTasksMapper.getTasksRole(role,toDoTasks.getAmosOrgCode());

                    if (listd != null && !listd.isEmpty()) {
                        List<String> idList=listd.stream().map(TasksRole::getAmosUserId).collect(Collectors.toList());
                        if(idList.indexOf(id)>-1){
                             if(idList.indexOf(id)+1>idList.size()-1){
                                 toDoTasks.setAmosUserId(idList.get(0));
                                 redisUtils.set("TAKS_" + role, idList.get(0));

                             }else{
                                 toDoTasks.setAmosUserId(idList.get(idList.indexOf(id)+1));
                                 redisUtils.set("TAKS_" + role, idList.get(idList.indexOf(id)+1));
                             }
                        }else{
                            toDoTasks.setAmosUserId(idList.get(0));
                            redisUtils.set("TAKS_" + role, idList.get(0));
                        }
                    }else {
                        System.out.println(role+"没有此角色人员");
                        log.info("没有此角色人员！");
                    }

                } else {

                    List<TasksRole> listd = toDoTasksMapper.getTasksRole(role,toDoTasks.getAmosOrgCode());
                    if (listd != null && !listd.isEmpty()) {
                        List<String> idList=listd.stream().map(TasksRole::getAmosUserId).collect(Collectors.toList());
                        toDoTasks.setAmosUserId(idList.get(0));
                        redisUtils.set("TAKS_" + role, idList.get(0));

                    }  else {
                        System.out.println(role+"没有此角色人员");
                        log.info("没有此角色人员！");
                    }

                }
                toDoTasksMapper.insert(toDoTasks);
                emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(toDoTasks).getBytes(), 2 ,false);

                UserMessage userMessage=  new UserMessage( toDoTasks.getType(),  toDoTasks.getBusinessId(),  toDoTasks.getAmosUserId(),  new Date(),  toDoTasks.getTaskName()+"待完成",  toDoTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);
                emqKeeper.getMqttClient().publish("MY_MESSAGE" ,JSON.toJSONString(userMessage).getBytes(), 2 ,false);

            }
            }catch(Exception e){
                log.info("生成待办任务失败！");
                e.printStackTrace();

            }
        }

}