package org.nl.acs.device.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import org.nl.acs.device.domain.DeviceAssigned;
import org.nl.acs.device.domain.DeviceExtra;
import org.nl.acs.device.service.DeviceExtraService;
import org.nl.acs.device.service.dto.DeviceAssignedDto;
import org.nl.acs.device.service.dto.DeviceExtraDto;
import org.nl.acs.device.service.dto.DeviceExtraQueryParam;
import org.nl.acs.device.service.mapper.DeviceExtraMapper;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.common.exception.BadRequestException;
import org.nl.acs.utils.ConvertUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.common.utils.SecurityUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author jiaolm
* @date 2023-05-09
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = DeviceExtraService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeviceExtraServiceImpl extends CommonServiceImpl<DeviceExtraMapper, DeviceExtra> implements DeviceExtraService {

    // private final RedisUtils redisUtils;
    private final DeviceExtraMapper deviceExtraMapper;

    @Override
    public PageInfo<DeviceExtraDto> queryAll(DeviceExtraQueryParam query, Pageable pageable) {
        IPage<DeviceExtra> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<DeviceExtra> page = deviceExtraMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, DeviceExtraDto.class);
    }

    @Override
    public List<DeviceExtraDto> queryAll(DeviceExtraQueryParam query){
        return ConvertUtil.convertList(deviceExtraMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), DeviceExtraDto.class);
    }

    @Override
    public DeviceExtra getById(String id) {
        return deviceExtraMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public DeviceExtraDto findById(String id) {
        return ConvertUtil.convert(getById(id), DeviceExtraDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DeviceExtraDto resources) {
        DeviceExtra entity = ConvertUtil.convert(resources, DeviceExtra.class);
        return deviceExtraMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(DeviceExtraDto resources){
        DeviceExtra entity = ConvertUtil.convert(resources, DeviceExtra.class);
        int ret = deviceExtraMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // delCaches(ids);
        return deviceExtraMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id){
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(String id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<String> ids) {
        for (String id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<DeviceExtraDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (DeviceExtraDto deviceExtra : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("字段编码", deviceExtra.getExtraCode());
              map.put("字段名字", deviceExtra.getExtraName());
              map.put("字段值", deviceExtra.getExtraValue());
              map.put("扩展值类型", deviceExtra.getValueType());
              map.put("扩展字段类型", deviceExtra.getFiledType());
              map.put("顺序号", deviceExtra.getOrderSeq());
              map.put("设备标识", deviceExtra.getDeviceId());
              map.put("设备编码", deviceExtra.getDeviceCode());
              map.put("备注", deviceExtra.getRemark());
              map.put("是否启用", deviceExtra.getIsActive());
              map.put("是否删除", deviceExtra.getIsDelete());
              map.put("创建者", deviceExtra.getCreateBy());
              map.put("创建时间", deviceExtra.getCreateTime());
              map.put("修改者", deviceExtra.getUpdateBy());
              map.put("修改时间", deviceExtra.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/


    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        IPage<DeviceExtra> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<DeviceExtra> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(DeviceExtra::getUpdate_time);
        IPage<DeviceExtra> deviceAssignedIPage = deviceExtraMapper.selectPage(queryPage,wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(deviceAssignedIPage, DeviceExtra.class));
        return json;
    }

    @Override
    public List<DeviceExtraDto> queryAll(Map whereJson) {
        List<DeviceExtra>  list= new LambdaQueryChainWrapper<>(deviceExtraMapper)
                .list();
        return ConvertUtil.convertList(list, DeviceExtraDto.class);
    }

//    @Override
//    public DeviceExtraDto findById(String extra_id) {
//        WQLObject wo = WQLObject.getWQLObject("acs_device_extra");
//        JSONObject json = wo.query("extra_id ='" + extra_id + "'").uniqueResult(0);
//        final DeviceExtraDto obj = json.toJavaObject(DeviceExtraDto.class);
//        return obj;
//    }

//    @Override
//    public DeviceExtraDto findByCode(String code) {
//        WQLObject wo = WQLObject.getWQLObject("acs_device_extra");
//        JSONObject json = wo.query("extra_code ='" + code + "'").uniqueResult(0);
//        final DeviceExtraDto obj = json.toJavaObject(DeviceExtraDto.class);
//        return obj;
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(DeviceExtraDto dto) {
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setExtra_id(IdUtil.simpleUUID());
        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);
        DeviceExtra entity = ConvertUtil.convert(dto, DeviceExtra.class);
        deviceExtraMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DeviceExtraDto dto) {
        DeviceExtraDto entity = this.findById(dto.getExtra_id());
        if (entity == null) throw new BadRequestException("被删除或无权限，操作失败!");

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setUpdate_time(now);
        dto.setUpdate_by(currentUsername);

        DeviceExtra deviceExtra = ConvertUtil.convert(dto, DeviceExtra.class);
        deviceExtraMapper.updateById(deviceExtra);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) {
        for (String extra_id : ids) {
            this.removeById(extra_id);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteAllByDeviceIds(String[] deviceIds) {
        LambdaQueryWrapper<DeviceExtra> wrapper = new LambdaQueryWrapper<>();
        for (String device_id : deviceIds) {
//            wrapper.in(DeviceExtra::getFiled_type,"02","03");
            wrapper.eq(DeviceExtra::getDevice_id, device_id);
            deviceExtraMapper.delete(wrapper);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createByDeviceConfig(JSONObject json, String filed_type) {
        //设备标识
        String device_id = json.getString("device_id");
        String deviceIds[] = {device_id};
        this.deleteAllByDeviceIds(deviceIds);
        //设备标识不算扩展属性
        json.remove("device_id");
        for (Object key : json.keySet()) {
            DeviceExtraDto dto = new DeviceExtraDto();
            dto.setExtra_code((String) key);
            dto.setDevice_code(json.getString("device_code"));
            dto.setDevice_id(device_id);
            dto.setExtra_name((String) key);
            dto.setExtra_value(String.valueOf(json.get(key)));
            dto.setFiled_type("01");
            dto.setOrder_seq(new BigDecimal(0));
            this.create(dto);
        }

    }
}
