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

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.DataPermissionEnum;
import com.tuoheng.admin.enums.InspectionTaskTypeEnum;
import com.tuoheng.admin.enums.InspectionTypeEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.enums.code.dept.QueryDeptInfoCodeEnum;
import com.tuoheng.admin.enums.code.user.QueryUserInfoByIdCodeEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.admin.vo.InspectionInfoVo;
import com.tuoheng.admin.vo.inspection.InspectionCardVo;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.enums.ServiceExceptionEnum;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

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

/**
 * @Author ChengWang
 * @Date 2023/4/14
 */
@Service
@Slf4j
public class QueryInspectionCardListService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private DspServiceInstMapper dspServiceInstMapper;

    @Autowired
    private LiveChannelMapper liveChannelMapper;

    @Autowired
    private AccidentInspectionMapper accidentInspectionMapper;

    @Autowired
    private AccidentMapper accidentMapper;

    /**
     * 获取任务列表
     * @return
     */
    public JsonResult getInspectionCardList() {
        //根据当前登录用户获取数据权限信息
        String userId = CurrentUserUtil.getUserId();
        if(StringUtils.isEmpty(userId)){
            return JsonResult.error(QueryUserInfoByIdCodeEnum.USER_ID_IS_NULL.getCode()
                    ,QueryUserInfoByIdCodeEnum.USER_ID_IS_NULL.getMsg());
        }
        String tenantId = CurrentUserUtil.getTenantId();
        if(StringUtils.isEmpty(tenantId)){
            return JsonResult.error(QueryUserInfoByIdCodeEnum.USER_TENANT_ID_NULL.getCode()
                    ,QueryUserInfoByIdCodeEnum.USER_TENANT_ID_NULL.getMsg());
        }
        Tenant tenant = tenantMapper.selectById(tenantId);
        User user = userMapper.selectById(userId);
        if(ObjectUtil.isNull(user)){
            return JsonResult.error(QueryUserInfoByIdCodeEnum.USER_IS_NOT_EXIST.getCode(),
                    QueryUserInfoByIdCodeEnum.USER_IS_NOT_EXIST.getMsg());
        }
        //部门
        Dept dept = deptMapper.selectById(user.getDeptId());
        if(ObjectUtil.isNull(dept)){
            return JsonResult.error(QueryUserInfoByIdCodeEnum.USER_DEPT_NOT_EXIST.getCode(),
                    QueryUserInfoByIdCodeEnum.USER_DEPT_NOT_EXIST.getMsg());
        }
        //根据用户查询对应的数据权限
        Integer dataPermission = user.getDataPermission();
        List<InspectionCardVo> dataResult = new ArrayList<>();
        if(DataPermissionEnum.ALL.getCode() == dataPermission){
            dataResult = this.getAllInspectionList(tenant);
        }else if(DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == dataPermission){
            dataResult = this.getInspectionListByDept(tenant,dept);
        }else if(DataPermissionEnum.DEPT.getCode() == dataPermission){
            dataResult = this.getInspectionListByMyDept(tenant,dept);
        }


        return JsonResult.success(dataResult);

    }

    /**
     * 获取全部任务
     * @return
     */
    private List<InspectionCardVo> getAllInspectionList(Tenant tenant) {
        String tenantId = tenant.getId();
        List<Inspection> inspectionList = inspectionMapper.selectList(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getTenantId, tenantId)
                .in(Inspection::getStatus, 5, 6, 10)
                .eq(Inspection::getMark, MarkEnum.VALID.getCode())
                .ne(Inspection::getInspectionType,3)
                .orderByDesc(Inspection::getCreateTime));
        JsonResult jsonResult = this.check(inspectionList);
        if(jsonResult.getCode() != 0){
            log.info("当前租户下对应的任务状态数据为空");
            return null;
        }
        //过滤掉关联的应急任务数据
        List<Inspection> list = new ArrayList<>();
        this.getInspectionList(inspectionList, list);
        //封装InspectionCardVo
        List<InspectionCardVo> resultList = list.stream().map(x -> {
            InspectionCardVo vo = new InspectionCardVo();
            BeanUtils.copyProperties(x, vo);
            //部门名称
            Dept dept = deptMapper.selectById(x.getDeptId());
            if (ObjectUtil.isNotNull(dept)) {
                vo.setDeptName(dept.getName());
            }
            //算法实例名称
            DspServiceInst dspServiceInst = dspServiceInstMapper.selectById(x.getDspServiceInstId());
            if (ObjectUtil.isNotNull(dspServiceInst)) {
                vo.setDspServiceName(dspServiceInst.getName());
            }
            //直播视频url
            LiveChannel liveChannel = liveChannelMapper.selectOne(Wrappers.<LiveChannel>lambdaQuery()
                    .eq(LiveChannel::getInspectionId, x.getId())
                    .eq(LiveChannel::getMark, MarkEnum.VALID.getCode()));
            if (ObjectUtil.isNotNull(liveChannel)) {
                vo.setAipullUrl(liveChannel.getAipullUrl());
            }
            //回放视频
            vo.setAiVideoUrl(CommonConfig.videoURL + x.getAiVideoUrl());
            //事故来源
            this.getAccidentSource(x, vo);
            return vo;
        }).collect(Collectors.toList());

        return resultList;
    }

    /**
     * 获取本部分及子部门任务
     * @return
     */
    private List<InspectionCardVo> getInspectionListByDept(Tenant tenant,Dept dept) {
        //获取本部门及子孙部门id列表
        List<String> deptIdList = deptMapper.selectAllChildListById(dept.getId());
        //查询该部门列表下对应的任务
        List<Inspection> inspectionList = new ArrayList<>();
        for (String deptId : deptIdList) {
            List<Inspection> list = inspectionMapper.selectList(Wrappers.<Inspection>lambdaQuery()
                    .eq(Inspection::getTenantId, tenant.getId())
                    .in(Inspection::getStatus, 5, 6, 10)
                    .eq(Inspection::getDeptId, deptId)
                    .eq(Inspection::getMark, MarkEnum.VALID.getCode())
                    .ne(Inspection::getInspectionType,3)
                    .orderByDesc(Inspection::getCreateTime));
           if(CollectionUtils.isNotEmpty(list)){
               list.stream().forEach(x-> inspectionList.add(x));
           }
        }

        JsonResult jsonResult = this.check(inspectionList);
        if(jsonResult.getCode() != 0){
            log.info("当前租户下对应的任务状态数据为空");
            return null;
        }
        //过滤掉关联的应急任务数据
        List<Inspection> list = new ArrayList<>();
        this.getInspectionList(inspectionList, list);
        //封装InspectionCardVo
        List<InspectionCardVo> resultList = list.stream().map(x -> {
            InspectionCardVo vo = new InspectionCardVo();
            BeanUtils.copyProperties(x, vo);
            //部门名称
            if(StringUtils.isNotEmpty(dept.getName())){
                vo.setDeptName(dept.getName());
            }
            //算法实例名称
            DspServiceInst dspServiceInst = dspServiceInstMapper.selectById(x.getDspServiceInstId());
            if (ObjectUtil.isNotNull(dspServiceInst)) {
                vo.setDspServiceName(dspServiceInst.getName());
            }
            //直播视频url
            LiveChannel liveChannel = liveChannelMapper.selectOne(Wrappers.<LiveChannel>lambdaQuery()
                    .eq(LiveChannel::getInspectionId, x.getId())
                    .eq(LiveChannel::getMark, MarkEnum.VALID.getCode()));
            if (ObjectUtil.isNotNull(liveChannel)) {
                vo.setAipullUrl(liveChannel.getAipullUrl());
            }
            //回放视频
            vo.setAiVideoUrl(CommonConfig.videoURL + x.getAiVideoUrl());
            //事故来源
            this.getAccidentSource(x, vo);
            return vo;
        }).collect(Collectors.toList());

        return resultList;
    }

    /**
     * 获取本部分任务
     * @return
     */
    private List<InspectionCardVo> getInspectionListByMyDept(Tenant tenant,Dept dept) {
        //部门id
        String deptId = dept.getId();
        if(StringUtils.isEmpty(deptId)){
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "部门id为空");
        }
        String tenantId = tenant.getId();
        List<Inspection> inspectionList = inspectionMapper.selectList(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getTenantId, tenantId)
                .eq(Inspection::getDeptId,deptId)
                .in(Inspection::getStatus, 5, 6, 10)
                .eq(Inspection::getMark, MarkEnum.VALID.getCode())
                .ne(Inspection::getInspectionType,3)
                .orderByDesc(Inspection::getCreateTime));
        //过滤掉关联的应急任务数据
        List<Inspection> list = new ArrayList<>();
        this.getInspectionList(inspectionList, list);
        //封装InspectionCardVo
        List<InspectionCardVo> resultList = list.stream().map(x -> {
            InspectionCardVo vo = new InspectionCardVo();
            BeanUtils.copyProperties(x, vo);
            //部门名称
            if(StringUtils.isNotEmpty(dept.getName())){
                vo.setDeptName(dept.getName());
            }
            //算法实例名称
            DspServiceInst dspServiceInst = dspServiceInstMapper.selectById(x.getDspServiceInstId());
            if (ObjectUtil.isNotNull(dspServiceInst)) {
                vo.setDspServiceName(dspServiceInst.getName());
            }
            //直播视频url
            LiveChannel liveChannel = liveChannelMapper.selectOne(Wrappers.<LiveChannel>lambdaQuery()
                    .eq(LiveChannel::getInspectionId, x.getId())
                    .eq(LiveChannel::getMark, MarkEnum.VALID.getCode()));
            if (ObjectUtil.isNotNull(liveChannel)) {
                vo.setAipullUrl(liveChannel.getAipullUrl());
            }
            //回放视频
            vo.setAiVideoUrl(CommonConfig.videoURL + x.getAiVideoUrl());
            //事故来源
            this.getAccidentSource(x, vo);
            return vo;
        }).collect(Collectors.toList());

        return resultList;
    }

    /**
     * 数据筛选
     * @param inspectionList
     * @param list
     */
    private void getInspectionList(List<Inspection> inspectionList, List<Inspection> list) {
        for (Inspection inspection : inspectionList) {
            if(StringUtils.isEmpty(inspection.getEmergencyDataInspectionId())){
                list.add(inspection);
            }
        }
    }

    /**
     * 应急任务对应的事故来源
     * @param x
     * @param vo
     */
    private void getAccidentSource(Inspection x, InspectionCardVo vo) {
        if(x.getType() == InspectionTaskTypeEnum.EMERGENCY_INSPECTION.getCode()){
            //创建的应急任务,查询对应的事故
            AccidentInspection accidentInspection = accidentInspectionMapper.selectOne(Wrappers.<AccidentInspection>lambdaQuery()
                    .eq(AccidentInspection::getInspectionId, x.getId())
                    .eq(AccidentInspection::getMark, MarkEnum.VALID.getCode()));
            if(ObjectUtil.isNull(accidentInspection)){
                throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
            }
            String accidentId = accidentInspection.getAccidentId();
            if(StringUtils.isNotEmpty(accidentId)){
                vo.setAccidentId(accidentId);
            }
            Accident accident = accidentMapper.selectOne(Wrappers.<Accident>lambdaQuery()
                    .eq(Accident::getId, accidentId)
                    .eq(Accident::getMark, MarkEnum.VALID.getCode()));
            if(ObjectUtil.isNotNull(accident)){
                if(accident.getSource() != null){
                    vo.setAccidentSource(accident.getSource());
                }
            }
        }
    }

    //数据校验
    private JsonResult check(List<Inspection> inspectionList) {
        //查询当前租户下的任务
        if(CollectionUtils.isEmpty(inspectionList) || inspectionList.size() == 0){
            return JsonResult.error();
        }
        return JsonResult.success();
    }


}
