package com.tuoheng.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.common.ServiceExceptionEnum;
import com.tuoheng.admin.entity.domain.*;
import com.tuoheng.admin.entity.request.*;
import com.tuoheng.admin.entity.vo.MissionVO;
import com.tuoheng.admin.entity.vo.QuestionCountVO;
import com.tuoheng.admin.entity.vo.QuestionTypeCountVO;
import com.tuoheng.admin.entity.vo.QuestionVO;
import com.tuoheng.admin.enums.*;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.service.IQuestionService;
import com.tuoheng.admin.service.IQuestionTypeService;
import com.tuoheng.admin.service.third.dsp.DspCallBackService;
import com.tuoheng.admin.service.warning.IWarningService;
import com.tuoheng.admin.service.warning.WarningServiceImpl;
import com.tuoheng.admin.utils.GaodeUtil;
import com.tuoheng.admin.utils.TimeUtil;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.utils.ShiroUtils;
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 org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 巡检问题表 服务实现类
 *
 * @author qiujinyang
 * @since 2022-08-03
 */
@Service
@Slf4j
public class QuestionServiceImpl extends BaseServiceImpl<QuestionMapper, Question> implements IQuestionService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionTypeMapper questionTypeMapper;

    @Autowired
    private ThMissionMapper missionMapper;

    @Autowired
    private ThInspectionMapper inspectionMapper;

    @Autowired
    private WorkOrderQuestionMapper workOrderQuestionMapper;

    @Autowired
    private IQuestionTypeService questionTypeService;

    @Autowired
    private DspCallBackService dspCallBackService;

    private final static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    @Transactional(readOnly = true)
    public IPage<QuestionVO> queryPage(QuestionQuery query) throws ParseException {
        if (null == query.getPage() || null == query.getLimit()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        // 获取分页数据
        IPage<Question> page = new Page<>(query.getPage(), query.getLimit());

        LambdaQueryWrapper<Question> questionLambdaQueryWrapper = new LambdaQueryWrapper<Question>()
                .eq(Question::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(ObjectUtil.isNotEmpty(query.getMissionId()), Question::getMissionId, query.getMissionId())
                .like(ObjectUtil.isNotEmpty(query.getName()), Question::getMissionName, query.getName())
                .eq(ObjectUtil.isNotEmpty(query.getType()), Question::getType, query.getType())
                .eq(ObjectUtil.isNotEmpty(query.getStatus()), Question::getStatus, query.getStatus())
                .eq(Question::getMark, MarkTypeEnum.VALID.getCode()).orderByDesc(Question::getCreateTime);
        if (ObjectUtil.isNotEmpty(query.getStartTime()) && ObjectUtil.isNotEmpty(query.getEndTime())) {
            query.setStartTime(query.getStartTime() + " 00:00:00");
            query.setEndTime(query.getEndTime() + " 23:59:59");
            questionLambdaQueryWrapper.between(Question::getCreateTime, dateformat.parse(query.getStartTime()), dateformat.parse(query.getEndTime()));
        }
        IPage<Question> pageData = questionMapper.selectPage(page, questionLambdaQueryWrapper);
        List<Question> questions = pageData.getRecords();
        List<QuestionVO> questionVOList = new ArrayList<>();
        questions.forEach(question -> {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question, questionVO);
            LambdaQueryWrapper<WorkOrderQuestion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(WorkOrderQuestion::getTenantId, question.getTenantId())//xz
                    .eq(WorkOrderQuestion::getQuestionId, question.getId());
            WorkOrderQuestion workOrderQuestion = workOrderQuestionMapper.selectOne(lambdaQueryWrapper);
            if (workOrderQuestion != null) {
                questionVO.setWordOrderStatus(1);
                questionVO.setHandleStatus(workOrderQuestion.getStatus());
            } else {
                questionVO.setWordOrderStatus(0);
                questionVO.setHandleStatus(0);
            }
            questionVOList.add(questionVO);
        });
        IPage<QuestionVO> resultPage = new Page<>();
        resultPage.setCurrent(pageData.getCurrent());
        resultPage.setPages(pageData.getPages());
        resultPage.setSize(pageData.getSize());
        resultPage.setTotal(pageData.getTotal());
        resultPage.setRecords(questionVOList);
        return resultPage;

    }

    @Override
    public List<Question> distributed(QuestionQuery query) {
        List<ThMission> thMissions = missionMapper.selectList(new LambdaQueryWrapper<ThMission>()
                        .eq(ThMission::getTenantId, ShiroUtils.getTenantId())
                        .eq(ThMission::getType, AccidentTaskEnum.INSPECTION_TASK.getCode())
                        .eq(ThMission::getMark, MarkTypeEnum.VALID.getCode())
                        .in(ThMission::getStatus, Arrays.asList(TaskStatusEnum.FLIGHT.getCode(), TaskStatusEnum.FAIL.getCode(), TaskStatusEnum.COMPLETE.getCode()))
                        .orderByDesc(ThMission::getUpdateTime));
        return this.getQuestions(query, thMissions);
    }

    private List<Question> getQuestions(QuestionQuery query, List<ThMission> thMissions) {
        if (thMissions.size() == 0) {
            return new ArrayList<>();
        }
        try {
            LambdaQueryWrapper<Question> questionLambdaQueryWrapper = new LambdaQueryWrapper<Question>()
                    .eq(ObjectUtil.isNotEmpty(query.getType()), Question::getType, query.getType())
                    .eq(Question::getStatus, QuestionStatusEnum.CONFIRM.getCode())
                    .eq(Question::getTenantId, ShiroUtils.getTenantId())//xz
                    .eq(Question::getMark, MarkTypeEnum.VALID.getCode()).orderByDesc(Question::getCreateTime);

            if (ObjectUtil.isNotEmpty(query.getStartTime()) && ObjectUtil.isNotEmpty(query.getEndTime())) {
                query.setStartTime(query.getStartTime() + " 00:00:00");
                query.setEndTime(query.getEndTime() + " 23:59:59");
                questionLambdaQueryWrapper.between(Question::getCreateTime, dateformat.parse(query.getStartTime()), dateformat.parse(query.getEndTime()));
            }

            if ((ObjectUtil.isNotEmpty(query.getStartTime()) && ObjectUtil.isNotEmpty(query.getEndTime()))
                    || StringUtils.isNotEmpty(query.getMissionName())) {
                questionLambdaQueryWrapper.like(StringUtils.isNotEmpty(query.getMissionName()), Question::getMissionName, query.getMissionName());
            } else {
                //只需要取最上面的那一条
                questionLambdaQueryWrapper.eq(Question::getMissionId, thMissions.get(0).getId());
            }
            return questionMapper.selectList(questionLambdaQueryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询出错！");
            return null;
        }
    }

    @Override
    public JsonResult<Boolean> check(QuestionStatusRequest entity) {
        //已经生成工单的问题无法修改
        for (Integer id : entity.getId()) {
            List<WorkOrderQuestion> workOrderQuestions = workOrderQuestionMapper.selectList(new LambdaQueryWrapper<WorkOrderQuestion>()
                            .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                            .eq(WorkOrderQuestion::getQuestionId, id));
            if (StringUtils.isNotEmpty(workOrderQuestions)) {
                return JsonResult.error("问题已生成工单，无法修改！");
            }
        }


        //根据ID的数量来判断是否是批量确认和忽略
        Question question = new Question(UpdateOrCreateEnum.UPDATE.getCode());
        question.setStatus(entity.getStatus());
        int update;
        Integer qId;
        if (entity.getId().length > 1) {
            qId = entity.getId()[0];
            //批量
            update = questionMapper.update(question, new LambdaUpdateWrapper<Question>().in(Question::getId, Arrays.asList(entity.getId())));
        } else {
            //查询巡检问题分类
            List<QuestionType> questionTypeList = questionTypeMapper.selectList(new LambdaQueryWrapper<QuestionType>()
                    .eq(QuestionType::getCode, entity.getType())
                    .eq(QuestionType::getMark, 1));
            if (StringUtils.isNotEmpty(questionTypeList)) {
                question.setQuestionName(questionTypeList.get(0).getContent());
                question.setQuestionDesc(questionTypeList.get(0).getContent());
            }
            //单个
            qId = entity.getId()[0];
            question.setId(qId);
            question.setType(entity.getType());
            update = questionMapper.updateById(question);
        }

        Integer missionId = questionMapper.selectById(qId).getMissionId();
        ThMission thMission = new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
        thMission.setReportStatus(ReportStatusEnum.UPDATE.getCode());
        thMission.setId(missionId);
        missionMapper.updateById(thMission);


        return JsonResult.success(update > 0);
    }

    @Override
    public JsonResult<List<QuestionCountVO>> analyze(Integer missionId) {
        List<QuestionCountVO> resultMap = questionMapper.analyze(missionId, ShiroUtils.getTenantId());
        return JsonResult.success(resultMap);
    }

    @Override
    public JsonResult<Map<String, Integer>> analyzeController(Integer missionId) {
        List<QuestionCountVO> questionCountVoList = questionMapper.analyze(missionId, ShiroUtils.getTenantId());
        Map<String, Integer> resultMap = new HashMap<>();
        for (QuestionCountVO questionCountVo : questionCountVoList) {
            setInfo(resultMap, questionCountVo, QuestionStatusEnum.CONFIRM.getCode(), QuestionStatusEnum.CONFIRM.name().toLowerCase());
            setInfo(resultMap, questionCountVo, QuestionStatusEnum.NEGLECT.getCode(), QuestionStatusEnum.NEGLECT.name().toLowerCase());
            setInfo(resultMap, questionCountVo, QuestionStatusEnum.NOTREVIEWED.getCode(), QuestionStatusEnum.NOTREVIEWED.name().toLowerCase());
        }
        int sum = 0;
        if (!resultMap.containsKey(QuestionStatusEnum.CONFIRM.name().toLowerCase())) {
            resultMap.put(QuestionStatusEnum.CONFIRM.name().toLowerCase(), 0);
        } else {
            sum += resultMap.get(QuestionStatusEnum.CONFIRM.name().toLowerCase());
        }

        if (!resultMap.containsKey(QuestionStatusEnum.NEGLECT.name().toLowerCase())) {
            resultMap.put(QuestionStatusEnum.NEGLECT.name().toLowerCase(), 0);
        } else {
            sum += resultMap.get(QuestionStatusEnum.NEGLECT.name().toLowerCase());
        }
        resultMap.remove(QuestionStatusEnum.NEGLECT.name().toLowerCase());
        resultMap.put(QuestionStatusEnum.CONFIRM.name().toLowerCase(), sum);

        if (!resultMap.containsKey(QuestionStatusEnum.NOTREVIEWED.name().toLowerCase())) {
            resultMap.put(QuestionStatusEnum.NOTREVIEWED.name().toLowerCase(), 0);
        }
        return JsonResult.success(resultMap);
    }

    private static void setInfo(Map<String, Integer> resultMap, QuestionCountVO questionCountVo, Integer code, String name) {
        if (questionCountVo.getStatus().equals(code)) {
            if (resultMap.containsKey(name)) {
                Integer current = resultMap.get(name);
                current = current + questionCountVo.getQuantity();
                resultMap.put(name, current);
            } else {
                resultMap.put(name, questionCountVo.getQuantity());
            }
        }
    }

    @Override
    public JsonResult<List<QuestionTypeCountVO>> analyzeType(Integer missionId) {
        List<QuestionTypeCountVO> questionTypeCountList = questionMapper.analyzeType
                (missionId, ShiroUtils.getTenantId());
        //添加问题的分类
        List<QuestionType> questionTypeList = new ArrayList<>();
        try {
            questionTypeList = questionTypeService.getQuestionType();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, String> codeMap = new HashMap<>();
        for (QuestionType questionType : questionTypeList) {
            codeMap.put(questionType.getCode(), questionType.getContent());
        }
        for (QuestionTypeCountVO questionTypeCountVO : questionTypeCountList) {
            questionTypeCountVO.setContent(codeMap.get(questionTypeCountVO.getType()));
        }
        return JsonResult.success(questionTypeCountList);
    }

    /**
     * DSP分析处理逻辑
     * @param requestId
     * @param callbackRequest
     * @return
     * @throws ServiceException
     */
    @Override
    public JsonResult process(String requestId, CallbackRequest callbackRequest) throws ServiceException {
        return dspCallBackService.process(requestId, callbackRequest);
    }

}
