package com.zd.airbottle.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.zd.airbottle.domain.*;
import com.zd.airbottle.domain.dto.QpUseRecordDto;
import com.zd.airbottle.domain.vo.*;
import com.zd.airbottle.domain.vo.report.AirAmount;
import com.zd.airbottle.domain.vo.report.WebUseRecordVo;
import com.zd.airbottle.mapper.QpUseRecordMapper;
import com.zd.airbottle.service.*;
import com.zd.common.core.constant.HttpStatus;
import com.zd.common.core.constant.SecurityConstants;
import com.zd.common.core.domain.R;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.bean.TransferUtils;
import com.zd.common.security.utils.SaveUtil;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.model.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 使用记录Service业务层处理
 *
 * @author hanson
 */
@Service
public class QpUseRecordServiceImpl implements IQpUseRecordService {
    @Autowired
    private QpUseRecordMapper qpUseRecordMapper;

    @Autowired
    private RemoteUserService userService;
    @Autowired
    private IQpBottleStorageService storageService;

    @Autowired
    private IQpTaskService taskService;

    @Autowired
    private IQpAirGoodsConfigService goodsConfigService;
    @Autowired
    private IQpAirBottleConfigService bottleConfigService;

    @Autowired
    private IQpQualificationApplyService qualificationApplyService;

    @Autowired
    private IQpBottleStorageErrorService storageErrorService;

    /**
     * 查询使用记录
     *
     * @param id 使用记录主键
     * @return 使用记录
     */
    @Override
    public QpUseRecordVo selectQpUseRecordById(Long id) {
        QpUseRecord qpUseRecord = qpUseRecordMapper.selectQpUseRecordById(id);
        QpUseRecordVo recordVo = new QpUseRecordVo();
        BeanUtils.copyProperties(qpUseRecord, recordVo);

        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
        recordVo.setUseTimeApp(recordVo.getUseTime()!=null?sdf.format(recordVo.getUseTime()):null);
        recordVo.setBackTimeApp(recordVo.getBackTime()!=null?sdf.format(recordVo.getBackTime()):null);

        QpBottleStorageRVo storageRVo = storageService.getById(qpUseRecord.getStorageId());
        recordVo.setStorageVo(storageRVo);
        return recordVo;
    }

    /**
     * 查询使用记录列表
     *
     * @param qpUseRecord 使用记录
     * @return 使用记录
     */
    @Override
    public List<QpUseRecord> selectQpUseRecordList(QpUseRecord qpUseRecord) {
        return qpUseRecordMapper.selectQpUseRecordList(qpUseRecord);
    }

    /**
     * 新增使用记
     * value 说明：
     *
     * @param recordDto 使用记录
     * @return 结果
     */
    @Transactional
    @Override
    public Integer insertQpUseRecord(QpUseRecordDto recordDto) {
        int result = 1;
        R<LoginUser> userInfo = userService.getUserInfo(SecurityUtils.getUsername(), SecurityConstants.INNER);
        if (userInfo.getCode() != HttpStatus.SUCCESS || userInfo.getData() == null) {
            throw new ServiceException("用户账号异常");
        }
        //查询用户使用资格
        LoginUser user = userInfo.getData();
        QpQualificationApplyVO qualificationApply = new QpQualificationApplyVO();
        qualificationApply.setUserId(user.getUserid());
        List<QpQualificationApplyVO> qualificationApplies = qualificationApplyService.selectQpQualificationApplyList(qualificationApply);
        qualificationApplies = qualificationApplies.stream().filter(qa -> qa.getCenterAuditStatus() == 1).filter(qa -> qa.getEndTime().getTime() > Calendar.getInstance().getTime().getTime()).collect(Collectors.toList());
        if (qualificationApplies.isEmpty()) {
            result = 3;
        }

        Long storageId = recordDto.getStorageId();
        if (qpUseRecordMapper.isUse(storageId) != null) {
            result = 4;
        }
        if (result != 1) {
            return result;
        }

        //判断气瓶气压是否接近最低安全值
        BigDecimal beforeUse = recordDto.getBeforeUse();
        QpBottleStorageRVo bottleStorageRVo = storageService.getById(storageId);
        if (bottleStorageRVo == null) {
            throw new ServiceException("库存信息错误");
        }
        Long airBottleConfigId = bottleStorageRVo.getAirBottleConfigId();
        QpAirBottleConfig airBottleConfig = bottleConfigService.selectQpAirBottleConfigById(airBottleConfigId);
        QpAirGoodsConfig goodsConfig = goodsConfigService.selectQpAirGoodsConfigById(airBottleConfig.getConfigId());
        if (goodsConfig == null) {
            throw new ServiceException("货品配置错误");
        }
        BigDecimal minValue = goodsConfig.getMinValue();
        double currentValue = beforeUse.subtract(minValue).doubleValue();
        if (currentValue > 0 && currentValue <= 0.5) {
            result = 2;
        } else if (currentValue < 0) {
            throw new ServiceException("气瓶余量低于安全值，禁止使用");
        }
        recordDto.setContacts(user.getSysUser().getNickName())
                .setPhone(user.getSysUser().getPhonenumber())
                .setUseTime(Calendar.getInstance().getTime());
        QpUseRecord useRecord = new QpUseRecord();
        BeanUtils.copyProperties(recordDto, useRecord);
        QpBottleStorage bottleStorage = new QpBottleStorage();

        QpBottleStorageRVo storageRVo = storageService.getById(useRecord.getStorageId());
        if (storageRVo == null) {
            throw new ServiceException("气瓶不存在");
        }
        bottleStorage.setId(useRecord.getStorageId());
        bottleStorage.setStorageStatus(2);
        Integer isSurplus = recordDto.getIsSurplus();
        if (isSurplus == 1) {
            // 修改库存中气瓶余量标记
            bottleStorage.setIsSurplus(isSurplus);
            bottleStorage.setCurrentPressure(useRecord.getBeforeUse().doubleValue());
            QpBottleStorageError bottleStorageError = new QpBottleStorageError();
            bottleStorageError.setStorageId(storageRVo.getId())
                    .setBeforeEdit(BigDecimal.valueOf(storageRVo.getCurrentPressure()))
                    .setAfterEdit(useRecord.getBeforeUse());
            storageErrorService.insertQpBottleStorageError(bottleStorageError);
        }
        if (storageService.updateQpBottleStorage(bottleStorage) <= 0) {
            throw new ServiceException("入库数据异常");
        }
        //设置其他公共字段
        SaveUtil.setCommonAttr(useRecord);
        if (qpUseRecordMapper.insertQpUseRecord(useRecord) >= 1) {
            return result;
        }
        throw new ServiceException("使用登记记录错误");
    }

    /**
     * 修改使用记录
     *
     * @param qpUseRecord 使用记录
     * @return 结果
     */
    @Transactional
    @Override
    public int updateQpUseRecord(QpUseRecord qpUseRecord) {
        Long storageId = qpUseRecord.getStorageId();
        List<QpUseRecord> qpUseRecords = qpUseRecordMapper.selectQpUseRecordList(new QpUseRecord().setStorageId(storageId));
        qpUseRecords = qpUseRecords.stream().filter(ur -> ur.getAfterUse() == null).collect(Collectors.toList());
        if (qpUseRecords.size() != 1) {
            throw new ServiceException("数据异常");
        }
        QpUseRecord useRecord = qpUseRecords.get(0);

        BigDecimal afterUse = qpUseRecord.getAfterUse();
        BigDecimal beforeUse = useRecord.getBeforeUse();
        if (afterUse.compareTo(beforeUse) > 0) {
            throw new ServiceException("使用后的气压不能大于使用前的气压");
        }
        if (ObjectUtil.isNotEmpty(beforeUse) && ObjectUtil.isNotEmpty(afterUse)) {
            qpUseRecord.setAmount(beforeUse.subtract(afterUse));
            qpUseRecord.setBackTime(Calendar.getInstance().getTime());
        }
        //修改库存中气瓶余量
        QpBottleStorage bottleStorage = storageService.selectQpBottleStorageById(storageId);
        QpBottleStorage storage = new QpBottleStorage();
        storage.setStorageStatus(1);
        storage.setCurrentPressure(afterUse.doubleValue());
        storage.setId(bottleStorage.getId());
        storageService.updateQpBottleStorage(storage);

        qpUseRecord.setId(useRecord.getId());
        qpUseRecord.setUpdateTime(DateUtils.getNowDate());
        qpUseRecord.setUpdateBy(SecurityUtils.getUsername());
        return qpUseRecordMapper.updateQpUseRecord(qpUseRecord);
    }

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

    /**
     * 删除使用记录信息
     *
     * @param id 使用记录主键
     * @return 结果
     */
    @Override
    public int deleteQpUseRecordById(Long id) {
        return qpUseRecordMapper.deleteQpUseRecordById(id);
    }

    @Override
    public List<QpUseRecordVo> getListVo(List<QpUseRecord> list) {
        List<QpUseRecordVo> recordVos = TransferUtils.transferList(list, QpUseRecordVo.class);
        List<Long> storageIds = recordVos.stream().map(QpUseRecordVo::getStorageId).collect(Collectors.toList());
        List<QpBottleStorageRVo> bottleStorages = storageService.getByIds(storageIds);
        Map<Long, QpBottleStorageRVo> storageRVoMap = bottleStorages.stream().collect(Collectors.toMap(QpBottleStorageRVo::getId, b -> b));
        recordVos.forEach(u -> {
            Long storageId = u.getStorageId();
            if (storageRVoMap.containsKey(storageId)) {
                QpBottleStorageRVo bottleStorageRVo = storageRVoMap.get(storageId);
                u.setAirName(bottleStorageRVo.getAirName()).setStorageVo(bottleStorageRVo);
            }
        });
        return recordVos;
    }

    @Override
    public List<AirAmount> calcRepertory(String airName) {
        return qpUseRecordMapper.calcRepertory(airName);
    }

    /**
     * 用气量信息统计
     *
     * @param airName 气体名称
     * @return 数据集合
     */
    @Override
    public List<AirAmount> calcAmount(String airName) {
        return qpUseRecordMapper.calcAmount(airName);
    }

    @Override
    public List<AirAmount> calcApply(String airName) {
        return qpUseRecordMapper.calcApply(airName);
    }

    @Override
    public WebUseRecordVo getBottleInfo(Long id) {
        // 获取使用记录
        QpUseRecord useRecord = qpUseRecordMapper.selectQpUseRecordById(id);
        Long storageId = useRecord.getStorageId();
        List<QpUseRecord> useRecords = qpUseRecordMapper.selectQpUseRecordList(new QpUseRecord().setStorageId(storageId));
        return getWebUseRecordVo(useRecords, storageId);
    }

    /***
     * 根据入库id查询使用记录
     */
    @Override
    public List<QpUseRecordVo> getUseDetailsList(QpUseRecord qpUseRecord) {
        return qpUseRecordMapper.getUseDetailsList(qpUseRecord);
    }

    /***
     * 当前登录人 申请并入库的气瓶使用记录
     */
    @Override
    public List<QpUseRecordVo> getUseDetailsListByUserId(QpUseRecord qpUseRecord) {
        return qpUseRecordMapper.getUseDetailsListByUserId(qpUseRecord);
    }

    /***
     *当前登录人 气瓶使用记录-带规格
     */
    @Override
    public List<QpAirGoodsConfigRelationVo> getUseRecordSpecsList(QpAirGoodsConfigRelationVo vo) {
        return qpUseRecordMapper.getUseRecordSpecsList(vo);
    }

    /**
     * 气瓶使用记录查询
     */
    @Override
    public List<QpUseRecordVo> getUseDetailsListByStorageId(QpUseRecordVo useRecordVo) {
        return qpUseRecordMapper.getUseDetailsListByStorageId(useRecordVo);
    }

    @Override
    public List<QpUseRecordVo> getBottleInfoByStorageId(Long storageId) {
        return qpUseRecordMapper.getBottleInfoByStorageId(storageId);
    }

    @Override
    public List<QpUseRecord> getInUseByStorageIds(List<Long> storageIds) {
        return qpUseRecordMapper.getInUseByStorageIds(storageIds);
    }

    @Override
    public WebUseRecordVo getBottleRecord(Long storageId) {
        // 获取使用记录
        List<QpUseRecord> useRecords = qpUseRecordMapper.selectQpUseRecordList(new QpUseRecord().setStorageId(storageId));
        WebUseRecordVo recordVo = getWebUseRecordVo(useRecords, storageId);
        List<QpUseRecordVo> recordVos =Optional.ofNullable(recordVo.getRecordVos()).orElseGet(Collections::emptyList);

        Map<Long, Long> recordCount = recordVos.stream().collect(Collectors.groupingBy(QpUseRecordVo::getUserId, Collectors.counting()));

        recordVos = recordVos.stream().collect(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(QpUseRecordVo::getUserId))))
                .stream().map(r->r.setCountNumber(Math.toIntExact(recordCount.get(r.getUserId()))))
                .sorted(Comparator.comparing(QpUseRecordVo::getUseTime).reversed())
                .collect(Collectors.toList());

        recordVo.setRecordVos(recordVos);
        return recordVo;
    }

    /***
     * 根据入库id查询气瓶最后一条使用记录
     */
    @Override
    public QpUseRecord selectQpUseRecordByIdstorageId(Long storageId) {
        return qpUseRecordMapper.selectQpUseRecordByIdstorageId(storageId);
    }

    private WebUseRecordVo getWebUseRecordVo(List<QpUseRecord> useRecords, Long storageId) {
        List<QpUseRecordVo> recordVos = TransferUtils.transferList(useRecords, QpUseRecordVo.class);
        QpBottleStorageRVo storageRVo = storageService.getById(storageId);
        // 获取入库信息
        //气瓶名称等相关内容
        WebUseRecordVo recordVo = new WebUseRecordVo();
        BeanUtils.copyProperties(storageRVo, recordVo);

        Long taskId = storageRVo.getTaskId();
        // 获取申请信息
        QpTask qpTask = taskService.selectQpTaskById(taskId);
        QpTaskRVo taskRVo = new QpTaskRVo();
        BeanUtils.copyProperties(qpTask, taskRVo);
        taskRVo.setAmount(recordVos.stream().map(QpUseRecordVo::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        return recordVo.setRecordVos(recordVos).setTaskRVO(taskRVo);
    }
}
