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.query.QueryWrapper;
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.Question;
import com.tuoheng.admin.entity.domain.QuestionHandle;
import com.tuoheng.admin.entity.domain.WorkOrder;
import com.tuoheng.admin.entity.domain.WorkOrderQuestion;
import com.tuoheng.admin.entity.request.WorkOrderHandleRequest;
import com.tuoheng.admin.entity.request.WorkOrderQuestionRequest;
import com.tuoheng.admin.entity.request.WorkOrderRequest;
import com.tuoheng.admin.entity.vo.QuestionDetailVO;
import com.tuoheng.admin.entity.vo.WorkOrderQuestionVO;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.WorkOrderStatusEnum;
import com.tuoheng.admin.mapper.QuestionHandleMapper;
import com.tuoheng.admin.mapper.QuestionMapper;
import com.tuoheng.admin.mapper.WorkOrderMapper;
import com.tuoheng.admin.mapper.WorkOrderQuestionMapper;
import com.tuoheng.admin.service.IWorkOrderService;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.config.CommonConfig;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.DateUtils;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.entity.User;
import com.tuoheng.system.mapper.UserMapper;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkOrder> implements IWorkOrderService {

    @Autowired
    private WorkOrderMapper workOrderMapper;

    @Autowired
    private WorkOrderQuestionMapper workOrderQuestionMapper;

    @Autowired
    private QuestionHandleMapper questionHandleMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public JsonResult queryPage(WorkOrderRequest request) {
        if(null == request.getPage() || null == request.getLimit()){
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }

        Date startDate = null;
        Date endDate = null;
        if(StringUtils.isNotEmpty(request.getCreateStartTime()) && StringUtils.isNotEmpty(request.getCreateEndTime())){
            String startTime = request.getCreateStartTime() + " 00:00:00";
            String endTime = request.getCreateEndTime() + " 23:59:59";
            startDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime);
            endDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime);
        }
        // 获取分页数据
        IPage<WorkOrder> page = new Page<>(request.getPage(), request.getLimit());
        IPage<WorkOrder> pageData = workOrderMapper.selectPage(page, new LambdaQueryWrapper<WorkOrder>()
                .eq(WorkOrder::getTenantId, ShiroUtils.getTenantId())//xz
                .like(StringUtils.isNotEmpty(request.getCode()), WorkOrder::getCode, request.getCode())
                .eq(ObjectUtil.isNotEmpty(request.getStatus()), WorkOrder::getStatus, request.getStatus())
                .between(ObjectUtil.isNotNull(startDate),WorkOrder::getCreateTime, startDate, endDate)
                .apply((null != request.getHandleFlag() && 1 == request.getHandleFlag()),"FIND_IN_SET(" + ShiroUtils.getUserId()+",assign_user)")
                .eq(WorkOrder::getMark, MarkTypeEnum.VALID.getCode())
                .orderByDesc(WorkOrder::getCreateTime));

        pageData.getRecords().stream().map(vo -> {

            //查询问题总数
            Integer questionTotal = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
                    .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                    .eq(WorkOrderQuestion::getWorkOrderId, vo.getId()));
            vo.setQuestionTotal(questionTotal);

            //查询未处理问题数
            Integer unhandledTotal = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
                    .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                    .eq(WorkOrderQuestion::getWorkOrderId, vo.getId())
                    .eq(WorkOrderQuestion::getStatus, 0));
            vo.setUnhandledTotal(unhandledTotal);

            //处理人员名称
            if (StringUtils.isNotEmpty(vo.getAssignUser())) {
                List<String> assignUser = Arrays.asList(vo.getAssignUser().split(","));
                List<Integer> assignUserInteger = assignUser.stream().map(Integer::parseInt).collect(Collectors.toList());
                List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getId, assignUserInteger));
                List<String> assignUserNameList = userList.stream().map(User::getRealname).collect(Collectors.toList());
                vo.setAssignUserName(String.join(",", assignUserNameList));
            }

            return vo;
        }).collect(Collectors.toList());
        return JsonResult.success(pageData);

    }

    @Override
    @Transactional
    public JsonResult generate(Integer[] ids) {
        Integer questionId = ids[0];
        Question question = questionMapper.selectById(questionId);
        //校验，已生成工单的问题，无法生成工单
        Integer count = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
                .in(WorkOrderQuestion::getQuestionId, ids));
        if(count > 0){
            return JsonResult.error("有问题已生成工单");
        }

        String code = DateUtils.generateCode("XJGD");

        WorkOrder workOrder = new WorkOrder();
        workOrder.setCode(code);
        workOrder.setTenantId(question.getTenantId());//xz
        workOrderMapper.insert(workOrder);

        for (Integer id : ids) {

            WorkOrderQuestion workOrderQuestion = new WorkOrderQuestion();
            workOrderQuestion.setWorkOrderId(workOrder.getId());
            workOrderQuestion.setQuestionId(id);
            workOrderQuestion.setTenantId(question.getTenantId());//xz
            workOrderQuestionMapper.insert(workOrderQuestion);
        }
        return JsonResult.success();
    }

    @Override
    public JsonResult assign(WorkOrderRequest request) {
        WorkOrder workOrder = new WorkOrder();
        workOrder.setId(request.getId());
        workOrder.setStatus(WorkOrderStatusEnum.ALLOCATED.getCode());
        workOrder.setAssignUser(StringUtils.join(request.getHandleUserList(), ","));
        workOrder.setAssignTime(new Date());
        workOrderMapper.updateById(workOrder);
        return JsonResult.success();
    }

    @Override
    @Transactional
    public JsonResult handle(WorkOrderHandleRequest request) {
        //校验，已处理的问题，无法再处理
        Integer handleCount = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
                .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(WorkOrderQuestion::getQuestionId, request.getQuestionId())
                .eq(WorkOrderQuestion::getStatus, 1)
                .eq(WorkOrderQuestion::getMark, MarkTypeEnum.VALID.getCode()));
        if(handleCount > 0){
            return JsonResult.error("问题已经处理，无法再处理");
        }

        //将工单子表状态修改为已处理
        WorkOrderQuestion workOrderQuestion = new WorkOrderQuestion();
        BeanUtils.copyProperties(request, workOrderQuestion);
        workOrderQuestion.setStatus(1);
        workOrderQuestionMapper.update(workOrderQuestion, new LambdaQueryWrapper<WorkOrderQuestion>()
//                .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(WorkOrderQuestion::getWorkOrderId, request.getWorkOrderId())
                .eq(WorkOrderQuestion::getQuestionId, request.getQuestionId()));

        //问题处理结果表新增
        QuestionHandle questionHandle = new QuestionHandle();
        BeanUtils.copyProperties(request, questionHandle);
        questionHandle.setHandlerUser(ShiroUtils.getUserId());
        questionHandle.setHandlerTime(new Date());
        questionHandle.setTenantId(ShiroUtils.getTenantId());//xz
        questionHandleMapper.insert(questionHandle);

        //查询工单下待处理的问题，如全部处理完，将工单状态修改为已完成
        Integer count = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
                        .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(WorkOrderQuestion::getWorkOrderId, request.getWorkOrderId())
                .eq(WorkOrderQuestion::getStatus, 0));
        if(count == 0){
            WorkOrder workOrder = new WorkOrder();
            workOrder.setId(request.getWorkOrderId());
            workOrder.setStatus(WorkOrderStatusEnum.COMPLETED.getCode());
            workOrder.setFinishTime(new Date());
            workOrderMapper.updateById(workOrder);
        }
        return JsonResult.success();
    }

    @Override
    public JsonResult questionPage(WorkOrderQuestionRequest request) {

        // 设置分页参数
        IPage<WorkOrderQuestionVO> page = new Page<>(request.getPage(), request.getLimit());
        // 查询结果
        int tenantId = ShiroUtils.getTenantId();
        IPage<WorkOrderQuestionVO> pageInfo = workOrderMapper.questionPage(page, request, tenantId);
        for (WorkOrderQuestionVO record : pageInfo.getRecords()) {
            if(StringUtils.isNotEmpty(record.getHandlerImage())){
                String[] imgHanders = record.getHandlerImage().split(",");
                for (int i = 0; i < imgHanders.length; i++) {
                    imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
                }
                String handerImg = StringUtils.join(imgHanders, ",");
                record.setHandlerImage(handerImg);
            }
        }
        return JsonResult.success(pageInfo);
    }

    @Override
    public JsonResult questionDetail(Integer questionId) {
        QuestionDetailVO questionDetailVO = new QuestionDetailVO();
        //查询问题详情
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();//xz
        queryWrapper.lambda().eq(Question::getTenantId, ShiroUtils.getTenantId()).eq(Question::getId, questionId);//xz
        Question question = questionMapper.selectOne(queryWrapper);//xz
        questionDetailVO.setQuestion(question);

        //查询问题处理详情
        QuestionHandle questionHandle = questionHandleMapper.selectOne(new LambdaQueryWrapper<QuestionHandle>()
                .eq(QuestionHandle::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(QuestionHandle::getQuestionId, questionId)
                .eq(QuestionHandle::getMark, MarkTypeEnum.VALID.getCode()));
        //拼接图片域名
        if(null != questionHandle && StringUtils.isNotEmpty(questionHandle.getHandlerImage())){
            String[] imgHanders = questionHandle.getHandlerImage().split(",");
            for (int i = 0; i < imgHanders.length; i++) {
                imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
            }
            String handerImg = StringUtils.join(imgHanders, ",");
            questionHandle.setHandlerImage(handerImg);
        }

        //查询处理人名称
        User user = userMapper.selectById(questionHandle.getHandlerUser());
        if(ObjectUtil.isNotNull(user)){
            questionHandle.setHandlerUserName(user.getRealname());
        }

        //查询问题处理状态
        WorkOrderQuestion workOrderQuestion = workOrderQuestionMapper.selectOne(new LambdaQueryWrapper<WorkOrderQuestion>()
                .eq(WorkOrderQuestion::getTenantId, ShiroUtils.getTenantId())//xz
                .eq(WorkOrderQuestion::getQuestionId, questionId));
        questionDetailVO.setQuestionHandle(questionHandle);
        questionHandle.setStatus(workOrderQuestion.getStatus());

        questionDetailVO.setQuestionHandle(questionHandle);
        return JsonResult.success(questionDetailVO);
    }


}
