package com.yeejoin.amos.boot.module.common.biz.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.api.service.IOrgUsrService;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.module.common.api.dto.FailureAuditDto;
import com.yeejoin.amos.boot.module.common.api.dto.FailureDetailsDto;
import com.yeejoin.amos.boot.module.common.api.dto.FailureRepairlogDto;
import com.yeejoin.amos.boot.module.common.api.entity.FailureAudit;
import com.yeejoin.amos.boot.module.common.api.enums.AuditResultEnum;
import com.yeejoin.amos.boot.module.common.api.enums.FailureStatuEnum;
import com.yeejoin.amos.boot.module.common.api.mapper.FailureAuditMapper;
import com.yeejoin.amos.boot.module.common.api.service.IFailureAuditService;

import static com.yeejoin.amos.boot.module.common.biz.service.impl.FailureDetailsServiceImpl.EMERGENCY_COMMAND;
import static com.yeejoin.amos.boot.module.common.biz.service.impl.FailureDetailsServiceImpl.PROCESS_NAME;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2021-08-04
 */
@Service
public class FailureAuditServiceImpl extends BaseService<FailureAuditDto, FailureAudit, FailureAuditMapper>
        implements IFailureAuditService {
    @Autowired
    FailureDetailsServiceImpl failureDetailsService;

    @Autowired
    FailureRepairlogServiceImpl failureRepairlogService;

    @Autowired
    OrgUsrServiceImpl iOrgUsrService;


    /**
     * 发起审核
     */
    @Transactional
    public Object savemodel(FailureAuditDto model, ReginParams userInfo) throws Exception {

        int condition = Integer.parseInt(model.getCondition());
        model.setAuditTime(new Date());
        model.setAuditDepartmentId(userInfo.getDepartment().getSequenceNbr());
        model.setAuditor(userInfo.getUserModel().getRealName());
        String parentId = iOrgUsrService.getParentId(userInfo.getUserModel().getUserId());
        OrgUsr orgUsr = iOrgUsrService.getById(parentId);
        model.setAuditDepartment(orgUsr.getBizOrgName());

        FailureDetailsDto failureDetailsDto = failureDetailsService.queryBySeq(model.getFaultId());

        int auditResult = 0;
        Boolean repairResult = null;
        Long seq = Long.valueOf(iOrgUsrService.getParentId(userInfo.getUserModel().getUserId()));
        //根据审核的结果进行业务操作
        if (condition == AuditResultEnum.AGREE.getCode() && seq.equals(failureDetailsDto.getBizCode())) {
            auditResult = AuditResultEnum.AGREE.getCode();
            repairResult = updateStatus(model, FailureStatuEnum.WAITING_AUDIT, userInfo, condition);
        } else if (condition == (AuditResultEnum.REFUSE.getCode())) {
            auditResult = AuditResultEnum.REFUSE.getCode();
            repairResult = updateStatus(model, FailureStatuEnum.REFUSE, userInfo, condition);
        } else if (condition == (AuditResultEnum.SEND_BACK.getCode())) {
            auditResult = AuditResultEnum.SEND_BACK.getCode();
            repairResult = updateStatus(model, FailureStatuEnum.WAITING_SUBMIT, userInfo, condition);
        } else if (condition == AuditResultEnum.AGREE.getCode()) {
            auditResult = AuditResultEnum.AGREE.getCode();
            repairResult = updateStatus(model, FailureStatuEnum.WAITING_MAINTAIN, userInfo, condition);
        }

        if (!repairResult) {
            throw new Exception("添加报修日志失败");
        }
        model.setAuditResult(auditResult);

        FailureAuditDto failureAuditDto = this.createWithModel(model);
        if (ObjectUtils.isEmpty(failureAuditDto)){
            throw new Exception("审核失败");
        }
        return true;
    }

    /**
     * 修改故障保修单任务状态
     */
    @Transactional
    public Boolean updateStatus(FailureAuditDto model, FailureStatuEnum status, ReginParams userInfo, int condition) throws Exception {

        FailureDetailsDto failureDetailsDto = failureDetailsService.queryBySeq(model.getFaultId());
        //当前角色部门id为应急指挥科的时候 并且同意时 不修改主表状态 依然为待审核
        //当前角色部门id为维修部门的时候 修改状态
        failureDetailsDto.setCurrentStatus(status.getCode());
        failureDetailsDto.setSequenceNbr(model.getFaultId());
        failureDetailsService.updateWithModel(failureDetailsDto);

        String conditionText;
        boolean result = failureDetailsService.checkExcuteTaskAuth(failureDetailsDto.getSequenceNbr(), userInfo);
        if (result) {
            //添加报修日志
            Long faultId = model.getFaultId();
            Date processTime = model.getAuditTime();
            String processDepartment = model.getAuditDepartment();
            Integer processAuditorId = Integer.parseInt(userInfo.getUserModel().getUserId());
            String processAuditorName = userInfo.getUserModel().getRealName();
            Long auditDepartmentId = (userInfo.getDepartment().getSequenceNbr());
            if (condition == AuditResultEnum.AGREE.getCode()) {
                conditionText = AuditResultEnum.AGREE.getName();
                repairlog(faultId,  processAuditorId, auditDepartmentId, processTime, processDepartment, conditionText, processAuditorName);
            } else if (condition == AuditResultEnum.SEND_BACK.getCode()) {
                conditionText = AuditResultEnum.SEND_BACK.getName();
                repairlog(faultId,  processAuditorId, auditDepartmentId, processTime, processDepartment, conditionText, processAuditorName);
            } else if (condition == AuditResultEnum.REFUSE.getCode()) {
                conditionText = AuditResultEnum.REFUSE.getName();
                repairlog(faultId,  processAuditorId, auditDepartmentId, processTime, processDepartment, conditionText, processAuditorName);
            }
            if (failureDetailsService.excuteTask(failureDetailsDto.getProcessId(), userInfo, condition + "")){
                return true;
            }else {
                throw new Exception("执行流程失败");
            }
        }
        return false;
    }

    /**
     * 添加报修日志
     */
    @Transactional
    public Boolean repairlog(Long faultId,  Integer processAuditorId, Long departmentId, Date processTime,
                             String processDepartment, String processResult, String processAuditorName) {
        FailureRepairlogDto failureRepairlogDto = new FailureRepairlogDto();
        failureRepairlogDto.setFaultId(faultId);
        failureRepairlogDto.setProcessAuditorId(processAuditorId);
        failureRepairlogDto.setProcessDepartmentId(departmentId);
        failureRepairlogDto.setProcessTime(processTime);
        failureRepairlogDto.setProcessDepartment(processDepartment);
        failureRepairlogDto.setProcessResult(processResult);
        failureRepairlogDto.setProcessAuditorName(processAuditorName);
        failureRepairlogService.createWithModel(failureRepairlogDto);
        if (ObjectUtils.isNotEmpty(failureRepairlogDto)) {
            return true;
        }
        return false;
    }

    /**
     * 根据FaultId查询
     */
    public List<FailureAudit> findByfaultId(Long faultId) {
        QueryWrapper<FailureAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fault_id", faultId).orderByDesc("audit_time");
        return baseMapper.selectList(queryWrapper);
    }

    public FailureAudit findByFaultId(Long faultId) {
        LambdaQueryWrapper<FailureAudit> wrapper = new LambdaQueryWrapper<FailureAudit>();
        wrapper.eq(FailureAudit::getIsDelete, false);
        wrapper.eq(FailureAudit::getFaultId, faultId);
        wrapper.orderByAsc(FailureAudit::getAuditTime);
        wrapper.last("LIMIT 1");
        return this.baseMapper.selectOne(wrapper);
    }

}