package com.ruoyi.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.domain.dto.event.EventTypeAssigneeAddRequest;
import com.ruoyi.web.domain.dto.event.EventTypeAssigneeEditRequest;
import com.ruoyi.web.domain.dto.event.EventTypeAssigneeQueryRequest;
import com.ruoyi.web.domain.entity.Event;
import com.ruoyi.web.domain.entity.EventAssign;
import com.ruoyi.web.domain.entity.EventTypeAssignee;
import com.ruoyi.web.domain.vo.PersonInfoVO;
import com.ruoyi.web.domain.vo.event.EventTypeAssigneeVO;
import com.ruoyi.web.mapper.EventTypeAssigneeMapper;
import com.ruoyi.web.service.EventAssignService;
import com.ruoyi.web.service.EventService;
import com.ruoyi.web.service.EventTypeAssigneeService;
import com.ruoyi.web.service.PersonInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class EventTypeAssigneeServiceImpl extends ServiceImpl<EventTypeAssigneeMapper, EventTypeAssignee>
        implements EventTypeAssigneeService {


    @Resource
    private EventTypeAssigneeService eventTypeAssigneeService;

    @Resource
    private PersonInfoService personInfoService;

    @Resource
    private EventAssignService eventAssignService;

    @Resource
    private EventService eventService;


    /**
     * 添加
     *
     * @param eventTypeAssigneeAddRequest
     * @return
     */
    @Override
    public boolean addEventTypeAssignee(EventTypeAssigneeAddRequest eventTypeAssigneeAddRequest) {
        if (ObjectUtil.isEmpty(eventTypeAssigneeAddRequest)) {
            throw new ServiceException("参数为空");
        }
        // 获取请求参数
        List<Integer> types = eventTypeAssigneeAddRequest.getTypes();
        Integer personId = eventTypeAssigneeAddRequest.getPersonId();

        if (ObjectUtil.isEmpty(personId)) {
            throw new ServiceException("人员ID不能为空");
        }
        if (CollectionUtil.isEmpty(types)) {
            throw new ServiceException("事件类型列表不能为空");
        }

        // personId -> userId
        Integer userId = getUserId(personId);
        QueryWrapper<EventTypeAssignee> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        int count = this.count(wrapper);
        if (count > 0) {
            throw new ServiceException("该用户已经是负责人,请勿重新添加");
        }

        // 构建批量插入数据
        List<EventTypeAssignee> assignees = types.stream()
                .map(type -> {
                    EventTypeAssignee assignee = new EventTypeAssignee();
                    assignee.setType(type);
                    assignee.setUserId(userId);
                    return assignee;
                })
                .collect(Collectors.toList());

        // 执行批量插入
        return eventTypeAssigneeService.saveBatch(assignees);
    }

    /**
     * userId -> personId
     *
     * @param personId
     * @return
     */
    private Integer getUserId(Integer personId) {
        List<Integer> personIds = CollUtil.newArrayList(personId);
        List<Integer> userIds = personInfoService.getUserIdListByPersonIds(personIds);
        if (CollUtil.isEmpty(userIds)) {
            throw new ServiceException("未找到用户");
        }
        return userIds.get(0);
    }

    /**
     * 删除
     *
     * @param personId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteEventTypeAssignee(Integer personId) {
        if (ObjectUtil.isEmpty(personId)) {
            throw new ServiceException("id不能为空或id异常");
        }
        ArrayList<Integer> personIds = new ArrayList<>();
        personIds.add(personId);
        List<Integer> userIds = personInfoService.getUserIdListByPersonIds(personIds);
        if (CollectionUtil.isEmpty(userIds)) {
            throw new ServiceException("未找到用户");
        }
        Integer userId = userIds.get(0);

        QueryWrapper<EventTypeAssignee> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        boolean remove = this.remove(wrapper);

        if (remove) {
            // 5. 同步删除事件分配表记录（未完结的）
            QueryWrapper<EventAssign> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("status", 0);
            return eventAssignService.remove(queryWrapper);
        }
        return false;
    }

    /**
     * 修改(负责人类型 不能传空 必须有一个 若要取消 直接删除)  要么新增  要么删除类型
     *
     * @param eventTypeAssigneeEditRequest
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editEventTypeAssignee(EventTypeAssigneeEditRequest eventTypeAssigneeEditRequest) {
        // 1.判断是否存在
//        Integer id = eventTypeAssigneeEditRequest.getId();
//        EventTypeAssignee oldEventTypeAssignee = this.getById(id);
//        if (oldEventTypeAssignee == null) {
//            throw new ServiceException("数据不存在");
//        }
        // 2.获取请求参数
        List<Integer> types = eventTypeAssigneeEditRequest.getTypes();
        Integer personId = eventTypeAssigneeEditRequest.getPersonId();
        if (ObjectUtil.isEmpty(personId)) {
            throw new ServiceException("人员ID不能为空");
        }
        if (CollectionUtil.isEmpty(types)) {
            throw new ServiceException("事件类型列表不能为空");
        }

        // 3.人口id ——> 系统用户id
        Integer userId = getUserId(personId);

        // 4. 删除该负责人原有的所有分配记录
        LambdaQueryWrapper<EventTypeAssignee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EventTypeAssignee::getUserId, userId);
        // 获取已经具有的 类型
        List<EventTypeAssignee> oldEventTypeAssigneeList = this.list(wrapper);
        List<Integer> oldTypes;
        if (CollectionUtil.isNotEmpty(oldEventTypeAssigneeList)) {
            oldTypes = oldEventTypeAssigneeList.stream().map(EventTypeAssignee::getType).collect(Collectors.toList());
        } else {
            oldTypes = Collections.emptyList();
        }
        this.remove(wrapper);

        // 5. 批量插入新数据
        List<EventTypeAssignee> assignees = types.stream()
                .map(type -> {
                    EventTypeAssignee assignee = new EventTypeAssignee();
                    assignee.setType(type);
                    assignee.setUserId(userId);
                    assignee.setUpdateTime(new Date());
                    return assignee;
                })
                .collect(Collectors.toList());

        // 获取重复 类型      oldTypes=2     types= 1,2     onlyInOldTypes = 2
        if (CollectionUtil.isNotEmpty(oldTypes)) {
            // 找出用户失去的类型（仅在 oldTypes 中存在，不在 types 中）  （修改的类型中不包含的类型，需要将事件分配的数据进行删除）
            List<Integer> onlyInOldTypes = oldTypes.stream()
                    .filter(e -> !types.contains(e))
                    .collect(Collectors.toList());
            // 删除对应的事件分配数据（该用户失去对应类型未完结的事件）
            if (CollectionUtil.isNotEmpty(onlyInOldTypes)) {
                QueryWrapper<Event> eventQueryWrapper = new QueryWrapper<>();
                eventQueryWrapper.select("id")
                        .in("type", onlyInOldTypes)
                        .eq("status", 0);
                List<Event> events = eventService.list(eventQueryWrapper);
                if (CollectionUtil.isNotEmpty(events)) {
                    List<Integer> eventIds = events.stream().map(Event::getId).collect(Collectors.toList());

                    boolean b = eventAssignService.deleteEventAssign(eventIds, userId);
                    if (!b) {
                        throw new ServiceException("同步事件分配失败，修改失败");
                    }
                }
            }
        }
        if (!this.saveBatch(assignees)) {
            throw new ServiceException("修改失败");
        }
    }

    /**
     * 获取包装类 (返回 负责人拥有的事件类型列表 )
     *
     * @param eventTypeAssigneeList
     * @return
     */
    @Override
    public EventTypeAssigneeVO getEventTypeAssigneeVO(List<EventTypeAssignee> eventTypeAssigneeList) {
        if (CollectionUtil.isEmpty(eventTypeAssigneeList)) {
            throw new ServiceException("请求参数不存在");
        }
        // 检查第一条记录的非空字段
        EventTypeAssignee first = eventTypeAssigneeList.get(0);
        if (first.getId() == null || first.getUserId() == null) {
            throw new ServiceException("数据字段不完整");
        }

        List<Integer> types = eventTypeAssigneeList.stream().map(
                eventTypeAssignee -> {
                    return eventTypeAssignee.getType();
                }).collect(Collectors.toList());
        EventTypeAssigneeVO eventTypeAssigneeVO = new EventTypeAssigneeVO();
        eventTypeAssigneeVO.setId(first.getId());

        // 将 用户id  转为 人口id 返回
        eventTypeAssigneeVO.setPersonId(first.getUserId());
        eventTypeAssigneeVO.setUpdateTime(first.getUpdateTime());
        eventTypeAssigneeVO.setCreateTime(first.getCreateTime());
        eventTypeAssigneeVO.setTypes(types);

        return eventTypeAssigneeVO;
    }


    /**
     * 根据人口id 获取事件负责人类型分配包装类
     *
     * @param personId
     * @return
     */
    @Override
    public EventTypeAssigneeVO getEventTypeAssigneeById(int personId) {
        if (personId <= 0 || ObjectUtil.isEmpty(personId)) {
            throw new ServiceException("Id不能为空或Id异常");
        }
        // 通过人口id 获取用户id
        Integer userId = getUserId(personId);

        QueryWrapper<EventTypeAssignee> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        List<EventTypeAssignee> eventTypeAssigneeList = this.list(wrapper);
        return getEventTypeAssigneeVO(eventTypeAssigneeList);
    }


    /**
     * 根据事件类型获取 事件负责人列表(未包含管理员)
     *
     * @param type
     * @return
     */
    @Override
    public List<PersonInfoVO> getListEventPersonInfoVO(Integer type) {
        if (type == null) {
            throw new ServiceException("请求参数错误");
        }
        QueryWrapper<EventTypeAssignee> wrapper = new QueryWrapper<>();
        wrapper.eq("type", type);
        List<EventTypeAssignee> eventTypeAssigneeList = this.list(wrapper);
        if (eventTypeAssigneeList.isEmpty()) {
            return new ArrayList<>();
        }
        // 从 eventTypeAssigneeList 中 获取 userId 列表
        List<Integer> userIds = eventTypeAssigneeList.stream().map(eventTypeAssignee -> {
            return eventTypeAssignee.getUserId();
        }).collect(Collectors.toList());
        return personInfoService.getPersonInfoVOListByUserIds(userIds);
    }


    /**
     * 分页获取事件负责人分配列表
     *
     * @param eventTypeAssignQueryRequest
     * @return 返回 对应类型下的负责人列表
     */
    @Override
    public Page<PersonInfoVO> getListEventPersonInfoVOByPage(EventTypeAssigneeQueryRequest eventTypeAssignQueryRequest) {
        long pageNum = eventTypeAssignQueryRequest.getPageNum();
        long size = eventTypeAssignQueryRequest.getPageSize();
        Integer id = eventTypeAssignQueryRequest.getId();
        Integer type = eventTypeAssignQueryRequest.getType();
        String sortField = eventTypeAssignQueryRequest.getSortField();
        String sortOrder = eventTypeAssignQueryRequest.getSortOrder();

        // 1. 分页查询
        QueryWrapper<EventTypeAssignee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtil.isNotEmpty(type), "type", type);
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), "ascend".equals(sortOrder), sortField);
        List<EventTypeAssignee> eventTypeAssigneeList = this.list(queryWrapper);

        // 从 eventTypeAssigneeList 中 获取 userId 列表
        List<Integer> userIds = eventTypeAssigneeList.stream().map(eventTypeAssignee -> {
            return eventTypeAssignee.getUserId();
        }).collect(Collectors.toList());
        // 获取 负责人列表
        List<PersonInfoVO> eventPersonInfoVOList = personInfoService.getPersonInfoVOListByUserIds(userIds);
        Map<Integer, List<Integer>> userTypeMap = new HashMap<>();
        // 如果type为空，查询所有相关的type
        if (ObjectUtil.isEmpty(type)) {
            QueryWrapper<EventTypeAssignee> eventTypeAssigneeQueryWrapper = new QueryWrapper<>();
            List<EventTypeAssignee> assignees = eventTypeAssigneeService.list(eventTypeAssigneeQueryWrapper);

            // 按user_id分组，收集对应的type列表
            userTypeMap = assignees.stream()
                    .collect(Collectors.groupingBy(
                            EventTypeAssignee::getUserId,
                            Collectors.mapping(EventTypeAssignee::getType, Collectors.toList())
                    ));
            // 为每个负责人设置type列表
            for (PersonInfoVO personInfoVO : eventPersonInfoVOList) {
                Integer userId = personInfoVO.getUserId();
                List<Integer> types = userTypeMap.getOrDefault(userId, Collections.emptyList());
                // 对 types 进行升序排序（从小到大）
                Collections.sort(types);
                personInfoVO.setType(types);
            }
        }

        // 构造分页 计算分页数据
        List<PersonInfoVO> pageData = eventPersonInfoVOList.stream()
                .skip((pageNum - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        int total = eventPersonInfoVOList.size();
        Page<PersonInfoVO> resultPage = new Page<>(pageNum, size, total);
        resultPage.setRecords(pageData);
        return resultPage;
    }

}