package com.ruoyi.asset.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
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.TbAssetStatusRecord;
import com.ruoyi.asset.domain.TbPlace;
import com.ruoyi.asset.domain.dto.TbBorrowRecordDTO;
import com.ruoyi.asset.domain.dto.TbCountAssetDTO;
import com.ruoyi.asset.mapper.TbAssetMapper;
import com.ruoyi.asset.mapper.TbAssetStatusRecordMapper;
import com.ruoyi.asset.mapper.TbPlaceMapper;
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.TbAssetBorrowRecordMapper;
import com.ruoyi.asset.domain.TbAssetBorrowRecord;
import com.ruoyi.asset.service.ITbAssetBorrowRecordService;

import javax.annotation.Resource;

/**
 * 设备借用记录Service业务层处理
 * 
 * @author 原动力
 * @date 2023-03-27
 */
@Service
public class TbAssetBorrowRecordServiceImpl extends ServiceImpl<TbAssetBorrowRecordMapper, TbAssetBorrowRecord> implements ITbAssetBorrowRecordService
{
    @Autowired
    private TbAssetBorrowRecordMapper tbAssetBorrowRecordMapper;

    @Resource
    private TbAssetMapper tbAssetMapper;

    @Resource
    private TbPlaceMapper tbPlaceMapper;

    @Resource
    private TbAssetStatusRecordMapper tbAssetStatusRecordMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 查询设备借用记录
     * 
     * @param id 设备借用记录主键
     * @return 设备借用记录
     */
    @Override
    public TbAssetBorrowRecord selectTbAssetBorrowRecordById(Long id)
    {
        return tbAssetBorrowRecordMapper.selectTbAssetBorrowRecordById(id);
    }

    @Override
    public List<TbAssetBorrowRecord> selectTbAssetBorrowRecordList(TbAssetBorrowRecord tbAssetBorrowRecord) {
        return tbAssetBorrowRecordMapper.selectTbAssetBorrowRecordList(tbAssetBorrowRecord);
    }

    @Override
    public List<TbBorrowRecordDTO> selectTbAssetBorrowRecordDTOList(TbAssetBorrowRecord tbAssetBorrowRecord)
    {
        List<TbAssetBorrowRecord> tbAssetBorrowRecords = tbAssetBorrowRecordMapper.selectTbAssetBorrowRecordList(tbAssetBorrowRecord);
        List<TbBorrowRecordDTO> borrowRecordDTOS = new ArrayList<>();
        for (TbAssetBorrowRecord assetBorrowRecord : tbAssetBorrowRecords) {
            TbBorrowRecordDTO tbBorrowRecordDTO = BeanUtil.toBean(assetBorrowRecord, TbBorrowRecordDTO.class);
            Long userId = assetBorrowRecord.getUserId();
            SysUser sysUser = sysUserMapper.selectUserById(userId);
            tbBorrowRecordDTO.setUsername(sysUser.getUserName());
            String assetBarCode = assetBorrowRecord.getAssetBarCode();
            TbAsset tbAsset = tbAssetMapper.selectTbAssetByBarCode(assetBarCode);
            tbBorrowRecordDTO.setTbAsset(tbAsset);

            borrowRecordDTOS.add(tbBorrowRecordDTO);
        }
        return borrowRecordDTOS;
    }

    /**
     * 新增设备借用记录
     * 
     * @param tbAssetBorrowRecord 设备借用记录
     * @return 结果
     */
    @Override
    public int insertTbAssetBorrowRecord(TbAssetBorrowRecord tbAssetBorrowRecord)
    {
        return tbAssetBorrowRecordMapper.insertTbAssetBorrowRecord(tbAssetBorrowRecord);
    }

    /**
     * 修改设备借用记录
     * 
     * @param tbAssetBorrowRecord 设备借用记录
     * @return 结果
     */
    @Override
    public int updateTbAssetBorrowRecord(TbAssetBorrowRecord tbAssetBorrowRecord)
    {
        return tbAssetBorrowRecordMapper.updateTbAssetBorrowRecord(tbAssetBorrowRecord);
    }

    /**
     * 批量删除设备借用记录
     * 
     * @param ids 需要删除的设备借用记录主键
     * @return 结果
     */
    @Override
    public int deleteTbAssetBorrowRecordByIds(Long[] ids)
    {
        return tbAssetBorrowRecordMapper.deleteTbAssetBorrowRecordByIds(ids);
    }

    /**
     * 删除设备借用记录信息
     * 
     * @param id 设备借用记录主键
     * @return 结果
     */
    @Override
    public int deleteTbAssetBorrowRecordById(Long id)
    {
        return tbAssetBorrowRecordMapper.deleteTbAssetBorrowRecordById(id);
    }

    /**
     * 新增设备借用记录
     *
     * @param tbAssetBorrowRecord 设备借用记录信息
     * @return 结果
     */
    @Override
    public AjaxResult saveBorrowRecord(TbAssetBorrowRecord tbAssetBorrowRecord) {
        String assetBarCode = tbAssetBorrowRecord.getAssetBarCode();
        TbAsset tbAsset = tbAssetMapper.selectTbAssetByBarCode(assetBarCode);
        if (tbAsset == null) {
            return AjaxResult.error("资产设备不存在");
        }
        TbAssetBorrowRecord borrowRecord = query().eq("asset_bar_code", assetBarCode).eq("isReturn", 0).one();
        if (borrowRecord != null && borrowRecord.getIsreturn() < 1) {
            return AjaxResult.error("当前资产设备已借出");
        }
        if (tbAsset.getStatus() != 1) {
            if (tbAsset.getStatus() == 0) {
                return AjaxResult.error("当前资产设备已故障");
            }
            if (tbAsset.getStatus() == 2) {
                return AjaxResult.error("当前资产设备已报废");
            }
        }
        String borrowPlaceName = tbAssetBorrowRecord.getBorrowPlaceName();
        TbPlace tbPlace = tbPlaceMapper.selectTbPlaceByName(borrowPlaceName);
        if (tbPlace == null) {
            return AjaxResult.error("借用地点不存在");
        }

        Long userId = UserUtils.getLoginUserId();
        tbAssetBorrowRecord.setUserId(userId);
        tbAssetBorrowRecord.setIsreturn(0L);
        tbAssetBorrowRecord.setActualReturnDate(null);

        boolean result = save(tbAssetBorrowRecord);

        if (result) {
            TbAssetStatusRecord tbAssetStatusRecord = tbAssetStatusRecordMapper.selectTbAssetStatusRecordByAssetBarCode(assetBarCode);
            if (tbAssetStatusRecord == null) {
                TbAssetStatusRecord statusRecord = new TbAssetStatusRecord();
                statusRecord.setAssetBarCode(assetBarCode);
                statusRecord.setBorrowNumber(1L);
                int insert = tbAssetStatusRecordMapper.insert(statusRecord);
                if (insert < 1) {
                    throw new ServiceException("借用失败");
                }
            } else {
                Long borrowNumber = tbAssetStatusRecord.getBorrowNumber();
                tbAssetStatusRecord.setBorrowNumber(borrowNumber+1);
                int update = tbAssetStatusRecordMapper.updateById(tbAssetStatusRecord);
                if (update < 1) {
                    throw new ServiceException("借用失败");
                }
            }
        }

        return result ? AjaxResult.success("借用成功", tbAssetBorrowRecord) : AjaxResult.error("借用失败");
    }

    @Override
    public AjaxResult updateBorrowRecordToReturn(String barCode) {
        if (StrUtil.isBlank(barCode)) {
            return AjaxResult.error("资产条形码不能为空");
        }
        TbAssetBorrowRecord borrowRecord = query().eq("asset_bar_code", barCode).eq("isReturn", 0).one();
        if (borrowRecord == null) {
            return AjaxResult.error("资产设备已归还");
        }
        Long borrowUserId = borrowRecord.getUserId();
        Long returnUserId = UserUtils.getLoginUserId();
        if (!borrowUserId.equals(returnUserId)) {
            return AjaxResult.error("非借用人本人归还");
        }
        borrowRecord.setIsreturn(1L);
        borrowRecord.setActualReturnDate(new Date());
        boolean result = updateById(borrowRecord);
        return result ? AjaxResult.success("归还成功") : AjaxResult.error("归还失败");
    }

    /**
     * 获取用户自己设备借用记录
     *
     * @return 设备借用记录集合
     */
    @Override
    public List<TbAssetBorrowRecord> selectMeTbAssetBorrowRecord(Long status) {
        Long loginUserId = UserUtils.getLoginUserId();
        QueryWrapper<TbAssetBorrowRecord> borrowRecordQueryWrapper = new QueryWrapper<>();
        borrowRecordQueryWrapper.eq("user_id", loginUserId).orderByAsc("isReturn").orderByDesc("borrow_date");
        if (status != null) {
            if (status < 0 || status > 1) {
                status = 0L;
            }
            borrowRecordQueryWrapper.eq("isReturn", status);
        }
        return list(borrowRecordQueryWrapper);
    }

    @Override
    public TbBorrowRecordDTO selectMeTbAssetBorrowRecordById(Long id) {
        Long loginUserId = UserUtils.getLoginUserId();
        TbAssetBorrowRecord borrowRecord = query().eq("user_id", loginUserId).eq("id", id).one();
        if (borrowRecord == null) {
            return null;
        }
        String assetBarCode = borrowRecord.getAssetBarCode();
        TbAsset tbAsset = tbAssetMapper.selectTbAssetByBarCode(assetBarCode);

        TbBorrowRecordDTO tbBorrowRecordDTO = BeanUtil.toBean(borrowRecord, TbBorrowRecordDTO.class);
        tbBorrowRecordDTO.setTbAsset(tbAsset);
        return tbBorrowRecordDTO;
    }

    @Override
    public AjaxResult countMeTbAssetBorrowRecord(Long status) {
        Long loginUserId = UserUtils.getLoginUserId();
        QueryWrapper<TbAssetBorrowRecord> borrowRecordQueryWrapper = new QueryWrapper<>();
        borrowRecordQueryWrapper.eq("user_id", loginUserId);
        if (status != null) {
            if (status < 0 || status > 1) {
                status = 0L;
            }
            borrowRecordQueryWrapper.eq("isReturn", status);
        }
        int count = count(borrowRecordQueryWrapper);
        return AjaxResult.success("查询成功", count);
    }

    @Override
    public List<TbCountAssetDTO> countAssetDto() {
        List<TbCountAssetDTO> dto = tbAssetBorrowRecordMapper.countAssetDto();
        return dto;
    }

    @Resource
    private EmailUtils emailUtils;

    @Override
    public void informNotReturnUser() {
        Date date = new Date();

        long time = date.getTime();
        long five = 5 * 24 * 60 * 60 * 1000;
        long fiveDate = five + time;
        Date toDate = new Date(fiveDate);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String begin = dateFormat.format(date);
        String end = dateFormat.format(toDate);

        List<TbAssetBorrowRecord> borrowRecords = query().eq("isReturn", 0).ge("return_date", begin).le("return_date", end).list();
        List<TbAssetBorrowRecord> borrowRecordList = borrowRecords.stream().filter(Objects::nonNull).collect(Collectors.toList());

        if (borrowRecordList.isEmpty()) {
            return;
        }
        Set<Long> userIdSet = new HashSet<>();

        for (TbAssetBorrowRecord borrowRecord : borrowRecordList) {
            userIdSet.add(borrowRecord.getUserId());
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String nowDate = simpleDateFormat.format(date);

        for (Long userId : userIdSet) {
            SysUser sysUser = sysUserMapper.selectUserById(userId);
            String email = sysUser.getEmail();
            List<TbAssetBorrowRecord> collect = borrowRecordList.stream().filter(record -> record.getUserId().equals(userId)).collect(Collectors.toList());

            String start = "<!DOCTYPE html>\r\n" +
                    "<html>\r\n" +
                    "<head>\r\n" +
                    "<meta charset=\"UTF-8\">\r\n" +
                    "<title>Insert title here</title>\r\n" +
                    "</head>\r\n" +
                    "<body>\r\n" +
                    "<h3>"+ nowDate +"待归还设备提醒</h3>" +
                    "<table border=\"1\">";
            StringBuilder content = new StringBuilder("<tr><th style=\"font-size: 18px\">设备条形码</th><th style=\"font-size: 18px\">归还时间</th></tr>");
            String end2 = "</table>" +
                    "</body>\r\n" +
                    "</html>";
            for (TbAssetBorrowRecord borrowRecord : collect) {
                String assetBarCode = borrowRecord.getAssetBarCode();
                Date returnDate = borrowRecord.getReturnDate();
                SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String returnTime = simpleDateFormat1.format(returnDate);
                content.append("<tr><td style=\"font-size: 18px\">").append(assetBarCode).append("</td>");
                content.append("<td style=\"font-size: 18px\">").append(returnTime).append("</td></tr>");
            }
            String html = start + content + end2;

            // TODO 邮箱记得更换回来
            emailUtils.sendHtmlMail("2786794141@qq.com", "待归还设备提醒", html);
        }
    }
}
