package com.zd.airbottle.service.impl;

import com.alibaba.fastjson.JSON;
import com.zd.airbottle.domain.*;
import com.zd.airbottle.domain.vo.*;
import com.zd.airbottle.domain.vo.report.AirAmount;
import com.zd.airbottle.mapper.QpBottleStorageMapper;
import com.zd.airbottle.service.*;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.bean.TransferUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.system.api.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 气瓶入库Service业务层处理
 */
@Service
@Slf4j
public class QpBottleStorageServiceImpl implements IQpBottleStorageService {
    @Resource
    private QpBottleStorageMapper qpBottleStorageMapper;

    @Resource
    private TokenService tokenService;

    @Resource
    private IQpAirBottleConfigService bottleConfigService;

    @Resource
    private IQpTaskService taskService;

    @Resource
    private IQpUseRecordService recordService;

    @Resource
    private IQpUsegasApplyService usegasApplyService;

    @Resource
    private IQpAirGoodsConfigService goodsConfigService;

    @Resource
    private IQpRfidTagService qpRfidTagService;


    /**
     * 查询气瓶入库
     *
     * @param id 气瓶入库主键
     * @return 气瓶入库
     */
    @Override
    public QpBottleStorageVO selectQpBottleStorageById(Long id) {
        return qpBottleStorageMapper.selectQpBottleStorageById(id);
    }

    /**
     * 查询气瓶入库列表
     *
     * @param bottleStorage 气瓶入库
     * @return 气瓶入库
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.AIRBOTTLE_STORAGE)
    public List<QpBottleStorageVO> selectQpBottleStorageList(QpBottleStorageVO bottleStorage) {
        return qpBottleStorageMapper.selectQpBottleStorageList(bottleStorage);
    }

    /**
     * 信息记录-入库记录
     *
     * @param bottleStorage 信息记录-入库记录
     * @return 信息记录-入库记录集合
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.AIRBOTTLE_INFORMATIONRECORD)
    public List<QpBottleStorageVO> selectQpBottleStorageRecordList(QpBottleStorageVO bottleStorage) {
        return qpBottleStorageMapper.selectQpBottleStorageList(bottleStorage);
    }

    /**
     * 新增气瓶入库
     *
     * @param qpBottleStorage 气瓶入库
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertQpBottleStorage(QpBottleStorageVO qpBottleStorage) {

        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        if (qpBottleStorage.getAirStatus() == 1) {
            //拒收
            qpBottleStorage.setRejectionApplyUserid(sysUser.getUserId());
            qpBottleStorage.setRejectionApplyTime(new Date());
        } else if (qpBottleStorage.getAirStatus() == 0) {
            //入库

            //查询标签信息
            QpRfidTag rfidTag = qpRfidTagService.selectByTag(qpBottleStorage.getElectronicTag());
            if (rfidTag == null) {
                throw new ServiceException("未查询到该标签信息！");
            } else if (1 == rfidTag.getIsBind()) {
                throw new ServiceException("该标签已绑定！");
            }

            qpBottleStorage.setStorageUserid(sysUser.getUserId());
            qpBottleStorage.setAirNumber(String.valueOf(new Date().getTime()));
            qpBottleStorage.setStorageStatus(1);//闲置状态
            qpBottleStorage.setCurrentPressure(qpBottleStorage.getGasPressure());

            Map<String, String> map = new HashMap<>();
            map.put("airName", qpBottleStorage.getAirName());//气体名称
            map.put("gasLevel", qpBottleStorage.getConfigName());//规格
            map.put("companyName", qpBottleStorage.getCompanyName());//商家名称
            map.put("airConstituents", qpBottleStorage.getAirConstituents());//气体组分
            qpBottleStorage.setSpecificationName(JSON.toJSONString(map));

            //刷新标签状态
            QpRfidTag tag = qpRfidTagService.selectQpRfidTagById(rfidTag.getId());
            tag.setIsBind(1);//绑定
            qpRfidTagService.updateQpRfidTag(tag);
        }
        qpBottleStorage.setCreateTime(new Date());
        return qpBottleStorageMapper.insertQpBottleStorage(qpBottleStorage);
    }

    /**
     * 修改气瓶入库
     *
     * @param qpBottleStorage 气瓶入库
     * @return 结果
     */
    @Override
    public int updateQpBottleStorage(QpBottleStorage qpBottleStorage) {
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        if ("2".equals(qpBottleStorage.getRemark())) {
            //同意拒收
            qpBottleStorage.setRejectionUserid(sysUser.getUserId());
            qpBottleStorage.setRejectionTime(new Date());
        }
        return qpBottleStorageMapper.updateQpBottleStorage(qpBottleStorage);
    }

    /**
     * 批量删除气瓶入库
     *
     * @param ids 需要删除的气瓶入库主键
     * @return 结果
     */
    @Override
    public int deleteQpBottleStorageByIds(Long[] ids) {
        return qpBottleStorageMapper.deleteQpBottleStorageByIds(ids);
    }

    /**
     * 删除气瓶入库信息
     *
     * @param id 气瓶入库主键
     * @return 结果
     */
    @Override
    public int deleteQpBottleStorageById(Long id) {
        return qpBottleStorageMapper.deleteQpBottleStorageById(id);
    }

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

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

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

    /**
     * 入库表实验室关联查询
     */
    @Override
    public List<QpBottleStorageVO> selectQpBottleStorageByRelationSubject(QpBottleStorageVO qpBottleStorageVO) {
        return qpBottleStorageMapper.selectQpBottleStorageByRelationSubject(qpBottleStorageVO);
    }

    @Override
    public List<QpBottleStorageRVo> getByIds(List<Long> ids) {
        List<QpBottleStorage> storages = qpBottleStorageMapper.getByIds(ids);
        List<QpBottleStorageRVo> storageRVos = TransferUtils.transferList(storages, QpBottleStorageRVo.class);
        Map<Long, QpAirBottleConfigVo> configVoMap = getConfigMap(storageRVos.stream().map(QpBottleStorageRVo::getAirBottleConfigId).collect(Collectors.toList()), bottleConfigService);
        List<Long> taskIds = storages.stream().map(QpBottleStorage::getTaskId).collect(Collectors.toList());
        List<QpTask> tasks = taskService.getByIds(taskIds);
        Map<Long, QpTask> taskMap = tasks.stream().collect(Collectors.toMap(QpTask::getId, t -> t));

        storageRVos.forEach(s -> {
            Long configId = s.getAirBottleConfigId();
            if (configVoMap.containsKey(configId)) {
                QpAirBottleConfigVo configVo = configVoMap.get(configId);
                s.setConfigName(configVo.getConfigName())
                        .setCompanyName(configVo.getCompanyName())
                        .setAirConstituents(configVo.getAirConstituents())
                        .setAirName(configVo.getAirName())
                        .setConfigName(configVo.getConfigName());
            }
            Long taskId = s.getTaskId();
            if (taskMap.containsKey(taskId)) {
                QpTask task = taskMap.get(taskId);
                s.setLocation(task.getLocation());
                s.setSubjectId(task.getLocationId());
                s.setOwner(task.getUserName());
                s.setOwnerId(task.getUserId());
                s.setOwnerPhone(task.getPhone());
            }
        });
        return storageRVos;
    }

    @Override
    public QpBottleStorageRVo getById(Long id) {
        QpBottleStorage bottleStorage = qpBottleStorageMapper.selectQpBottleStorageById(id);
        return getQpBottleStorageRVo(bottleStorage);
    }

    private QpBottleStorageRVo getQpBottleStorageRVo(QpBottleStorage bottleStorage) {
        QpBottleStorageRVo storageRVo = new QpBottleStorageRVo();
        BeanUtils.copyProperties(bottleStorage, storageRVo);

        Long taskId = bottleStorage.getTaskId();
        QpTask task = taskService.selectQpTaskById(taskId);
        if (task != null) {
            storageRVo.setLocation(task.getLocation());
            storageRVo.setSubjectId(task.getLocationId());
            storageRVo.setOwner(task.getUserName());
            storageRVo.setOwnerId(task.getUserId());
            storageRVo.setOwnerPhone(task.getPhone());
        }
        Long airBottleConfigId = bottleStorage.getAirBottleConfigId();
        List<QpAirBottleConfigVo> bottleConfigVos = bottleConfigService.getByIds(Collections.singletonList(airBottleConfigId));
        Map<Long, QpAirBottleConfigVo> bottleConfigVoMap = bottleConfigVos.stream().collect(Collectors.toMap(QpAirBottleConfigVo::getId, c -> c));
        if (bottleConfigVoMap.containsKey(airBottleConfigId)) {
            QpAirBottleConfigVo configVo = bottleConfigVoMap.get(airBottleConfigId);
            storageRVo.setConfigName(configVo.getConfigName())
                    .setCompanyName(configVo.getCompanyName())
                    .setAirConstituents(configVo.getAirConstituents())
                    .setAirName(configVo.getAirName());
        }
        return storageRVo;
    }

    @Override
    public QpBottleStorageRVo getByElectronicTag(String electronicTag) {
        if (StringUtils.isAllEmpty(electronicTag)) {
            throw new ServiceException("电子标签不能为空");
        }

        QpBottleStorage bottleStorage = qpBottleStorageMapper.getByElectronicTag(electronicTag);
        QpBottleStorageRVo qpBottleStorageRVo=null;
        if (bottleStorage != null) {
            qpBottleStorageRVo = getQpBottleStorageRVo(bottleStorage);
            List<QpUseRecord> qpUseRecords = recordService.selectQpUseRecordList(new QpUseRecord().setStorageId(bottleStorage.getId()));
            List<QpUseRecord> useRecords = qpUseRecords.stream().filter(u -> u.getAfterUse() == null).collect(Collectors.toList());
            if (!useRecords.isEmpty()) {
                qpBottleStorageRVo.setCurrentStatus(4);
                qpBottleStorageRVo.setCurrentUserId(useRecords.get(0).getUserId());
                return qpBottleStorageRVo;
            }

            QpAirBottleConfig airBottleConfig = bottleConfigService.selectQpAirBottleConfigById(bottleStorage.getAirBottleConfigId());
            QpAirGoodsConfig goodsConfig = goodsConfigService.selectQpAirGoodsConfigById(airBottleConfig.getConfigId());
            if (goodsConfig == null) {
                throw new ServiceException("货品配置错误");
            }
            BigDecimal minValue = goodsConfig.getMinValue();
            double currentValue = BigDecimal.valueOf(bottleStorage.getCurrentPressure()).subtract(minValue).doubleValue();
            if (currentValue < 0) {
                qpBottleStorageRVo.setCurrentStatus(2);
                return qpBottleStorageRVo;
            }

            //查询用户使用资格
            QpUsegasApplyVO usegasApplyVO = new QpUsegasApplyVO();
            usegasApplyVO.setUserId(SecurityUtils.getUserId());
            usegasApplyVO.setUseGasName(qpBottleStorageRVo.getAirName());
            usegasApplyVO.setSubjectId(qpBottleStorageRVo.getSubjectId());
            usegasApplyVO.setCenterAuditStatus(1);

            List<QpUsegasApplyVO> usegasApplyVOS = usegasApplyService.selectQpUsegasApplyList(usegasApplyVO);
            // 用户没有用气资格
            if (usegasApplyVOS.isEmpty()) {
                qpBottleStorageRVo.setCurrentStatus(3);
            }
        }
        log.error("标签：{}\t气瓶未找到",electronicTag);
        return qpBottleStorageRVo;
    }

    /**
     * 解除绑定
     */
    @Override
    public int bottleStorageUnbind(Long id) {
        return qpBottleStorageMapper.bottleStorageUnbind(id);
    }

    /**
     * 绑定
     */
    @Override
    public int bottleStorageBinding(QpBottleStorage qpBottleStorage) {
        //查询标签是否被存在
        QpBottleStorageVO bottleStorageVO = new QpBottleStorageVO();
        bottleStorageVO.setElectronicTag(qpBottleStorage.getElectronicTag());
        List<QpBottleStorageVO> list = qpBottleStorageMapper.selectQpBottleStorageList(bottleStorageVO);
        if (!list.isEmpty()) {
            throw new ServiceException("该RFID已被绑定，请重新选择RFID标签");
        }
        int flg = qpBottleStorageMapper.bottleStorageBinding(qpBottleStorage);
        if (flg > 0) {
            //查询标签信息
            QpRfidTag rfidTag = qpRfidTagService.selectByTag(qpBottleStorage.getElectronicTag());
            if (rfidTag == null) {
                throw new ServiceException("未查询到该标签信息！");
            } else if (1 == rfidTag.getIsBind()) {
                throw new ServiceException("该标签已绑定！");
            }

            //刷新标签状态
            QpRfidTag tag = qpRfidTagService.selectQpRfidTagById(rfidTag.getId());
            tag.setIsBind(1);//绑定
            qpRfidTagService.updateQpRfidTag(tag);
        }
        return flg;
    }

    @Override
    public List<QpBottleStorage> getList(QpBottleStorage bottleStorage) {
        return qpBottleStorageMapper.getList(bottleStorage);
    }

    @Override
    public List<BottleStorageInfoVo> getStorageInfoList(BottleStorageInfoVo storageInfoVo) {
        return qpBottleStorageMapper.getStorageInfoList(storageInfoVo);
    }

    /***
     *供应商首页待办事项
     */
    @Override
    public List<QpBottleStorageVO> selectQpTaskListIndex(QpBottleStorageVO storageVO) {
        return qpBottleStorageMapper.selectQpTaskListIndex(storageVO);
    }

    /**
     * 查询入库的气瓶
     */
    @Override
    public List<QpBottleStorageVO> selectIntoStorageList(QpBottleStorageVO bottleStorageVO) {
        return qpBottleStorageMapper.selectIntoStorageList(bottleStorageVO);
    }

    /***
     *查询问题气瓶
     */
    @Override
    public List<QpBottleStorageVO> selectStorageListRelation(QpBottleStorageVO bottleStorageVO) {
        return qpBottleStorageMapper.selectStorageListRelation(bottleStorageVO);
    }

    /**
     * 查询实验室负责人
     */
    @Override
    public Map<String, Object> selectSubectDetalsById(Long subjectId) {
        return qpBottleStorageMapper.selectSubectDetalsById(subjectId);
    }

    static Map<Long, QpAirBottleConfigVo> getConfigMap(List<Long> configIds, IQpAirBottleConfigService bottleConfigService) {
        List<QpAirBottleConfigVo> bottleConfigVos = bottleConfigService.getByIds(configIds);
        return bottleConfigVos.stream().collect(Collectors.toMap(QpAirBottleConfigVo::getId, c -> c));
    }
}
