package com.tuoheng.admin.service.iotequipment.query;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.conver.IotEquipmentConverMapper;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.DataPermissionEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.enums.code.inspection.QueryInspectionPageListCodeEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.request.iotequipment.QueryIotEquipmentPageListRequest;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.admin.vo.IotEquipmentVo;
import com.tuoheng.common.core.utils.JsonResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 物联设备 业务类
 *
 * @author wanjing
 * @since 2023-11-25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QueryEditIotEquipmentPageListService {

    private final DeptMapper deptMapper;

    private final IotEquipmentMapper iotEquipmentMapper;

    private final RoadInformationMapper roadInformationMapper;

    private final SectionMapper sectionMapper;

    private final UserMapper userMapper;

    public JsonResult getPageList(QueryIotEquipmentPageListRequest request) {
        User user = CurrentUserUtil.getUserInfo();
        JsonResult result = this.check(request);
        if (0 != result.getCode()) {
            log.info("查询物联设备分页列表：校验失败：{}", result.getMsg());
            return result;
        }

        // 获取部门Id的查询范围
        List<String> deptIdList = this.getDeptIdList(user);
        request.setDeptIdList(deptIdList);
        request.setTenantId(user.getTenantId());

        // 设置分页参数
        IPage<IotEquipment> page = new Page<>(request.getPage(), request.getLimit());
        // 查询结果
        IPage<IotEquipment> pageData = iotEquipmentMapper.selectPageList(page, request);
        if (null == pageData || pageData.getTotal() == 0) {
            log.info("获取任务分页列表为空");
            return JsonResult.success(null, QueryInspectionPageListCodeEnum.DATA_IS_FAILED.getMsg());
        }

        List<IotEquipmentVo> iotEquipmentVoList = this.buildIotEquipmentVoList(pageData.getRecords());
        // 重写返回结果对象
        IPage<IotEquipmentVo> pageDataVo = new Page<>();
        pageDataVo.setPages(pageData.getPages());
        pageDataVo.setCurrent(pageData.getCurrent());
        pageDataVo.setSize(pageData.getSize());
        pageDataVo.setTotal(pageData.getTotal());
        pageDataVo.setRecords(iotEquipmentVoList);
        return JsonResult.success(pageDataVo);
    }

    /**
     * 检查参数
     *
     * @param request
     * @return
     */
    private JsonResult check(QueryIotEquipmentPageListRequest request) {
        return JsonResult.success();
    }

    /**
     * 获取部门Id的查询范围
     *
     * @return
     */
    private List<String> getDeptIdList(User user) {
        List<String> deptIdList = new ArrayList<>();
        if (DataPermissionEnum.ALL.getCode() == user.getDataPermission()) {
            return deptIdList;
        } else if (DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == user.getDataPermission()) {
            deptIdList = deptMapper.selectAllChildListById(user.getDeptId());
        } else if (DataPermissionEnum.DEPT.getCode() == user.getDataPermission()) {
            deptIdList.add(user.getDeptId());
        }
        return deptIdList;
    }

    private List<IotEquipmentVo> buildIotEquipmentVoList(List<IotEquipment> iotEquipmentList) {
        if (CollectionUtil.isEmpty(iotEquipmentList)) {
            return null;
        }
        List<IotEquipmentVo> iotEquipmentVoList = IotEquipmentConverMapper.INSTANCE.fromIotEquipmentToIotEquipmentVoList(iotEquipmentList);
        Map<String, Dept> deptMap = this.getDeptMap(iotEquipmentList);
        Map<String, RoadInformation> roadInformationMap = this.getRoadInformationMap(iotEquipmentList);
        Map<String, Section> sectionMap = this.getSectionMap(iotEquipmentList);
        Map<String, User> userMap = this.getUserMap(iotEquipmentList);
        Dept dept;
        RoadInformation roadInformation;
        Section section;
        User user;
        for (IotEquipmentVo iotEquipmentVo : iotEquipmentVoList) {
            if (ObjectUtil.isNotEmpty(deptMap)) {
                dept = deptMap.get(iotEquipmentVo.getDeptId());
                if (ObjectUtil.isNotEmpty(dept)) {
                    iotEquipmentVo.setDeptName(dept.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(roadInformationMap)) {
                roadInformation = roadInformationMap.get(iotEquipmentVo.getRoadId());
                if (ObjectUtil.isNotEmpty(roadInformation)) {
                    iotEquipmentVo.setRoadName(roadInformation.getName());
                }
            }

            //返回数据模型新增字段:路段范围sectionRange 和 用户名username
            if (ObjectUtil.isNotEmpty(sectionMap)) {
                section = sectionMap.get(iotEquipmentVo.getSectionId());
                if (ObjectUtil.isNotEmpty(section)) {
                    iotEquipmentVo.setSectionRange(section.getSectionRange());
                }
            }

            if (ObjectUtil.isNotEmpty(userMap)) {
                user = userMap.get(iotEquipmentVo.getCreateUser());
                if (ObjectUtil.isNotEmpty(user)) {
                    iotEquipmentVo.setCreateUsername(user.getRealname());
                }
            }
        }
        return iotEquipmentVoList;
    }

    /**
     * 获取用户列表，放到map，减少循环次数
     *
     * @param iotEquipmentList
     * @return
     */
    private Map<String, User> getUserMap(List<IotEquipment> iotEquipmentList) {
        List<String> userIdList = iotEquipmentList.stream().map(o -> o.getCreateUser()).collect(Collectors.toList());
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>()
                .in(User::getId, userIdList)
                .eq(User::getMark, MarkEnum.VALID.getCode()));
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        return userMap;
    }

    /**
     * 获取路段列表，放到map，减少循环次数
     *
     * @param iotEquipmentList
     * @return
     */
    private Map<String, Section> getSectionMap(List<IotEquipment> iotEquipmentList) {
        List<String> sectionIdList = iotEquipmentList.stream().map(o -> o.getSectionId()).collect(Collectors.toList());
        List<Section> sectionList = sectionMapper.selectList(new LambdaQueryWrapper<Section>()
                .in(Section::getId, sectionIdList)
                .eq(Section::getMark, MarkEnum.VALID.getCode()));
        Map<String, Section> sectionMap = sectionList.stream().collect(Collectors.toMap(Section::getId, Function.identity()));
        return sectionMap;
    }

    /**
     * 设置列表中每一个的部门名称
     * 查询到的列表中的部门Id，作为部门id列表，查询所有的部门，该结果数据量不会太大，放到map中
     *
     * @param iotEquipmentList
     * @return
     */
    private Map<String, Dept> getDeptMap(List<IotEquipment> iotEquipmentList) {
        if (CollectionUtil.isEmpty(iotEquipmentList)) {
            return null;
        }
        List<String> deptIdList = iotEquipmentList.stream().map(o -> o.getDeptId()).collect(Collectors.toList());
        List<Dept> deptList = deptMapper.selectListByIdList(deptIdList);
        if (CollectionUtil.isEmpty(deptList)) {
            return null;
        }
        Map<String, Dept> deptMap = deptList.stream().collect(Collectors.toMap(Dept::getId, Function.identity()));
        return deptMap;
    }

    /**
     * 获取公路列表，放到map，减少循环次数
     *
     * @param iotEquipmentList
     * @return
     */
    private Map<String, RoadInformation> getRoadInformationMap(List<IotEquipment> iotEquipmentList) {
        List<String> roadInformationIdList = iotEquipmentList.stream().map(o -> o.getRoadId()).collect(Collectors.toList());
        List<RoadInformation> roadInformationList = roadInformationMapper.selectList(new LambdaQueryWrapper<RoadInformation>()
                .in(RoadInformation::getId, roadInformationIdList)
                .eq(RoadInformation::getMark, MarkEnum.VALID.getCode()));
        Map<String, RoadInformation> roadInformationMap = roadInformationList.stream().collect(Collectors.toMap(RoadInformation::getId, Function.identity()));
        return roadInformationMap;
    }

}
