package com.tuoheng.miniprogram.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.CommonUtils;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import com.tuoheng.miniprogram.dao.*;
import com.tuoheng.miniprogram.entity.*;
import com.tuoheng.miniprogram.entity.dto.QuestionIdentificationDto;
import com.tuoheng.miniprogram.entity.query.InspectionFileQuery;
import com.tuoheng.miniprogram.enums.InspectionFileEnum;
import com.tuoheng.miniprogram.enums.DataPermissionEnum;
import com.tuoheng.miniprogram.service.IInspectionFileService;
import com.tuoheng.miniprogram.utils.CurrentUserUtil;
import com.tuoheng.miniprogram.vo.InspectionFileCountVo;
import com.tuoheng.miniprogram.vo.InspectionFileInfoVo;
import com.tuoheng.miniprogram.vo.PlayBackInfoVo;
import com.tuoheng.miniprogram.vo.SeeQuestionVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author ChengWang
 * @Date 2022/11/23
 */
@Service
@Slf4j
public class InspectionFileServiceImpl implements IInspectionFileService {

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoadInformationMapper roadInformationMapper;

    @Autowired
    private QuestionTypeMapper questionTypeMapper;

    /**
     * 待确认问题 status状态为5
     *
     * @param query
     * @return
     */
    @Override
    public JsonResult unconfirmedQuestion(InspectionFileQuery query) {
        if (null == query.getLimit() && null == query.getPage()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        if (StringUtils.isEmpty(query.getInspectionId())) {
            return JsonResult.error("任务id为空");
        }
        //登录用户信息
        String tenantId = CurrentUserUtil.getTenantId();
        query.setTenantId(tenantId);
        //查询当前对应的任务
        Inspection inspection = inspectionMapper.selectOne(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getId, query.getInspectionId())
                .eq(Inspection::getTenantId,tenantId)
                .eq(Inspection::getMark, 1));
        if (ObjectUtil.isNull(inspection)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //设置分页
        IPage<InspectionFile> page = new Page<>(query.getPage(), query.getLimit());
        //获取分页数据
        IPage<InspectionFile> result = inspectionFileMapper.selectPage(page, Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getInspectionId, query.getInspectionId())
                .eq(InspectionFile::getMark, 1)
                .eq(InspectionFile::getStatus, 5)
                .orderByDesc(InspectionFile::getCheckTime));
        IPage<InspectionFileInfoVo> pageData = getInspectionFileInfoVoIPage(inspection, result);

        return JsonResult.success(pageData);
    }

    /**
     * 已确认问题 status状态为15
     *
     * @param query
     * @return
     */
    @Override
    public JsonResult confirmedQuestion(InspectionFileQuery query) {
        if (null == query.getLimit() && null == query.getPage()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        if (StringUtils.isEmpty(query.getInspectionId())) {
            return JsonResult.error("任务id为空");
        }
        //登录用户信息
        String tenantId = CurrentUserUtil.getTenantId();
        query.setTenantId(tenantId);
        //查询当前对应的任务
        Inspection inspection = inspectionMapper.selectOne(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getId, query.getInspectionId())
                .eq(Inspection::getTenantId,tenantId)
                .eq(Inspection::getMark, 1));
        if (ObjectUtil.isNull(inspection)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //设置分页
        IPage<InspectionFile> page = new Page<>(query.getPage(), query.getLimit());
        //获取分页数据
        IPage<InspectionFile> result = inspectionFileMapper.selectPage(page, Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getInspectionId, query.getInspectionId())
                .eq(InspectionFile::getMark, 1)
                .eq(InspectionFile::getStatus, 15)
                .orderByDesc(InspectionFile::getCheckTime));
        IPage<InspectionFileInfoVo> pageData = getInspectionFileInfoVoIPage(inspection, result);

        return JsonResult.success(pageData);

    }

    /**
     * 已忽略问题 status状态为10
     *
     * @param query
     * @return
     */
    @Override
    public JsonResult ignoredQuestion(InspectionFileQuery query) {
        if (null == query.getLimit() && null == query.getPage()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        if (StringUtils.isEmpty(query.getInspectionId())) {
            return JsonResult.error("任务id为空");
        }
        //登录用户信息
        String tenantId = CurrentUserUtil.getTenantId();
        query.setTenantId(tenantId);
        //查询当前对应的任务
        Inspection inspection = inspectionMapper.selectOne(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getId, query.getInspectionId())
                .eq(Inspection::getTenantId,tenantId)
                .eq(Inspection::getMark, 1));
        if (ObjectUtil.isNull(inspection)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //设置分页
        IPage<InspectionFile> page = new Page<>(query.getPage(), query.getLimit());
        //获取分页数据
        IPage<InspectionFile> result = inspectionFileMapper.selectPage(page, Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getInspectionId, query.getInspectionId())
                .eq(InspectionFile::getMark, 1)
                .eq(InspectionFile::getStatus, 10)
                .orderByDesc(InspectionFile::getCheckTime));
        IPage<InspectionFileInfoVo> pageData = getInspectionFileInfoVoIPage(inspection, result);

        return JsonResult.success(pageData);

    }

    /**
     * 问题标识
     *
     * @param dto
     * @return
     */
    @Override
    public JsonResult questionIdentification(QuestionIdentificationDto dto) {
        if (StringUtils.isEmpty(dto.getId())) return JsonResult.error("问题id不存在");
        //获取当前登录用户的租户id
        String tenantId = CurrentUserUtil.getTenantId();
        //查询任务此问题
        InspectionFile inspectionFile = inspectionFileMapper.selectOne(Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getId, dto.getId())
                .eq(InspectionFile::getMark, 1)
                .eq(StringUtils.isNotEmpty(dto.getTenantId()), InspectionFile::getTenantId, tenantId));
        //修改对应的问题类型和code及questionName
        inspectionFile.setQuestionId(dto.getQuestionId());
        QuestionType questionType = questionTypeMapper.selectById(dto.getQuestionId());
        if(ObjectUtil.isNotNull(questionType)){
            inspectionFile.setQuestionCode(questionType.getCode());
            inspectionFile.setQuestionName(questionType.getContent());
        }

        int count = inspectionFileMapper.updateById(inspectionFile);
        if (count <= 0) {
            return JsonResult.error();
        }
        //设置图片添加域名
        if (StringUtils.isNotEmpty(inspectionFile.getFileThumbnail())) {
            inspectionFile.setFileThumbnail(CommonConfig.imageURL + inspectionFile.getFileThumbnail());
        }
        if (StringUtils.isNotEmpty(inspectionFile.getFileOriginal())) {
            inspectionFile.setFileOriginal(CommonConfig.imageURL + inspectionFile.getFileOriginal());
        }
        if (StringUtils.isNotEmpty(inspectionFile.getFileImage())) {
            inspectionFile.setFileImage(CommonConfig.imageURL + inspectionFile.getFileImage());
        }


        return JsonResult.success(inspectionFile);
    }

    /**
     * 确认问题
     *
     * @param entity
     * @return
     */
    @Override
    public JsonResult confirm(InspectionFile entity) {
        if (StringUtils.isEmpty(entity.getId())) {
            return JsonResult.error("问题id为空");
        }

        //查询当前问题
        LambdaUpdateWrapper<InspectionFile> qw = new LambdaUpdateWrapper<>();
        qw.eq(InspectionFile::getId, entity.getId());
        qw.eq(InspectionFile::getMark, 1);
        qw.set(InspectionFile::getStatus, 15);
        qw.set(InspectionFile::getCheckUser, CurrentUserUtil.getUserId());
        qw.set(InspectionFile::getCheckTime, DateUtils.now());
        int count = inspectionFileMapper.update(entity, qw);
        if (count <= 0) {
            return JsonResult.error();
        }
        return JsonResult.success("确认问题成功");
    }

    /**
     * 忽略问题
     *
     * @param entity
     * @return
     */
    @Override
    public JsonResult ignore(InspectionFile entity) {
        if (null == entity.getId()) {
            return JsonResult.error("问题id为空");
        }
        //查询当前问题
        LambdaUpdateWrapper<InspectionFile> qw = new LambdaUpdateWrapper<>();
        qw.eq(InspectionFile::getId, entity.getId());
        qw.eq(InspectionFile::getMark, 1);
        qw.set(InspectionFile::getStatus, 10);
        int count = inspectionFileMapper.update(entity, qw);
        if (count <= 0) {
            return JsonResult.error();
        }
        return JsonResult.success("忽略问题成功");
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public JsonResult seeQuestion(String id) {
        //校验
        if (StringUtils.isEmpty(id)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        SeeQuestionVo vo = inspectionFileMapper.selectByInspectionId(id);
        if (ObjectUtil.isNull(vo)) {
            return JsonResult.error("未查询出对应的问题及处理结果");
        }
        //对属性处理
        if (StringUtils.isNotEmpty(vo.getFileImage())) {
            vo.setFileImage(CommonConfig.imageURL + vo.getFileImage());
        }
        if (StringUtils.isNotEmpty(vo.getFileThumbnail())) {
            vo.setFileThumbnail(CommonConfig.imageURL + vo.getFileThumbnail());
        }
        if (StringUtils.isNotEmpty(vo.getFileOriginal())) {
            vo.setFileOriginal(CommonConfig.imageURL + vo.getFileOriginal());
        }
        //对多张处理结果图进行处理用,隔开
        if (StringUtils.isNotEmpty(vo.getHandlerImage())) {
            String getHandlerImage = getMultipleUrl(vo.getHandlerImage());
            vo.setHandlerImage(getHandlerImage);
        }
        //处理人员返回realname
        String handleUserId = vo.getHandlerUser();
        if(StringUtils.isNotEmpty(handleUserId)){
            User user = userMapper.selectById(handleUserId);
            vo.setHandlerUser(user.getRealname());
        }


        return JsonResult.success(vo);
    }

    /**
     * 导航
     *
     * @param id
     * @return
     */
    @Override
    public JsonResult navigation(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        InspectionFile inspectionFile = inspectionFileMapper.selectOne(Wrappers.<InspectionFile>lambdaQuery()
                .eq(InspectionFile::getMark, 1)
                .eq(InspectionFile::getId, id));
        return JsonResult.success(inspectionFile);
    }

    /**
     * 问题处理统计
     *
     * @return
     */
    @Override
    public JsonResult handleCount() {
        //登录用户信息
        User userInfo = CurrentUserUtil.getUserInfo();
        String username = userInfo.getUsername();
        if (StringUtils.isEmpty(username)) {
            return JsonResult.error(InspectionFileEnum.USER_NAME_IS_NULL.getCode(), InspectionFileEnum.USER_NAME_IS_NULL.getMsg());
        }
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getMark, 1)
                .eq(User::getUsername, username));
        if (ObjectUtil.isNull(user)) {
            return JsonResult.error(InspectionFileEnum.USER_IS_NOT_EXIST.getCode(), InspectionFileEnum.USER_IS_NOT_EXIST.getMsg());
        }
        if (StringUtils.isEmpty(user.getId())) {
            return JsonResult.error(InspectionFileEnum.USER_ID_IS_NULL.getCode(), InspectionFileEnum.USER_ID_IS_NULL.getMsg());
        }
        if (null == user.getDataPermission()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //获取当前租户id
        String tenantId = CurrentUserUtil.getTenantId();
        if(StringUtils.isEmpty(tenantId)){
            return JsonResult.error(InspectionFileEnum.TENANT_ID_IS_NULL.getCode(),InspectionFileEnum.TENANT_ID_IS_NULL.getMsg());
        }

        //今日
        DateTime endTime = DateUtil.endOfDay(DateUtil.date());
        //一周前的时间
        DateTime startTime = DateUtil.offset(DateUtil.beginOfDay(DateUtil.date()), DateField.DAY_OF_WEEK, -4);
        List<InspectionFileCountVo> result = new ArrayList<>();
        //判断角色 1超级管理员 2部门管理员 3普通用户
        if (DataPermissionEnum.ALL.getCode() == user.getDataPermission()) {
            try {
                List<String> list = findDates(startTime, endTime);
                for (String s : list) {
                    InspectionFileCountVo vo = new InspectionFileCountVo();
                    vo.setCheckTime(s);
                    //查询当日登录用户的已处理问题总数,创建时间
                    Integer num = inspectionFileMapper.getInspectionFileHandleCount(s, tenantId);
                    if (null != num) {
                        vo.setInspectionHandleSum(num);
                    }
                    result.add(vo);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if (DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == user.getDataPermission() || DataPermissionEnum.DEPT.getCode() == user.getDataPermission()) {
            try {
                List<String> list = findDates(startTime, endTime);
                for (String s : list) {
                    InspectionFileCountVo vo = new InspectionFileCountVo();
                    vo.setCheckTime(s);
                    //查询当日登录用户的已处理问题总数,创建时间
                    Integer num = inspectionFileMapper.getInspectionFileCount(s, user.getId());
                    if (null != num) {
                        vo.setInspectionHandleSum(num);
                    }
                    result.add(vo);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }


        return JsonResult.success(result);
    }

    /**
     * 观看回放
     *
     * @param id
     * @return
     */
    @Override
    public JsonResult playback(String id) {
        //校验
        if (StringUtils.isEmpty(id)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //获取租户id
        String tenantId = CurrentUserUtil.getTenantId();
        if(StringUtils.isEmpty(tenantId)){
            return JsonResult.error("租户id为空");
        }
        //根据问题id查询对应的任务
        InspectionFile inspectionFile = inspectionFileMapper.selectById(id);
        if (ObjectUtil.isNull(inspectionFile)) {
            return JsonResult.error(InspectionFileEnum.DATA_IS_NULL.getCode(), InspectionFileEnum.DATA_IS_NULL.getMsg());
        }
        //获取对应的任务id
        String inspectionId = inspectionFile.getInspectionId();
        if (StringUtils.isEmpty(inspectionId)) {
            return JsonResult.error(InspectionFileEnum.INSPECTION_ID_NULL.getCode(), InspectionFileEnum.INSPECTION_ID_NULL.getMsg());
        }
        //根据任务id获取任务
        Inspection inspection = inspectionMapper.selectOne(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getTenantId, tenantId)
                .eq(Inspection::getMark, 1)
                .eq(Inspection::getId, inspectionId));
        PlayBackInfoVo vo = new PlayBackInfoVo();
        BeanUtils.copyProperties(inspection, vo);
        //对视频地址进行处理
        if (StringUtils.isNotEmpty(inspection.getAiVideoUrl())) {
            vo.setAiVideoUrl(CommonConfig.videoURL + inspection.getAiVideoUrl());
        }

        return JsonResult.success(vo);


    }

    /**
     * 多个url进行转换,用,号隔开
     *
     * @param url
     * @return
     */
    private String getMultipleUrl(String url) {

        List<String> collect = Arrays.asList(url.split(",")).stream().map(
                s -> CommonUtils.getImageURL(s)).collect(Collectors.toList());
        //返回
        return org.apache.commons.lang3.StringUtils.join(collect, ",");
    }

    private IPage<InspectionFileInfoVo> getInspectionFileInfoVoIPage(Inspection inspection, IPage<InspectionFile> result) {
        //数据转换
        return result.convert(t -> {
            InspectionFileInfoVo vo = Convert.convert(InspectionFileInfoVo.class, t);
            // 查询其他属性
            // 公路代号
            RoadInformation roadInformation = roadInformationMapper.selectOne(Wrappers.<RoadInformation>lambdaQuery()
                    .eq(RoadInformation::getId, inspection.getRoadId()));
            if (ObjectUtil.isNotNull(roadInformation)) {
                vo.setCode(roadInformation.getCode());
            }
            // 任务名称
            if (StringUtils.isNotEmpty(inspection.getName())) {
                vo.setName(inspection.getName());
            }
            // 任务时间
            if (null != inspection.getExecutionStartTime()) {
                vo.setExecutionStartTime(inspection.getExecutionStartTime());
            }
            // 缩略图
            if (StringUtils.isNotEmpty(t.getFileThumbnail())) {
                vo.setFileThumbnail(CommonConfig.imageURL + t.getFileThumbnail());
            }
            // 原图
            if (StringUtils.isNotEmpty(t.getFileOriginal())) {
                vo.setFileOriginal(CommonConfig.imageURL + t.getFileOriginal());
            }
            //标记图
            if(StringUtils.isNotEmpty(t.getFileImage())){
                vo.setFileImage(CommonConfig.imageURL + t.getFileImage());
            }
            // 问题类型
            if (StringUtils.isNotEmpty(t.getQuestionId())) {
                QuestionType questionType = questionTypeMapper.selectOne(Wrappers.<QuestionType>lambdaQuery()
                        .eq(QuestionType::getId, t.getQuestionId())
                        .eq(QuestionType::getMark, 1));
                if (null == questionType) {
                    throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
                }
                if (null != questionType.getName()) {
                    vo.setQuestionName(questionType.getContent());
                }
                if (StringUtils.isNotEmpty(questionType.getContent())) {
                    vo.setContent(questionType.getContent());
                }
                if(StringUtils.isNotEmpty(questionType.getCode())){
                    vo.setQuestionCode(questionType.getCode());
                }
            }

            return vo;
        });
    }


    /**
     * 传入两个时间范围，返回这两个时间范围内的所有时间，并保存在一个集合中
     *
     * @param beginTime
     * @param endTime
     * @return
     * @throws ParseException
     */
    public static List<String> findDates(Date beginTime, Date endTime)
            throws ParseException {
        List<String> allDate = new ArrayList();
        allDate.add(DateUtil.formatDate(beginTime));
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(beginTime);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(endTime);
        // 测试此日期是否在指定日期之后
        while (endTime.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            allDate.add(DateUtil.formatDate(calBegin.getTime()));
        }
        allDate.remove(allDate.size() - 1);
        return allDate;
    }

}
