package com.tuoheng.admin.service.cycle.query.list;

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.InspectionCycleConverMapper;
import com.tuoheng.admin.entity.Dept;
import com.tuoheng.admin.entity.Inspection;
import com.tuoheng.admin.entity.InspectionCycle;
import com.tuoheng.admin.entity.User;
import com.tuoheng.admin.enums.DataPermissionEnum;
import com.tuoheng.admin.enums.InspectionStatusEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.DeptMapper;
import com.tuoheng.admin.mapper.InspectionCycleMapper;
import com.tuoheng.admin.mapper.InspectionMapper;
import com.tuoheng.admin.mapper.UserMapper;
import com.tuoheng.admin.request.cycle.QueryInspectionCyclePageListRequest;
import com.tuoheng.admin.service.third.airport.AirportService;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.admin.vo.AirportInfoVo;
import com.tuoheng.admin.vo.AirportLineVo;
import com.tuoheng.admin.vo.cycle.InspectionCycleVo;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 查询周期任务分页列表业务层处理
 *
 * @author wanjing
 * @team tuoheng
 * @date 2023-08-25
 */
@Slf4j
@Service
public class QueryInspectionCyclePageListService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private InspectionCycleMapper inspectionCycleMapper;

    @Autowired
    private AirportService airportService;

    public JsonResult getPageList(QueryInspectionCyclePageListRequest request) {
//        log.info("进入查询周期任务分页列表业务");
        User user = CurrentUserUtil.getUserInfo();
        String tenantId = user.getTenantId();
        JsonResult result = this.check(tenantId, request);
        if (0 != result.getCode()) {
            log.info("进入查询周期任务分页列表业务：校验失败：{}", result.getMsg());
            return result;
        }
        List<String> deptIdList = new ArrayList<>();
        if (DataPermissionEnum.ALL.getCode() == user.getDataPermission()) {
        } 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());
        }

        request.setTenantId(tenantId);
        request.setDeptIdList(deptIdList);

        // 设置分页参数
        IPage<Inspection> page = new Page<>(request.getPage(), request.getLimit());
        // 查询结果
        IPage<InspectionCycle> pageData = inspectionCycleMapper.selectPageList(page, request);

        // 构造返回结果对象
        List<InspectionCycleVo> inspectionCycleVoList = this.buildInspectionCycleVoList(pageData.getRecords());

        // 重写返回结果对象
        IPage<InspectionCycleVo> inspectionCycleVoPageData = new Page<>();
        inspectionCycleVoPageData.setPages(pageData.getPages());
        inspectionCycleVoPageData.setCurrent(pageData.getCurrent());
        inspectionCycleVoPageData.setSize(pageData.getSize());
        inspectionCycleVoPageData.setTotal(pageData.getTotal());
        inspectionCycleVoPageData.setRecords(inspectionCycleVoList);

        return JsonResult.success(inspectionCycleVoPageData);
    }

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

    /**
     * @param inspectionCycleList
     * @return
     */
    private List<InspectionCycleVo> buildInspectionCycleVoList(List<InspectionCycle> inspectionCycleList) {
        Map<String, String> deptMap = this.getDeptMap(inspectionCycleList);
        Map<String, String> updateUsernameMap = this.getUpdateUsernameMap(inspectionCycleList);
        Map<String, AirportInfoVo> airportMap = this.getAirportMap(inspectionCycleList);
        Map<Integer, AirportLineVo> airportLineMap = this.getAirportLineMap(inspectionCycleList);
        List<InspectionCycleVo> inspectionCycleVoList = InspectionCycleConverMapper.INSTANCE.fromInspectionCycleListToInspectionCycleVoList(inspectionCycleList);
        String deptName;
        String updateUsername;
        Integer executCount;
        AirportInfoVo airportInfoVo;
        AirportLineVo airportLineVo;
        for (InspectionCycleVo inspectionCycleVo : inspectionCycleVoList) {
            if (ObjectUtil.isNotEmpty(deptMap)) {
                deptName = deptMap.get(inspectionCycleVo.getDeptId());
                if (StringUtils.isNotEmpty(deptName)) {
                    inspectionCycleVo.setDeptName(deptName);
                }
            }
            if (ObjectUtil.isNotEmpty(updateUsernameMap)) {
                updateUsername = updateUsernameMap.get(inspectionCycleVo.getUpdateUser());
                if (StringUtils.isNotEmpty(updateUsername)) {
                    inspectionCycleVo.setUpdateUsername(updateUsername);
                }
            }
            if (ObjectUtil.isNotEmpty(airportMap)) {
                airportInfoVo = airportMap.get(String.valueOf(inspectionCycleVo.getAirportId()));
                if (ObjectUtil.isNotEmpty(airportInfoVo)) {
                    inspectionCycleVo.setAirportName(airportInfoVo.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(airportLineMap)) {
                airportLineVo = airportLineMap.get(inspectionCycleVo.getAirportLineId());
                if (ObjectUtil.isNotEmpty(airportLineVo)) {
                    inspectionCycleVo.setAirportLineName(airportLineVo.getFileName());
                    inspectionCycleVo.setAirportLineFileUrl(airportLineVo.getFileUrl());
                }
            }
            executCount = inspectionMapper.selectCount(new LambdaQueryWrapper<Inspection>()
                    .eq(Inspection::getInspectionCycleId, inspectionCycleVo.getId())
                    .ne(Inspection::getStatus, InspectionStatusEnum.WAIT_FLIGHT.getCode())
                    .eq(Inspection::getMark, MarkEnum.VALID.getCode()));
            inspectionCycleVo.setExecutCount(executCount);

        }
        return inspectionCycleVoList;
    }

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

    private Map<String, String> getUpdateUsernameMap(List<InspectionCycle> inspectionCycleList) {
        if (CollectionUtil.isEmpty(inspectionCycleList)) {
            return null;
        }
        Map<String, String> map = new HashMap<>();
        List<String> updateUserList = inspectionCycleList.stream().map(o -> o.getUpdateUser()).collect(Collectors.toList());
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>()
                .in(User::getId, updateUserList)
                .eq(User::getMark, MarkEnum.VALID.getCode()));
        for (User user : userList) {
            map.put(user.getId(), user.getRealname());
        }
        return map;
    }

    private Map<String, AirportInfoVo> getAirportMap(List<InspectionCycle> inspectionCycleList) {
        if (CollectionUtil.isEmpty(inspectionCycleList)) {
            return null;
        }
        List<Integer> airportIdList = inspectionCycleList.stream().map(o -> o.getAirportId()).collect(Collectors.toList());
        String airportIds = airportIdList.stream().map(x -> String.valueOf(x)).collect(Collectors.joining(",", "", ""));
        List<AirportInfoVo> airportInfoVoList = airportService.getAirportInfoList(airportIds);
        if (CollectionUtil.isEmpty(airportInfoVoList)) {
            return null;
        }
        Map<String, AirportInfoVo> airportMap = airportInfoVoList.stream().collect(Collectors.toMap(AirportInfoVo::getId, Function.identity()));
        return airportMap;
    }

    private Map<Integer, AirportLineVo> getAirportLineMap(List<InspectionCycle> inspectionCycleList) {
        if (CollectionUtil.isEmpty(inspectionCycleList)) {
            return null;
        }
        List<Integer> airportLineIdList = inspectionCycleList.stream().map(o -> o.getAirportLineId()).collect(Collectors.toList());
        List<AirportLineVo> airportLineVoList = airportService.getAirportLineListByAirportIdAndLineIdList(null, airportLineIdList);
        if (CollectionUtil.isEmpty(airportLineVoList)) {
            return null;
        }
        Map<Integer, AirportLineVo> airportLineMap = airportLineVoList.stream().collect(Collectors.toMap(AirportLineVo::getId, Function.identity()));
        return airportLineMap;
    }
}
