package com.ruoyi.ss.suit.service.impl;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.deviceSuit.domain.DeviceSuitQuery;
import com.ruoyi.ss.deviceSuit.domain.DeviceSuitVO;
import com.ruoyi.ss.deviceSuit.service.DeviceSuitConverter;
import com.ruoyi.ss.deviceSuit.service.DeviceSuitService;
import com.ruoyi.ss.suit.domain.Suit;
import com.ruoyi.ss.suit.domain.SuitBO;
import com.ruoyi.ss.suit.domain.SuitQuery;
import com.ruoyi.ss.suit.domain.SuitVO;
import com.ruoyi.ss.suit.mapper.SuitMapper;
import com.ruoyi.ss.suit.service.SuitConverter;
import com.ruoyi.ss.suit.service.SuitService;
import com.ruoyi.ss.suit.service.SuitValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 套餐Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-25
 */
@Service
public class SuitServiceImpl implements SuitService
{
    @Autowired
    private SuitMapper suitMapper;

    @Autowired
    private SuitConverter suitConverter;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private DeviceSuitService deviceSuitService;

    @Autowired
    private DeviceSuitConverter deviceSuitConverter;

    @Autowired
    private SuitValidator suitValidator;

    /**
     * 查询套餐
     *
     * @param suitId 套餐主键
     * @return 套餐
     */
    @Override
    public SuitVO selectSuitBySuitId(Long suitId)
    {
        return suitMapper.selectSuitBySuitId(suitId);
    }

    /**
     * 查询套餐列表
     *
     * @param suit 套餐
     * @return 套餐
     */
    @Override
    public List<SuitVO> selectSuitList(SuitQuery suit)
    {
        return suitMapper.selectSuitList(suit);
    }

    /**
     * 新增套餐
     *
     * @param suit 套餐
     * @return 结果
     */
    @Override
    public int insertSuit(SuitBO suit)
    {
        this.preInsert(suit);

        Integer result = transactionTemplate.execute(status -> {
            // 新增
            int insert = suitMapper.insertSuit(suit);
            ServiceUtil.assertion(insert != 1, "新增套餐失败");

            // 新增关联
            int batchInsert = deviceSuitService.batchInsert(deviceSuitConverter.toPo(suit));
            ServiceUtil.assertion(batchInsert != suit.getDeviceIds().size(), "新增关联失败");

            // 后校验
            SuitVO vo = selectSuitBySuitId(suit.getSuitId());
            suitValidator.afterCheck(vo, null);

            return insert;
        });

        return result == null ? 0 : result;
    }

    @Override
    public int setSort(List<? extends Suit> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return 0;
        }
        return suitMapper.batchUpdateSort(list);
    }

    /**
     * 插入前操作
     */
    private void preInsert(Suit suit) {
        suit.setCreateTime(DateUtils.getNowDate());
    }

    /**
     * 修改套餐
     *
     * @param suit 套餐
     * @return 结果
     */
    @Override
    public int updateSuit(SuitBO suit) {
        SuitVO old = selectSuitBySuitId(suit.getSuitId());
        ServiceUtil.assertion(old == null, "待修改的数据不存在");

        suit.setUpdateTime(DateUtils.getNowDate());
        Integer result = transactionTemplate.execute(status -> {
            // 更新数据
            int update = suitMapper.updateSuit(suit);
            ServiceUtil.assertion(update != 1, "更新数据失败");

            // 更新设备关联
            if (suit.getDeviceIds() != null) {
                // 删除原有关联
                deviceSuitService.deleteBySuitId(suit.getSuitId());
                // 创建新的关联
                deviceSuitService.batchInsert(deviceSuitConverter.toPo(suit));
            }

            // 后校验
            SuitVO vo = selectSuitBySuitId(suit.getSuitId());
            suitValidator.afterCheck(vo, old);

            return update;
        });

        return result == null ? 0 : result;
    }

    /**
     * 批量删除套餐
     *
     * @param suitIds 需要删除的套餐主键
     * @return 结果
     */
    @Override
    public int deleteSuitBySuitIds(Long[] suitIds)
    {
        return suitMapper.deleteSuitBySuitIds(suitIds);
    }

    /**
     * 删除套餐信息
     *
     * @param suitId 套餐主键
     * @return 结果
     */
    @Override
    public int deleteSuitBySuitId(Long suitId)
    {
        return suitMapper.deleteSuitBySuitId(suitId);
    }

    /**
     * 批量逻辑删除
     *
     * @param suitIds
     * @return
     */
    @Override
    public int logicDel(List<Long> suitIds) {
        if (CollectionUtils.isEmptyElement(suitIds)) {
            return 0;
        }
        Integer result = transactionTemplate.execute(status -> {
            // 删除套餐
            int del = suitMapper.logicDel(suitIds);
            // 删除套餐关联关系
            deviceSuitService.deleteBySuitIds(suitIds);
            return del;
        });

        return result == null ? 0 : result;
    }

    /**
     * 通用查询映射方法
     * @param query 查询条件
     * @param keyMapper 映射方法,需要保证唯一性
     */
    @Override
    public <K> Map<K, SuitVO> selectMap(SuitQuery query, Function<? super SuitVO, ? extends K> keyMapper) {
        List<SuitVO> list = selectSuitList(query);
        if (CollectionUtils.isEmptyElement(list)) {
            return Collections.emptyMap();
        }
        return list.stream().collect(Collectors.toMap(keyMapper, item -> item));
    }

    /**
     * 通用分组方法
     *
     * @param query     查询条件
     * @param keyMapper 分组映射方法，需要保证唯一性
     */
    @Override
    public <K> Map<K, List<SuitVO>> selectGroup(SuitQuery query, Function<? super SuitVO, ? extends K> keyMapper) {
        List<SuitVO> list = selectSuitList(query);
        if (CollectionUtils.isEmptyElement(list)) {
            return Collections.emptyMap();
        }
        return list.stream()
                .filter(item -> Objects.nonNull(keyMapper.apply(item)))
                .collect(Collectors.groupingBy(keyMapper));
    }

    /**
     * 根据设备查询套餐列表
     *
     * @param deviceId
     * @return
     */
    @Override
    public List<SuitVO> selectByDeviceId(Long deviceId) {
        if (deviceId == null) {
            return Collections.emptyList();
        }
        DeviceSuitQuery query = new DeviceSuitQuery();
        query.setDeviceId(deviceId);
        List<DeviceSuitVO> deviceSuitList = deviceSuitService.selectDeviceSuitList(query);
        return deviceSuitList.stream().map(DeviceSuitVO::getSuit).collect(Collectors.toList());
    }

    /**
     * 查询套餐数量
     *
     * @param query
     * @return
     */
    @Override
    public int selectCount(SuitQuery query) {
        return suitMapper.selectCount(query);
    }

    @Override
    public int logicDelByDeviceId(Long deviceId) {
        if (deviceId == null) {
            return 0;
        }
        // TODO 删除关联关系
        return 0;
    }

    @Override
    public SuitVO selectOne(SuitQuery query) {
        return suitMapper.selectOne(query);
    }

}
