package com.tuoheng.admin.service.workorder.generate;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.InspectionFileStatusEnum;
import com.tuoheng.admin.enums.DataPermissionEnum;
import com.tuoheng.admin.enums.WorkOrderStatusEnum;
import com.tuoheng.admin.enums.code.workorder.GenerateWorkorderCodeEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 生成工单业务层处理
 *
 * @author wanjing
 * @team tuoheng
 * @date 2022-12-07
 */
@Slf4j
@Service
public class GenerateWorkorderService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private InspectionMapper inspectionMapper;
    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    @Autowired
    private WorkOrderMapper workOrderMapper;

    @Autowired
    private WorkOrderFileMapper workOrderFileMapper;

    /**
     * 生成工单
     *  1)、判断参数
     *      1.1）、判断参数
     *      1.2）、判断权限
     *  2)、添加到工单表
     *  3)、添加到工单子表
     *  4)、修改任务问题状态，改为已生成工单
     *
     * @param idList
     * @return
     */
    @Transactional
    public JsonResult generate(List<String> idList) {
        log.info("进入生成工单业务， idList:{}", idList);
        String userId = CurrentUserUtil.getUserId();
        String tenantId = CurrentUserUtil.getTenantId();
        JsonResult result = this.check(idList);
        if (0 != result.getCode()) {
            log.info("进入生成工单业务：校验失败：{}", result.getMsg());
            return result;
        }
        List<InspectionFile> inspectionFileList = (List<InspectionFile>) result.getData();
        List<String> inspectionIdList = inspectionFileList.stream().map(o -> o.getInspectionId()).collect(Collectors.toList());
        List<Inspection> inspectionList = inspectionMapper.selectBatchIds(inspectionIdList);
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getTenantId, tenantId)
                .eq(User::getId, userId)
                .eq(User::getMark, 1));
        result = checkPermission(user, inspectionList);

        if (0 != result.getCode()) {
            log.info("进入生成工单务：校验权限失败：{}", result.getMsg());
            return result;
        }

        WorkOrder workOrder = this.insertWorkOrder(user);

        this.insertWorkOrderFile(workOrder, idList);

        this.updateInspectionFileStatus(userId, idList);

        return JsonResult.success();
    }

    /**
     * 检查参数
     *
     * @param idList
     * @return
     */
    private JsonResult check(List<String> idList) {
        // 判断任务问题id是否为空
        if (CollectionUtil.isEmpty(idList)) {
            return JsonResult.error(GenerateWorkorderCodeEnum.ID_LIST_IS_NULL.getCode(), GenerateWorkorderCodeEnum.ID_LIST_IS_NULL.getMsg());
        }
        List<InspectionFile> inspectionFileList = inspectionFileMapper.selectBatchIds(idList);
        if (CollectionUtil.isEmpty(inspectionFileList)) {
            return JsonResult.error(GenerateWorkorderCodeEnum.INSPECTION_FILE_ID_LIST_IS_NOT_EXIST.getCode(), GenerateWorkorderCodeEnum.INSPECTION_FILE_ID_LIST_IS_NOT_EXIST.getMsg());
        }
        for (InspectionFile inspectionFile : inspectionFileList) {
            if (inspectionFile.getStatus() != InspectionFileStatusEnum.CONFIRMED.getCode()) {
                return JsonResult.error(GenerateWorkorderCodeEnum.INCLUDE_NO_CONFIRMED_INSPECTION.getCode(), GenerateWorkorderCodeEnum.INCLUDE_NO_CONFIRMED_INSPECTION.getMsg());
            }
        }
        return JsonResult.success(inspectionFileList);
    }

    /**
     * 判断是否有生成工单权限
     * 1）、超级管理员可选择所有部门问题生成工单
     * 2）、部门管理员仅可生成本部门工单，无法生成子部门工单
     * 3）、普通用户无生成工单权限
     *
     * @param user
     * @param inspectionList
     * @return
     */
    private JsonResult checkPermission(User user, List<Inspection> inspectionList) {
        if (DataPermissionEnum.ALL.getCode() == user.getDataPermission()) {
            return JsonResult.success(user);
        } else if (DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == user.getDataPermission()) {
            for (Inspection inspection : inspectionList) {
                if (!user.getDeptId().equals(inspection.getDeptId())) {
                    return JsonResult.error(GenerateWorkorderCodeEnum.ADMIN_NOT_GENERATE_CHILD_WORKORDER.getCode(), GenerateWorkorderCodeEnum.ADMIN_NOT_GENERATE_CHILD_WORKORDER.getMsg());
                }
            }
            return JsonResult.success(user);
        } else if (DataPermissionEnum.DEPT.getCode() == user.getDataPermission()) {
            return JsonResult.error(GenerateWorkorderCodeEnum.ORDINARY_USER_NO_PERMISSION_TO_GENERATE.getCode(), GenerateWorkorderCodeEnum.ORDINARY_USER_NO_PERMISSION_TO_GENERATE.getMsg());
        }
        return JsonResult.error();
    }

    /**
     *
     * 添加工单
     *
     */
    private WorkOrder insertWorkOrder(User user) {
        WorkOrder workOrder = new WorkOrder();
        String code = DateUtils.generateCode("XJGD");
        workOrder.setCode(code);
        workOrder.setTenantId(user.getTenantId());
        workOrder.setDeptId(user.getDeptId());
        workOrder.setStatus(WorkOrderStatusEnum.WAIT.getCode());
        workOrder.setDistributionId(user.getId()); // 分配人员
        workOrder.setCreateUser(user.getId());
        workOrder.setCreateTime(DateUtils.now());
        Integer rowCount = workOrderMapper.insert(workOrder);
        if (rowCount <= 0) {
            log.info("添加工单表失败");
        }
        return workOrder;
    }

    /**
     *
     * 添加工单子表
     *
     */
    private void insertWorkOrderFile(WorkOrder workOrder, List<String> idList) {
        List<WorkOrderFile> workOrderFileList = new ArrayList<>();
        WorkOrderFile workOrderFile;
        for (String id : idList) {
            workOrderFile = new WorkOrderFile();
            workOrderFile.setTenantId(workOrder.getTenantId());
            workOrderFile.setWorkOrderId(workOrder.getId());
            workOrderFile.setInspectionFileId(id);
            workOrderFileList.add(workOrderFile);
        }

        if (CollectionUtil.isEmpty(workOrderFileList)) {
           return;
        }
        Integer rowCount = workOrderFileMapper.insertBatch(workOrderFileList);
        if (rowCount <= 0) {
            log.info("添加工单子表失败");
        }
    }

    /**
     *
     * 问题状态，改为已生成工单
     *
     * @param userId
     * @param idList
     */
    private JsonResult updateInspectionFileStatus(String userId, List<String> idList) {
        Map<String, Object> map = new HashMap<>();
        map.put("status", InspectionFileStatusEnum.GENERATE_ORDER.getCode());
        map.put("updateUser", userId);
        map.put("updateTime", DateUtils.now());
        map.put("idList", idList);

        Integer rowCount = inspectionFileMapper.updateByIdList(map);
        if (rowCount <= 0) {
            log.info("修改任务问题状态， 确认失败");
            return JsonResult.error(GenerateWorkorderCodeEnum.GENERATE_IS_FAILED.getCode(), GenerateWorkorderCodeEnum.GENERATE_IS_FAILED.getMsg());
        }
        return JsonResult.success();
    }
}
