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.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
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 com.yeejoin.amos.boot.module.hygf.api.util.JsonUtils;
import com.yeejoin.amos.boot.module.hygf.api.util.ListUtils;
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.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
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 java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

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

    final static Logger log = LoggerFactory.getLogger(ToDoTasksServiceImpl.class);
    @Autowired
    protected EmqKeeper emqKeeper;
    @Autowired
    ToDoTasksMapper toDoTasksMapper;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    UserMessageMapper userMessageMapper;
    @Autowired
    Sequence sequence;
    @Value("classpath:/json/hygfRouth.json")
    private Resource hygfRouth;
    @Value("classpath:/json/wxHygfRouth.json")
    private Resource wxHygfRouth;

    /**
     * 分页查询
     */
    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.like(StringUtils.isNotEmpty(dto.getAmosUserId()), "amos_user_id", "%"+dto.getAmosUserId()+"%");
        qw.like(StringUtils.isNotEmpty(dto.getTaskName()), "task_name", "%"+dto.getTaskName()+"%");

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

    @Transactional
    public void completeAndAddToDoTask(List<String> userIds, ToDoTasks toDoTasks, String meg) {
        try {
            completeToDoTasks(toDoTasks, meg);
            addToDoTasksByUserIds(userIds, toDoTasks);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @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);
                    UserMessage userMessage = new UserMessage(doTask.getType(), doTask.getBusinessId(), doTask.getAmosUserId(), new Date(), doTask.getTaskName() + ",此消息已确认." + meg, doTask.getAmosOrgCode());
                    userMessageMapper.insert(userMessage);
                }
            } else {
                log.error("没有查询到待办,不进行更新和发送消息");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     *
     * 删除和业务关联的所有数据
     * @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 = ListUtils.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) {
            log.error(e.getMessage(), e);
        }
    }

    @Transactional
    @Async
    public void addToDoTasksByUserIds(List<String> userIds, ToDoTasks toDoTasks) {
        try {
            if (CollectionUtil.isNotEmpty(userIds)) {
                toDoTasks.setAmosUserId(userIds.toString());
                toDoTasks.setSequenceNbr(sequence.nextId());
                toDoTasksMapper.insert(toDoTasks);
                
                UserMessage userMessage = new UserMessage(toDoTasks.getType(), toDoTasks.getBusinessId(), toDoTasks.getAmosUserId(), new Date(), toDoTasks.getTaskName(), toDoTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);
            } else {
                log.error("用户为空,不进行添加待办和发送消息");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @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);
                UserMessage userMessage = new UserMessage(doTasks.getType(), doTasks.getBusinessId(), doTasks.getAmosUserId(), new Date(), doTasks.getTaskName() + ",此消息已确认." + meg, doTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);
            }

            toDoTasks.setAmosUserId(userId);
            toDoTasksMapper.insert(toDoTasks);
            
            UserMessage userMessage = new UserMessage(toDoTasks.getType(), toDoTasks.getBusinessId(), toDoTasks.getAmosUserId(), new Date(), toDoTasks.getTaskName(), toDoTasks.getAmosOrgCode());
            userMessageMapper.insert(userMessage);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @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);

                UserMessage userMessage = new UserMessage(doTasks.getType(), doTasks.getBusinessId(), doTasks.getAmosUserId(), new Date(), doTasks.getTaskName() + "已完成." + meg, doTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);


            }

            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);
                

                UserMessage userMessage = new UserMessage(toDoTasks.getType(), toDoTasks.getBusinessId(), toDoTasks.getAmosUserId(), new Date(), toDoTasks.getTaskName() + "待完成", toDoTasks.getAmosOrgCode());
                userMessageMapper.insert(userMessage);

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

        }
    }

    public String getRoleIdByName(String groupName) {
        return toDoTasksMapper.getRoleIdByName(groupName);
    }

    public List<String> getTodoUserIds(String companyOrgCode, String roleId) {
        return toDoTasksMapper.getTodoUserIds(companyOrgCode, roleId);
    }

    /**
     * 获取融资机构的待办人员
     * @param companyOrgCode
     * @param roleId
     * @return
     */
    public List<String> getTodoUserIdsByRzjg(String companyOrgCode, String roleId) {
        return toDoTasksMapper.getTodoUserIdsByRzjg(companyOrgCode, roleId);
    }
    /**
     * 根据区域公司、角色、经销商获取待办的人员
     * @param companyOrgCode
     * @param roleId
     * @param amosOrgCode
     * @return
     */
    public List<String> getTodoUserIds(String companyOrgCode, String roleId, String amosOrgCode) {
        if (StringUtils.isNotEmpty(companyOrgCode)) {
            companyOrgCode = "%" + companyOrgCode + "%";
        }
        if (StringUtils.isNotEmpty(roleId)) {
            roleId = "%" + roleId + "%";
        }
        if (StringUtils.isNotEmpty(amosOrgCode)) {
            amosOrgCode = amosOrgCode + "%";
        }
        return toDoTasksMapper.getTodoUserIdsByAmosDealer(companyOrgCode, roleId, amosOrgCode);
    }

    //获取路由地址
    public List<String> filterUsers(String taskType, String key, List<String> userId, String companyOrgCode, String amosDealerCode) {
        List<String> filterUsers = new ArrayList<>();
        List<Map> hygfRouthList = JsonUtils.getResourceList(hygfRouth);
        if (CollectionUtils.isNotEmpty(userId) && CollectionUtils.isNotEmpty(hygfRouthList)) {
            for (Map map : hygfRouthList) {
                if (map.get("taskType").equals(taskType) && map.get("key").equals(key) && "0".equals(map.get("isNeedSpecialDeal"))) {
                    String isAdminRole = (String) map.get("isAdminRole");
                    if ("1".equals(isAdminRole)) {
                        filterUsers = toDoTasksMapper.filterUsersByAdmin(companyOrgCode, userId);
                    } else if ("0".equals(isAdminRole)) {
                        filterUsers = toDoTasksMapper.filterUsersByAmosDealer(companyOrgCode, amosDealerCode, userId);
                    } else if ("2".equals(isAdminRole)) {
                        filterUsers = toDoTasksMapper.filterUsersByAmosDealerAdmin(amosDealerCode, userId);
                    }
                    break;
                }
            }
        }
        return filterUsers;
    }

    //获取路由地址
    public String getRouthPath(String taskType, String key, Object model) {
        List<Map> urlList = JsonUtils.getResourceList(hygfRouth);
        return getRouthPath(taskType, key, urlList, model);
    }

    //获取微信路由地址
    public String getWxRouthPath(String taskType, String key, Object model) {
        List<Map> urlList = JsonUtils.getResourceList(wxHygfRouth);
        return getRouthPath(taskType, key, urlList, model);
    }

    private String getRouthPath(String taskType, String key, List<Map> urlList, Object model) {
        String routhPath = "";
        try {
            for (Map map : urlList) {
                if (map.get("taskType").equals(taskType) && map.get("key").equals(key)) {
                    routhPath = map.get("url").toString();
                    if (StringUtils.isNotEmpty(routhPath)) {
                        // 检查 URL 是否已有参数
                        if (routhPath.contains("?")) {
                            String queryParams = toQueryParams(model);
                            if(StringUtils.isNotEmpty(queryParams)){
                                // 如果 URL 已经包含参数，使用 '&' 来拼接新的参数
                                routhPath = routhPath + "&" + queryParams;
                            }
                        } else {
                            // 如果 URL 没有参数，使用 '?' 来开始拼接
                            routhPath = routhPath + "?" + toQueryParams(model);
                        }
                    }
                    break;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return routhPath;
    }

    private <T> String toQueryParams(T obj) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();

        for (Class<?> clazz = obj.getClass(); !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                if (!Modifier.isStatic(field.getModifiers())) {
                    field.setAccessible(true);

                    try {
                        Object value = field.get(obj);

                        if (value != null && !"".equals(value)) {
                            String encodedValue = URLEncoder.encode(value.toString(), "UTF-8");
                            sb.append(field.getName()).append('=').append(encodedValue).append('&');
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : "";
    }

}