package com.kym.service.impl;

import com.kym.common.exception.BusinessException;
import com.kym.common.utils.CommUtil;
import com.kym.entity.DeviceRelation;
import com.kym.mapper.DeviceRelationMapper;
import com.kym.service.DeviceRelationService;
import com.kym.service.cache.KymCache;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author skyline
 * @since 2024-11-11
 */
@Service
public class DeviceRelationServiceImpl extends MyBaseServiceImpl<DeviceRelationMapper, DeviceRelation> implements DeviceRelationService {

    @PostConstruct
    private void init() {
        list().forEach(item -> {
            // 初始化短编号和设备信息的关联
            KymCache.INSTANCE.putWashShortId2ProductKeyAndDeviceName(Map.of(item.getShortId(), item.getProductKey() + "," + item.getDeviceName()));
            // shortId和stationId的对应关系
            KymCache.INSTANCE.putShortId2StationId(Map.of(item.getShortId(), item.getStationId()));
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DeviceRelation deviceRelation) {
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(deviceRelation.getShortId()), "短编号不能为空");
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(deviceRelation.getProductKey()), "产品key不能为空");
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(deviceRelation.getDeviceName()), "设备名称不能为空");
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(deviceRelation.getStationId()), "站点id不能为空");

        Long count = lambdaQuery()
                .eq(DeviceRelation::getShortId, deviceRelation.getShortId())
                .count();
        CommUtil.asserts(count == 0, "该短编号已存在");

        count = lambdaQuery()
                .eq(DeviceRelation::getProductKey, deviceRelation.getProductKey())
                .eq(DeviceRelation::getDeviceName, deviceRelation.getDeviceName())
                .count();
        CommUtil.asserts(count == 0, "该设备已绑定短编号");

        save(deviceRelation);

        // 同步到缓存
        KymCache.INSTANCE.putWashShortId2ProductKeyAndDeviceName(Map.of(deviceRelation.getShortId(), deviceRelation.getProductKey() + "," + deviceRelation.getDeviceName()));
        KymCache.INSTANCE.putShortId2StationId(Map.of(deviceRelation.getShortId(), deviceRelation.getStationId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByDevice(String productKey, String deviceName) {
        var relation = lambdaQuery()
                .eq(DeviceRelation::getProductKey, productKey)
                .eq(DeviceRelation::getDeviceName, deviceName)
                .one();
        if (relation != null) {
            removeById(relation.getId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeById(Long id) {
        var relation = getById(id);
        if (relation == null) {
            throw new BusinessException("设备关系不存在");
        }
        super.removeById(id);
        KymCache.INSTANCE.removeWashShortIdMapping(relation.getShortId());
        KymCache.INSTANCE.removeShortId2StationId(relation.getShortId());
    }

    @Override
    public List<DeviceRelation> listByStationId(String stationId) {
        return lambdaQuery()
                .eq(DeviceRelation::getStationId, stationId)
                .orderByAsc(DeviceRelation::getShortId)
                .list();
    }

}
