package com.usky.iot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.iot.domain.DmpDeviceStatus;
import com.usky.iot.domain.DmpDeviceType;
import com.usky.iot.domain.DmpProductAttribute;
import com.usky.iot.domain.DmpProductInfo;
import com.usky.iot.mapper.DmpDeviceTypeMapper;
import com.usky.iot.service.DmpDeviceTypeService;
import com.usky.common.mybatis.core.AbstractCrudService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 设备信息类型 服务实现类
 * </p>
 *
 * @author ya
 * @since 2023-06-06
 */
@Service
public class DmpDeviceTypeServiceImpl extends AbstractCrudService<DmpDeviceTypeMapper, DmpDeviceType> implements DmpDeviceTypeService {
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(DmpDeviceType dmpDeviceType) {
        if (checkNameUnique(dmpDeviceType)) {
            throw new BusinessException("新增设备类型'" + dmpDeviceType.getTypeName() + "'失败，该设备类型已经存在");
        }
        if (checkTypeCodeUnique(dmpDeviceType)) {
            throw new BusinessException("新增设备类型'" + dmpDeviceType.getTypeName() + "'失败，该设备类型编码已经存在");
        }
        dmpDeviceType.setCreatedBy(SecurityUtils.getUsername());
        dmpDeviceType.setCreatedTime(LocalDateTime.now());
        dmpDeviceType.setTenantId(SecurityUtils.getTenantId());
        this.save(dmpDeviceType);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(DmpDeviceType dmpDeviceType) {
        if (checkNameUnique(dmpDeviceType)) {
            throw new BusinessException("修改设备类型'" + dmpDeviceType.getTypeName() + "'失败，该设备类型已经存在");
        }
        if (checkTypeCodeUnique(dmpDeviceType)) {
            throw new BusinessException("修改设备类型'" + dmpDeviceType.getTypeName() + "'失败，该设备类型编码已经存在");
        }
        dmpDeviceType.setUpdatedBy(SecurityUtils.getUsername());
        dmpDeviceType.setUpdatedTime(LocalDateTime.now());
        this.updateById(dmpDeviceType);
    }

    @Override
    public boolean checkNameUnique(DmpDeviceType dmpDeviceType) {
        Integer id = null == dmpDeviceType.getId() ? -1 : dmpDeviceType.getId();
        LambdaQueryWrapper<DmpDeviceType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(DmpDeviceType::getTypeName, dmpDeviceType.getTypeName());
        DmpDeviceType one = this.getOne(queryWrapper);
        return null != one && !Objects.equals(one.getId(), id);
    }

    @Override
    public boolean checkTypeCodeUnique(DmpDeviceType dmpDeviceType) {
        Integer id = null == dmpDeviceType.getId() ? -1 : dmpDeviceType.getId();
        LambdaQueryWrapper<DmpDeviceType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(DmpDeviceType::getTypeCode, dmpDeviceType.getTypeCode());
        DmpDeviceType one = this.getOne(queryWrapper);
        return null != one && !Objects.equals(one.getId(), id);
    }

    @Override
    public void remove(Integer id) {
        DmpDeviceType one = this.getById(id);
        if(one == null){
            throw new BusinessException("设备类型不存在");
        }

        List<DmpProductInfo> list = baseMapper.getProductInfoList(one.getTypeCode());
        if(list.size() > 0){
            throw new BusinessException("当前类型已有关联产品，不可删除");
        }

        this.removeById(id);
    }

    @Override
    public CommonPage<DmpDeviceType> getDeviceTypeList(String typeCode, String typeName, Integer typeDomain, Integer pageNum, Integer pageSize) {
        IPage<DmpDeviceType> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<DmpDeviceType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(typeCode), DmpDeviceType::getTypeCode, typeCode)
                .like(StringUtils.isNotBlank(typeName), DmpDeviceType::getTypeName, typeName)
                .eq(typeDomain != null,DmpDeviceType::getTypeDomain,typeDomain);
        page = this.page(page, queryWrapper);
        return new CommonPage<>(page.getRecords(), page.getTotal(), pageSize, pageNum);
    }

    @Override
    public List<DmpDeviceType> tenantIdDeviceTypeList(){
        List<DmpDeviceType> list = new ArrayList<>();
        List<String> typeList = new ArrayList<>();
        List<DmpProductInfo> list1 = baseMapper.getProductInfo(SecurityUtils.getTenantId());
        if(CollectionUtils.isNotEmpty(list1)){
            for(int i=0;i<list1.size();i++){
                typeList.add(list1.get(i).getDeviceType().toString());
            }
        }
        if(CollectionUtils.isNotEmpty(typeList)){
            LambdaQueryWrapper<DmpDeviceType> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(DmpDeviceType::getTypeCode, typeList);
            list = this.list(queryWrapper);
        }

        return list;
    }

    @Override
    public List<Map<String, Object>> getDeviceTypeImges(List<Integer> deviceTypes) {
        QueryWrapper<DmpDeviceType> query = Wrappers.query();
        query.select("type_img as typeImg","type_code as deviceType")
                .in(CollectionUtil.isNotEmpty(deviceTypes),"type_code",deviceTypes);
        return this.listMaps(query);
    }
}