package com.hw.dms.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.hw.common.core.constant.DmsConstants;
import com.hw.common.core.constant.SecurityConstants;
import com.hw.common.core.exception.ServiceException;
import com.hw.common.core.utils.DateUtils;
import com.hw.common.core.utils.StringUtils;
import com.hw.common.core.utils.uuid.Seq;
import com.hw.common.security.utils.SecurityUtils;
import com.hw.dms.domain.*;
import com.hw.dms.mapper.DmsBillsLubeDetailMapper;
import com.hw.dms.mapper.DmsBillsLubeInstanceActivityMapper;
import com.hw.dms.mapper.DmsPlanLubeMapper;
import com.hw.system.api.RemoteSysCommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hw.dms.mapper.DmsBillsLubeInstanceMapper;
import com.hw.dms.service.IDmsBillsLubeInstanceService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 润滑工单Service业务层处理
 *
 * @author Open Platform
 * @date 2024-02-26
 */
@Service
public class DmsBillsLubeInstanceServiceImpl implements IDmsBillsLubeInstanceService {
    @Autowired
    private DmsBillsLubeInstanceMapper dmsBillsLubeInstanceMapper;

    @Autowired
    private DmsBillsLubeDetailMapper dmsBillsLubeDetailMapper;

    @Autowired
    private DmsPlanLubeMapper dmsPlanLubeMapper;

    @Autowired
    private DmsBillsLubeInstanceActivityMapper dmsBillsLubeInstanceActivityMapper;
    ;

    @Autowired
    private RemoteSysCommonService remoteSysCommonService;

    /**
     * 查询润滑工单
     *
     * @param lubeInstanceId 润滑工单主键
     * @return 润滑工单
     */
    @Override
    public DmsBillsLubeInstance selectDmsBillsLubeInstanceByLubeInstanceId(Long lubeInstanceId) {
        return dmsBillsLubeInstanceMapper.selectDmsBillsLubeInstanceByLubeInstanceId(lubeInstanceId);
    }

    /**
     * 查询润滑工单列表
     *
     * @param dmsBillsLubeInstance 润滑工单
     * @return 润滑工单
     */
    @Override
    public List<DmsBillsLubeInstance> selectDmsBillsLubeInstanceList(DmsBillsLubeInstance dmsBillsLubeInstance) {
        return dmsBillsLubeInstanceMapper.selectDmsBillsLubeInstanceList(dmsBillsLubeInstance);
    }

    /**
     * 新增润滑工单
     *
     * @param lubeInstanceCode 润滑计划编号
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDmsBillsLubeInstance(String lubeInstanceCode) {
        String lubeInstanceCodeS = lubeInstanceCode.replaceAll("\"", "");

        DmsPlanLube dmsPlanLube = dmsPlanLubeMapper.selectDmsPlanLubeJoinByPlanLubeCode(lubeInstanceCodeS);

        List<DmsPlanLubeDetail> planLubeDetails = dmsPlanLube.getDmsPlanLubeDetailList();
        if (planLubeDetails == null || planLubeDetails.isEmpty()) {
            return 0;
        }
        DmsBillsLubeInstance dmsBillsLubeInstance = new DmsBillsLubeInstance();

        Date lubeTime = dmsPlanLube.getLubeTime();
        dmsBillsLubeInstance.setPlanLubeId(dmsPlanLube.getPlanLubeId());
        dmsBillsLubeInstance.setCreateTime(DateUtils.getNowDate());
        dmsBillsLubeInstance.setPlanBeginTime(lubeTime);
        dmsBillsLubeInstance.setBillsLubeCode(Seq.getId(Seq.lubeInstanceSeqType, Seq.lubeInstanceCode));
        dmsBillsLubeInstance.setLubeStatus(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE);
        dmsBillsLubeInstance.setLubeGroup(dmsPlanLube.getLubeGroup());
        dmsBillsLubeInstance.setLubeSupervisor(dmsPlanLube.getLubeSupervisor());
        dmsBillsLubeInstance.setLubeLevel(dmsPlanLube.getLubeLevel());

        Long timeLimit = dmsPlanLube.getTimeLimit();
        dmsBillsLubeInstance.setIsFlag("1");
        dmsBillsLubeInstance.setPlanEndTime(new Date(lubeTime.getTime() + timeLimit * 1000l));
        int i = dmsBillsLubeInstanceMapper.insertDmsBillsLubeInstance(dmsBillsLubeInstance);

        batchInsertDmsBillsLubeDetail(dmsPlanLube, dmsBillsLubeInstance.getLubeInstanceId());
        return i;
    }

    public void batchInsertDmsBillsLubeDetail(DmsPlanLube dmsPlanLube, Long lubeInstanceId) {
        List<DmsPlanLubeDetail> planLubeDetails = dmsPlanLube.getDmsPlanLubeDetailList();
        List<DmsBillsLubeDetail> billsLubeDetails = new ArrayList<>();
        planLubeDetails.forEach(planLubeDetail -> {
            DmsBillsLubeDetail dmsBillsLubeDetail = new DmsBillsLubeDetail();
            dmsBillsLubeDetail.setLubeInstanceId(lubeInstanceId);
            dmsBillsLubeDetail.setDeviceId(planLubeDetail.getDeviceId());
            dmsBillsLubeDetail.setLubeStationId(planLubeDetail.getLubeStationId());
            dmsBillsLubeDetail.setLubeStandardId(planLubeDetail.getLubeStandardId());
            dmsBillsLubeDetail.setIsFlag(1L);
            billsLubeDetails.add(dmsBillsLubeDetail);
        });

        dmsBillsLubeInstanceMapper.batchDmsBillsLubeDetail(billsLubeDetails);
    }


    /**
     * 新增润滑工单
     *
     * @param dmsBillsLubeInstance 润滑工单
     * @return 结果
     */
    @Override
    public int insertDmsBillsLubeInstance(DmsBillsLubeInstance dmsBillsLubeInstance) {
        dmsBillsLubeInstance.setCreateTime(DateUtils.getNowDate());
        DmsPlanLube dmsPlanLube = dmsPlanLubeMapper.selectDmsPlanLubeByPlanLubeId(dmsBillsLubeInstance.getPlanLubeId());
        dmsBillsLubeInstance.setPlanBeginTime(dmsPlanLube.getLubeTime());
        dmsBillsLubeInstance.setLubeStatus("1");
        Date lubeTime = dmsPlanLube.getLubeTime();
        Long timeLimit = dmsPlanLube.getTimeLimit();
        dmsBillsLubeInstance.setPlanEndTime(new Date(lubeTime.getTime() + timeLimit * 1000l));
        int i = dmsBillsLubeInstanceMapper.insertDmsBillsLubeInstance(dmsBillsLubeInstance);
        List<DmsBillsLubeInstance> dmsBillsLubeInstances = dmsBillsLubeInstanceMapper.selectDmsBillsLubeInstanceList(dmsBillsLubeInstance);
        DmsBillsLubeInstance dmsBillsLubeInstance1 = dmsBillsLubeInstances.get(0);
        //新建润滑工单实例节点
        DmsBillsLubeInstanceActivity dmsBillsLubeInstanceActivity = new DmsBillsLubeInstanceActivity();
        dmsBillsLubeInstanceActivity.setLubeInstanceId(dmsBillsLubeInstance1.getLubeInstanceId());
        dmsBillsLubeInstanceActivity.setProcessActivityId(106l);
        dmsBillsLubeInstanceActivity.setLubeGroup(dmsPlanLube.getLubeGroup());
        dmsBillsLubeInstanceActivity.setLubeSupervisor(dmsPlanLube.getLubeSupervisor());
        dmsBillsLubeInstanceActivity.setLubeLevel(dmsPlanLube.getLubeLevel());
        dmsBillsLubeInstanceActivity.setProcessStepOrder(1l);
        dmsBillsLubeInstanceActivityMapper.insertDmsBillsLubeInstanceActivity(dmsBillsLubeInstanceActivity);
        return i;
    }

    /**
     * 修改润滑工单
     *
     * @param dmsBillsLubeInstance 润滑工单
     * @return 结果
     */
    @Override
    public int updateDmsBillsLubeInstance(DmsBillsLubeInstance dmsBillsLubeInstance) {
        dmsBillsLubeInstance.setUpdateTime(DateUtils.getNowDate());
        return dmsBillsLubeInstanceMapper.updateDmsBillsLubeInstance(dmsBillsLubeInstance);
    }

    /**
     * 批量删除润滑工单
     *
     * @param lubeInstanceIds 需要删除的润滑工单主键
     * @return 结果
     */
    @Override
    public int deleteDmsBillsLubeInstanceByLubeInstanceIds(Long[] lubeInstanceIds) {
        return dmsBillsLubeInstanceMapper.deleteDmsBillsLubeInstanceByLubeInstanceIds(lubeInstanceIds);
    }

    /**
     * 删除润滑工单信息
     *
     * @param lubeInstanceId 润滑工单主键
     * @return 结果
     */
    @Override
    public int deleteDmsBillsLubeInstanceByLubeInstanceId(Long lubeInstanceId) {
        return dmsBillsLubeInstanceMapper.deleteDmsBillsLubeInstanceByLubeInstanceId(lubeInstanceId);
    }

    @Override
    public int insertDmsBillsLubeInstancePDA(DmsBillsLubeInstance dmsBillsLubeInstance) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
        Long aLong = remoteSysCommonService.selectProcessActivityIdByWfProcessId(SecurityConstants.INNER, 106l);
        dmsBillsLubeInstance.setBillsLubeCode(sdf.format(DateUtils.getNowDate()));
        dmsBillsLubeInstance.setLubeStatus("1");
        dmsBillsLubeInstance.setIsFlag("1");
        //创建润滑工单实例节点
        DmsBillsLubeInstanceActivity dmsBillsLubeInstanceActivity = new DmsBillsLubeInstanceActivity();
        dmsBillsLubeInstanceActivity.setLubeInstanceId(dmsBillsLubeInstance.getLubeInstanceId());
        dmsBillsLubeInstanceActivity.setProcessActivityId(aLong);
        dmsBillsLubeInstanceActivity.setLubeGroup(dmsBillsLubeInstance.getLubeGroup());
        dmsBillsLubeInstanceActivity.setLubeLevel(dmsBillsLubeInstance.getLubeLevel());
        dmsBillsLubeInstanceActivity.setLubeSupervisor(dmsBillsLubeInstance.getLubeSupervisor());

        return 0;
    }


    /**
     * 获取最新一条未完成的润滑工单
     *
     * @param dmsBillsLubeInstance
     * @return
     */
    @Override
    public DmsBillsLubeInstance getNewestBillsLubeInstance(DmsBillsLubeInstance dmsBillsLubeInstance) {
        dmsBillsLubeInstance.setLubeStatusStr(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE
                + "," + DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_LUBING);
        DmsBillsLubeInstance newestBillsLubeInstance = dmsBillsLubeInstanceMapper.selectNewestDmsBillsLubeInstance(dmsBillsLubeInstance);
        if (newestBillsLubeInstance != null) {
            DmsBillsLubeDetail queryBillsLubeDetail = new DmsBillsLubeDetail();
            queryBillsLubeDetail.setLubeInstanceId(dmsBillsLubeInstance.getLubeInstanceId());
            List<DmsBillsLubeDetail> dmsBillsLubeDetails = dmsBillsLubeDetailMapper.selectDmsBillsLubeDetailJoinList(queryBillsLubeDetail);
            newestBillsLubeInstance.setDmsBillsLubeDetailList(dmsBillsLubeDetails);
        }

        return newestBillsLubeInstance;
    }


    /**
     * 开始润滑
     *
     * @param dmsBillsLubeDetail 润滑工单明细
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int startLube(DmsBillsLubeDetail dmsBillsLubeDetail) {
        DmsBillsLubeInstance dmsBillsLubeInstance = dmsBillsLubeInstanceMapper
                .selectDmsBillsLubeInstanceByLubeInstanceId(dmsBillsLubeDetail.getLubeInstanceId());
        String lubeStatus = StringUtils.isEmpty(dmsBillsLubeInstance.getLubeStatus()) ?
                DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE : dmsBillsLubeInstance.getLubeStatus();
        if (lubeStatus.equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_COMPLETE)) {//润滑完成
            throw new ServiceException("已经润滑完成");
        }

        Date currentDate = new Date();
        String userName = SecurityUtils.getUsername();

        if (lubeStatus.equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE)) {//待润滑
            dmsBillsLubeInstance.setLubeStatus(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_LUBING);
            dmsBillsLubeInstance.setRealBeginTime(currentDate);
            dmsBillsLubeInstance.setUpdateTime(currentDate);
            dmsBillsLubeInstance.setUpdateBy(userName);
            dmsBillsLubeInstanceMapper.updateDmsBillsLubeInstance(dmsBillsLubeInstance);

            dmsBillsLubeDetail.setBeginTime(currentDate);
            dmsBillsLubeDetail.setUpdateBy(userName);
            dmsBillsLubeDetail.setUpdateTime(currentDate);
            dmsBillsLubeDetail.setMaintStatus(Long.valueOf(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_LUBING));

            dmsBillsLubeDetailMapper.updateDmsBillsLubeDetail(dmsBillsLubeDetail);

        } else {//润滑中
            dmsBillsLubeDetail.setUpdateBy(userName);
            dmsBillsLubeDetail.setUpdateTime(currentDate);
            dmsBillsLubeDetailMapper.updateDmsBillsLubeDetail(dmsBillsLubeDetail);
        }

        return 1;
    }


    /**
     * 完成润滑
     *
     * @param dmsBillsLubeDetail 润滑工单明细
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int completeLube(DmsBillsLubeDetail dmsBillsLubeDetail) {
        Long lubeInstanceId = dmsBillsLubeDetail.getLubeInstanceId();
        DmsBillsLubeInstance dmsBillsLubeInstance = dmsBillsLubeInstanceMapper
                .selectDmsBillsLubeInstanceByLubeInstanceId(lubeInstanceId);
        String lubeStatus = StringUtils.isEmpty(dmsBillsLubeInstance.getLubeStatus()) ?
                DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE : dmsBillsLubeInstance.getLubeStatus();
        if (lubeStatus.equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_COMPLETE)) {//润滑完成
            throw new ServiceException("已经润滑完成");
        }

        if (lubeStatus.equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE)) {//待润滑
            throw new ServiceException("请先执行开始润滑");
        }

        Date currentDate = new Date();
        String userName = SecurityUtils.getUsername();

        DmsBillsLubeDetail queryLubeDetail = new DmsBillsLubeDetail();
        queryLubeDetail.setLubeInstanceId(lubeInstanceId);
        List<DmsBillsLubeDetail> lubeDetails = dmsBillsLubeDetailMapper.selectDmsBillsLubeDetailList(queryLubeDetail);

        /**获取未完成的润滑明细，并且需要排除当前提交完成的润滑明细*/
        List<DmsBillsLubeDetail> inCompleteLubeDetails = lubeDetails.stream().
                filter(lubeDetail -> !lubeDetail.getBillsLubeDetailId().equals(dmsBillsLubeDetail.getBillsLubeDetailId())
                        && (lubeDetail.getMaintStatus() == null || lubeDetail.getMaintStatus().equals("")
                        || lubeDetail.getMaintStatus().equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_TO_LUBE)
                        || lubeDetail.getMaintStatus().equals(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_LUBING))).collect(Collectors.toList());

        /**如果已经没有未完成的，则需要将工单修改成已完成，并更新结束时间*/
        if (inCompleteLubeDetails == null || inCompleteLubeDetails.isEmpty()) {
            dmsBillsLubeInstance.setLubeStatus(DmsConstants.DMS_BILLS_LUBE_INSTANCE_STATUS_COMPLETE);
            dmsBillsLubeInstance.setRealEndTime(currentDate);
            dmsBillsLubeInstance.setUpdateTime(currentDate);
            dmsBillsLubeInstance.setUpdateBy(userName);
            dmsBillsLubeInstanceMapper.updateDmsBillsLubeInstance(dmsBillsLubeInstance);
        }

        dmsBillsLubeDetail.setEndTime(currentDate);
        dmsBillsLubeDetail.setUpdateBy(userName);
        dmsBillsLubeDetail.setUpdateTime(currentDate);
        dmsBillsLubeDetail.setMaintStatus(DmsConstants.DMS_BILLS_MAINT_INSTANCE_STATUS_COMPLETE);

        dmsBillsLubeDetailMapper.updateDmsBillsLubeDetail(dmsBillsLubeDetail);

        return 1;
    }
}
