package com.ruoyi.asset.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.asset.domain.TbAsset;
import com.ruoyi.asset.domain.TbAssetBorrowRecord;
import com.ruoyi.asset.domain.TbAssetStatusRecord;
import com.ruoyi.asset.domain.dto.TbFaultReportDTO;
import com.ruoyi.asset.domain.dto.TbFaultReportProcessDTO;
import com.ruoyi.asset.domain.enums.TbAssetStatusEnum;
import com.ruoyi.asset.domain.enums.TbFaultProcessStateEnum;
import com.ruoyi.asset.mapper.TbAssetBorrowRecordMapper;
import com.ruoyi.asset.mapper.TbAssetMapper;
import com.ruoyi.asset.mapper.TbAssetStatusRecordMapper;
import com.ruoyi.asset.utils.EmailUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.UserUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.asset.mapper.TbFaultReportMapper;
import com.ruoyi.asset.domain.TbFaultReport;
import com.ruoyi.asset.service.ITbFaultReportService;

import javax.annotation.Resource;

/**
 * 故障报备Service业务层处理
 * 
 * @author 原动力
 * @date 2023-03-27
 */
@Service
public class TbFaultReportServiceImpl extends ServiceImpl<TbFaultReportMapper, TbFaultReport> implements ITbFaultReportService
{
    @Autowired
    private TbFaultReportMapper tbFaultReportMapper;

    @Resource
    private TbAssetMapper tbAssetMapper;

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private TbAssetBorrowRecordMapper tbAssetBorrowRecordMapper;

    @Resource
    private TbAssetStatusRecordMapper tbAssetStatusRecordMapper;

    @Resource
    private EmailUtils emailUtils;

    /**
     * 查询故障报备
     * 
     * @param id 故障报备主键
     * @return 故障报备
     */
    @Override
    public TbFaultReport selectTbFaultReportById(Long id)
    {
        return tbFaultReportMapper.selectTbFaultReportById(id);
    }

    /**
     * 查询故障报备列表
     * 
     * @param tbFaultReport 故障报备
     * @return 故障报备
     */
    @Override
    public List<TbFaultReportDTO> selectTbFaultReportList(TbFaultReport tbFaultReport)
    {
        List<TbFaultReport> tbFaultReports = tbFaultReportMapper.selectTbFaultReportList(tbFaultReport);
        ArrayList<TbFaultReportDTO> faultReportDTOS = new ArrayList<>();
        for (TbFaultReport faultReport : tbFaultReports) {
            TbFaultReportDTO tbFaultReportDTO = BeanUtil.toBean(faultReport, TbFaultReportDTO.class);
            String assetBarCode = faultReport.getAssetBarCode();
            TbAsset tbAsset = tbAssetMapper.selectTbAssetByBarCode(assetBarCode);
            tbFaultReportDTO.setTbAsset(tbAsset);
            faultReportDTOS.add(tbFaultReportDTO);
        }
        return faultReportDTOS;
    }

    /**
     * 新增故障报备
     * 
     * @param tbFaultReport 故障报备
     * @return 结果
     */
    @Override
    public int insertTbFaultReport(TbFaultReport tbFaultReport)
    {
        return tbFaultReportMapper.insertTbFaultReport(tbFaultReport);
    }

    /**
     * 修改故障报备
     * 
     * @param tbFaultReport 故障报备
     * @return 结果
     */
    @Override
    public int updateTbFaultReport(TbFaultReport tbFaultReport)
    {
        return tbFaultReportMapper.updateTbFaultReport(tbFaultReport);
    }

    /**
     * 批量删除故障报备
     * 
     * @param ids 需要删除的故障报备主键
     * @return 结果
     */
    @Override
    public int deleteTbFaultReportByIds(Long[] ids)
    {
        return tbFaultReportMapper.deleteTbFaultReportByIds(ids);
    }

    /**
     * 删除故障报备信息
     * 
     * @param id 故障报备主键
     * @return 结果
     */
    @Override
    public int deleteTbFaultReportById(Long id)
    {
        return tbFaultReportMapper.deleteTbFaultReportById(id);
    }

    /**
     * 小程序：新增故障报备信息
     *
     * @param tbFaultReport 故障报备信息
     * @return 结果
     */
    @Override
    public AjaxResult saveTbFaultReport(TbFaultReport tbFaultReport) {
        String assetBarCode = tbFaultReport.getAssetBarCode();
        TbAsset tbAsset = tbAssetMapper.selectTbAssetByBarCode(assetBarCode);
        if (tbAsset == null) {
            return AjaxResult.error("资产设备不存在");
        }
        Long status = tbAsset.getStatus();
        if (status != 1) {
            return AjaxResult.error("资产设备已报备");
        }
        QueryWrapper<TbAssetBorrowRecord> borrowRecordQueryWrapper = new QueryWrapper<>();
        borrowRecordQueryWrapper.eq("asset_bar_code", assetBarCode).eq("isReturn", 0);
        TbAssetBorrowRecord borrowRecord = tbAssetBorrowRecordMapper.selectOne(borrowRecordQueryWrapper);
        if (borrowRecord != null) {
            return AjaxResult.error("资产设备未归还");
        }
        Long loginUserId = UserUtils.getLoginUserId();
        tbFaultReport.setUserId(loginUserId);
        Date faultReportDate = new Date();
        tbFaultReport.setReportDate(faultReportDate);

        tbFaultReport.setId(null);
        tbFaultReport.setProcessState(TbFaultProcessStateEnum.pending.getProcessStateCode());
        tbFaultReport.setProcessResult(null);

        boolean result = save(tbFaultReport);
        if (result) {
            int updateResult = tbAssetMapper.updateTbAssetStatus(assetBarCode, TbAssetStatusEnum.fault.getStatusCode());
            if (updateResult < 1) {
                throw new ServiceException("故障上报失败", 500);
            }
            TbAssetStatusRecord tbAssetStatusRecord = tbAssetStatusRecordMapper.selectTbAssetStatusRecordByAssetBarCode(assetBarCode);
            if (tbAssetStatusRecord == null) {
                TbAssetStatusRecord statusRecord = new TbAssetStatusRecord();
                statusRecord.setAssetBarCode(assetBarCode);
                statusRecord.setFaultNumber(1L);
                statusRecord.setLastFaultDate(faultReportDate);
                int insert = tbAssetStatusRecordMapper.insert(statusRecord);
                if (insert < 1) {
                    throw new ServiceException("故障上报失败");
                }
            } else {
                Long faultNumber = tbAssetStatusRecord.getFaultNumber();
                tbAssetStatusRecord.setFaultNumber(faultNumber+1);
                tbAssetStatusRecord.setLastFaultDate(faultReportDate);
                int update = tbAssetStatusRecordMapper.updateById(tbAssetStatusRecord);
                if (update < 1) {
                    throw new ServiceException("故障上报失败");
                }
            }

            SysUser sysUser = userMapper.selectUserById(1L);
            String format = String.format("报备设备条形码：%s，报备设备名称：%s，故障原因：%s", assetBarCode, tbAsset.getName(), tbFaultReport.getFaultPhenomenon());
            // emailUtils.sendSimpleEmail(sysUser.getEmail(), "设备报备通知", format);

            // TODO 记得改回注释代码
            emailUtils.sendSimpleEmail("1248708657@qq.com", "设备报备通知", format);
        }

        return result ? AjaxResult.success("故障上报成功", tbFaultReport) : AjaxResult.error("故障上报失败");
    }

    /**
     * 故障报备处理
     *
     * @param faultReportProcessDTO 处理信息
     * @return 结果
     */
    @Override
    public AjaxResult tbFaultReportProcess(TbFaultReportProcessDTO faultReportProcessDTO) {
        Long faultReportId = faultReportProcessDTO.getTbFaultReportId();
        TbFaultReport faultReport = getById(faultReportId);
        if (faultReport == null) {
            return AjaxResult.error("故障报备不存在");
        }
        Long processState = faultReport.getProcessState();
        if (processState != null && processState.equals(TbFaultProcessStateEnum.processed.getProcessStateCode())) {
            return AjaxResult.error("故障报备已处理");
        }
        Long feedbackStatus = faultReportProcessDTO.getFeedbackStatus();
        if (feedbackStatus == null || feedbackStatus < 1 || feedbackStatus > 2){
            feedbackStatus = TbAssetStatusEnum.normal.getStatusCode();
        }
        faultReport.setProcessState(TbFaultProcessStateEnum.processed.getProcessStateCode());
        faultReport.setProcessResult(faultReportProcessDTO.getProcessResult());
        boolean result = updateById(faultReport);
        if (result) {
            int updateResult = tbAssetMapper.updateTbAssetStatus(faultReport.getAssetBarCode(), feedbackStatus);
            if (updateResult < 1) {
                throw new ServiceException("故障报备处理失败", 500);
            }
        }
        return result ? AjaxResult.success("故障报备处理成功", faultReport) : AjaxResult.error("故障报备处理失败");
    }

    /**
     * 获取用户自己故障报备记录
     *
     * @return 故障报备信息列表
     */
    @Override
    public List<TbFaultReport> selectMeTbFaultReport() {
        Long loginUserId = UserUtils.getLoginUserId();
        return query().eq("user_id", loginUserId).orderByDesc("report_date").list();
    }

}
