package com.zd.airbottle.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.zd.airbottle.constant.Constants;
import com.zd.airbottle.domain.QpAirBottle;
import com.zd.airbottle.domain.QpAirBottleConfig;
import com.zd.airbottle.domain.QpSupplier;
import com.zd.airbottle.domain.dto.QpAirBottleConfigDto;
import com.zd.airbottle.domain.dto.QpAirBottleDto;
import com.zd.airbottle.domain.vo.QpAirBottleConfigVo;
import com.zd.airbottle.domain.vo.QpAirBottleRVo;
import com.zd.airbottle.domain.vo.QpAirGoodsConfigVo;
import com.zd.airbottle.mapper.QpAirBottleMapper;
import com.zd.airbottle.service.IQpAirBottleConfigService;
import com.zd.airbottle.service.IQpAirBottleService;
import com.zd.airbottle.service.IQpAirGoodsConfigService;
import com.zd.airbottle.service.IQpSupplierService;
import com.zd.airbottle.utils.SupplierUtil;
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.service.TokenService;
import com.zd.common.security.utils.SaveUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 气瓶Service业务层处理
 */
@Service
public class QpAirBottleServiceImpl implements IQpAirBottleService {
    @Autowired
    private QpAirBottleMapper qpAirBottleMapper;
    @Autowired
    private IQpAirBottleConfigService configService;
    @Resource
    private IQpSupplierService supplierService;
    @Autowired
    private IQpAirGoodsConfigService goodsConfigService;

    @Resource
    private TokenService tokenService;

    /**
     * 查询气瓶
     *
     * @param id 气瓶主键
     * @return 气瓶
     */
    @Override
    public QpAirBottle selectQpAirBottleById(Long id) {
        return qpAirBottleMapper.selectQpAirBottleById(id);
    }

    /**
     * 查询气瓶列表
     *
     * @param airBottles 气瓶
     * @return 气瓶
     */
    @Override
    public List<QpAirBottleRVo> selectQpAirBottleList(List<QpAirBottle> airBottles) {
        //获取气瓶装置配置
        List<QpAirBottleConfig> configs = configService.getByBottleIds(airBottles.stream().map(QpAirBottle::getId).collect(Collectors.toList()));
        //获取根配置及其父类的相关属性
        Map<Long, QpAirGoodsConfigVo> configVoMap = goodsConfigService.getInfoByConfigIds(configs.stream().map(QpAirBottleConfig::getConfigId).collect(Collectors.toList()));
        //组装数据
        List<QpAirBottleConfigVo> bottleConfigVos = TransferUtils.transferList(configs, QpAirBottleConfigVo.class);
        bottleConfigVos.forEach(c -> {
            Long configId = c.getConfigId();
            if (configVoMap.containsKey(configId)) {
                QpAirGoodsConfigVo goodsConfigVo = configVoMap.get(configId);
                c.setConfigName(goodsConfigVo.getName());
            }
        });
        //对装配好的配置数据进行分组
        Map<Long, List<QpAirBottleConfigVo>> bottleConfigMap = bottleConfigVos.stream().collect(Collectors.groupingBy(QpAirBottleConfigVo::getBottleId));
        List<QpSupplier> suppliers = supplierService.selectQpSupplierListByIds(airBottles.stream().map(QpAirBottle::getSupplierId).toArray(Long[]::new));
        Map<Long, String> supplierMap = suppliers.stream().collect(Collectors.toMap(QpSupplier::getId, QpSupplier::getCompanyName));
        List<QpAirBottleRVo> bottleRVos = TransferUtils.transferList(airBottles, QpAirBottleRVo.class);
        bottleRVos.forEach(a -> {
            Long id = a.getId();
            if (bottleConfigMap.containsKey(id)) {
                a.setConfigVos(bottleConfigMap.get(id));
            }
            Long supplierId = a.getSupplierId();
            if (supplierMap.containsKey(supplierId)) {
                a.setCompanyName(supplierMap.get(supplierId));
            }
        });
        return bottleRVos;
    }

    @Override
    public List<QpAirBottle> getList(QpAirBottle qpAirBottle) {
        return qpAirBottleMapper.selectQpAirBottleList(qpAirBottle);
    }

    @Override
    public List<QpAirBottleConfig> getBySupplierId(Long supplierId) {
        List<QpAirBottle> bottles = qpAirBottleMapper.selectQpAirBottleList(new QpAirBottle().setSupplierId(supplierId));
        if (bottles.isEmpty()){
            return Collections.emptyList();
        }
        List<Long> bottleIds = bottles.stream().map(QpAirBottle::getId).collect(Collectors.toList());
        return configService.getByBottleIds(bottleIds);
    }

    /**
     * 根据气瓶ID查询气瓶
     *
     * @param id 气瓶id
     * @return 气瓶信息
     */
    @Override
    public QpAirBottleRVo getInfo(Long id) {
        QpAirBottle bottle = new QpAirBottle().setId(id);
        List<QpAirBottleRVo> bottleRVos = selectQpAirBottleList(getList(bottle));
        if (CollUtil.isNotEmpty(bottleRVos)) {
            return bottleRVos.get(0);
        }
        throw new ServiceException("未找到气瓶信息");
    }

    /**
     * 新增气瓶
     *
     * @param bottleDto 气瓶
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertQpAirBottle(QpAirBottleDto bottleDto) {
        QpAirBottle bottle = new QpAirBottle();
        BeanUtils.copyProperties(bottleDto, bottle);
        QpSupplier qpSupplier = supplierService.selectQpSupplierByAccountId(SecurityUtils.getUserId());
        bottle.setSupplierId(qpSupplier.getId()).setCenterAuditStatus(Constants.SUPPLIER_NOT_AUDIT);
        //设置其他公共字段
        SaveUtil.setCommonAttr(bottle);
        if (qpAirBottleMapper.insertQpAirBottle(bottle) > 0) {
            List<QpAirBottleConfigDto> configDtos = bottleDto.getConfigDtos();
            configDtos.forEach(c -> {
                QpAirBottleConfig config = new QpAirBottleConfig();
                BeanUtils.copyProperties(c, config);
                config.setBottleId(bottle.getId());
                configService.insertQpAirBottleConfig(config);
            });
            return 1;
        }
        return -1;
    }

    /**
     * 修改气瓶
     *
     * @param qpAirBottle 气瓶
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQpAirBottle(QpAirBottle qpAirBottle) {
        qpAirBottle.setUpdateTime(DateUtils.getNowDate());
        qpAirBottle.setUpdateBy(SecurityUtils.getUsername());
        return qpAirBottleMapper.updateQpAirBottle(qpAirBottle);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(QpAirBottleDto bottleDto) {
        QpAirBottle bottle = new QpAirBottle();
        BeanUtils.copyProperties(bottleDto, bottle);
        bottle.setUpdateTime(DateUtils.getNowDate());
        bottle.setUpdateBy(SecurityUtils.getUsername());

        if (qpAirBottleMapper.updateQpAirBottle(bottle) > 0) {
            List<QpAirBottleConfig> configs = configService.getByBottleId(bottle.getId());
            List<Long> configIds = Collections.synchronizedList(configs.stream().map(QpAirBottleConfig::getId).collect(Collectors.toList()));
            List<QpAirBottleConfigDto> configDtos = bottleDto.getConfigDtos();
            configDtos.forEach(c -> {
                QpAirBottleConfig config = new QpAirBottleConfig().setBottleId(bottle.getId());
                BeanUtils.copyProperties(c, config);
                if (c.getId() == null) {
                    config.setBottleId(bottle.getId());
                    configService.insertQpAirBottleConfig(config);
                } else {
                    configIds.remove(c.getId());
                    configService.updateQpAirBottleConfig(config);
                }
            });
            if (CollUtil.isNotEmpty(configIds)) {
                configService.deleteQpAirBottleConfigByIds(configIds.toArray(new Long[0]));
            }
            return 1;
        }
        return -1;
    }

    /**
     * 批量删除气瓶
     *
     * @param ids 需要删除的气瓶主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQpAirBottleByIds(Long[] ids) {
        List<QpAirBottleConfig> configs = configService.getByBottleIds(Arrays.asList(ids));
        if (CollUtil.isNotEmpty(configs)) {
            configService.deleteQpAirBottleConfigByIds(configs.stream().map(QpAirBottleConfig::getId).toArray(Long[]::new));
        }
        return qpAirBottleMapper.deleteQpAirBottleByIds(ids);
    }

    /**
     * 删除气瓶信息
     *
     * @param id 气瓶主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQpAirBottleById(Long id) {
        return qpAirBottleMapper.deleteQpAirBottleById(id);
    }

    @Override
    public Map<Long, Integer> getBySupplierIds(List<Long> supplierIds) {
        List<QpAirBottleRVo> bottleRVos = qpAirBottleMapper.getBySupplierIds(supplierIds);
        return bottleRVos.stream().collect(Collectors.toMap(QpAirBottleRVo::getSupplierId, QpAirBottleRVo::getSum));
    }

    @Override
    public List<QpAirBottleRVo> getByIds(List<Long> bottleIds) {
        if (bottleIds.isEmpty()) {
            return new ArrayList<>();
        }
        List<QpAirBottle> bottles = qpAirBottleMapper.getByIds(bottleIds);
        List<QpAirBottleRVo> bottleRVos = TransferUtils.transferList(bottles, QpAirBottleRVo.class);
        List<QpSupplier> suppliers = supplierService.getByIds(bottles.stream().map(QpAirBottle::getSupplierId).collect(Collectors.toList()));
        Map<Long, String> supplierMap = suppliers.stream().collect(Collectors.toMap(QpSupplier::getId, QpSupplier::getCompanyName));
        bottleRVos.forEach(b -> {
            Long supplierId = b.getSupplierId();
            if (supplierMap.containsKey(supplierId)) {
                b.setCompanyName(supplierMap.get(supplierId));
            }
        });
        return bottleRVos;
    }

    @Override
    public List<QpAirBottle> getSupplierList(QpAirBottle qpAirBottle) {

        return getList(qpAirBottle);
    }

    @Override
    public void setSupplier(QpAirBottle qpAirBottle) {
        QpSupplier supplier = SupplierUtil.getSupplier(tokenService, supplierService);
        qpAirBottle.setSupplierId(supplier.getId());
    }
}