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

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

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;

    private final Logger logger = LoggerFactory.getLogger(FailureAuditServiceImpl.class);

    /**
     * 分页查询
     */
    public Page<FailureAuditDto> queryForFailureAuditPage(Page<FailureAuditDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<FailureAuditDto> queryForFailureAuditList() {
        return this.queryForList("", false);
    }

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

        int condition = Integer.parseInt(model.getCondition());
        model.setAuditTime(new Date());
        model.setAuditDepartmentId(userInfo.getDepartment().getSequenceNbr());
        model.setAuditor(userInfo.getUserModel().getUserName());
        model.setAuditDepartment(userInfo.getDepartment().getDepartmentName());

        FailureDetailsDto failureDetailsDto = failureDetailsService.queryBySeq(model.getFaultId());
        try {
            //根据审核的结果进行业务操作
            if (condition == AuditResultEnum.AGREE.getCode()  && userInfo.getDepartment().getSequenceNbr().equals(failureDetailsDto.getBizCode())) {
                updateStatus(model, FailureStatuEnum.WAITING_AUDIT, userInfo,condition);
            } else if (condition == (AuditResultEnum.REFUSE.getCode())) {
                updateStatus(model, FailureStatuEnum.REFUSE, userInfo,condition);
            } else if (condition == (AuditResultEnum.SEND_BACK.getCode())) {
                updateStatus(model, FailureStatuEnum.WAITING_SUBMIT, userInfo,condition);
            } else if  (condition == AuditResultEnum.AGREE.getCode() ) {
                updateStatus(model, FailureStatuEnum.WAITING_MAINTAIN, userInfo,condition);
            }

            FailureAuditDto withModel = this.createWithModel(model);
        }catch (Exception e){
            e.printStackTrace();
            e.printStackTrace();
            logger.info("添加故障审核信息到数据库失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false ;
        }

        return true;
    }

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

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

        /*Map<String, Object> stringObjectMap = failureDetailsService.checkExcuteTaskAuthMap(failureDetailsDto.getSequenceNbr(), userInfo);
        String  name = stringObjectMap.get("name").toString();
        if (name.contains(EMERGENCY_COMMAND)) {
            failureDetailsDto.setCurrentStatus(failureDetailsDto.getCurrentStatus());
        }*/
        failureDetailsDto.setCurrentStatus(status.getCode());
        failureDetailsDto.setSequenceNbr(model.getFaultId());
        FailureDetailsDto failureDetailsDtos = failureDetailsService.updateWithModel(failureDetailsDto);
        System.out.println(failureDetailsDtos);

        String conditionText;
        boolean result = failureDetailsService.checkExcuteTaskAuth(failureDetailsDto.getSequenceNbr(), userInfo);
        if (result){
            //添加报修日志
            Long faultId = model.getFaultId();
            Date processTime = model.getAuditTime();
            String processDepartment = model.getAuditDepartment();
            String processAuditor = model.getAuditor();
            Integer processAuditorId =Integer.parseInt(userInfo.getUserModel().getUserId()) ;
            String processAuditorCid = userInfo.getUserModel().getUserName();
            Long auditDepartmentId = (userInfo.getDepartment().getSequenceNbr());
            if (condition == AuditResultEnum.AGREE.getCode()  ) {
                conditionText = AuditResultEnum.AGREE.getName();
                repairlog(faultId,processAuditor,processAuditorId,auditDepartmentId,processTime,processDepartment,conditionText,processAuditorCid);
            } else if (condition == AuditResultEnum.SEND_BACK.getCode()) {
                conditionText = AuditResultEnum.SEND_BACK.getName();
                repairlog(faultId,processAuditor,processAuditorId,auditDepartmentId,processTime,processDepartment,conditionText,processAuditorCid);
            } else if (condition == AuditResultEnum.REFUSE.getCode()){
                conditionText = AuditResultEnum.REFUSE.getName();
                repairlog(faultId,processAuditor,processAuditorId,auditDepartmentId,processTime,processDepartment,conditionText,processAuditorCid);
            }
            failureDetailsService.excuteTask(failureDetailsDto.getProcessId(), userInfo,condition+"");
            return true;
        }
       return false;
    }

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

    /**
     * 根据FaultId查询
     */
    public List<FailureAudit> findByfaultId(Long faultId) {
        Page<FailureAudit> page = new Page<>();
        QueryWrapper<FailureAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fault_id", faultId).orderByDesc("submission_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);
    }

}