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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.mapper.DeviceMapper;
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.common.utils.FileUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.acs.device.domain.DeviceErpmapping;
import org.nl.acs.device.service.DeviceErpmappingService;
import org.nl.acs.device.service.dto.AcsDeviceErpmappingDto;
import org.nl.acs.device.service.dto.DeviceErpmappingQueryParam;
import org.nl.acs.device.service.mapper.DeviceErpmappingMapper;
import org.nl.common.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

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

    // private final RedisUtils redisUtils;
    private final DeviceErpmappingMapper deviceErpmappingMapper;
    private final DeviceMapper deviceMapper;
    @Override
    public PageInfo<AcsDeviceErpmappingDto> queryAll(DeviceErpmappingQueryParam query, Pageable pageable) {
        IPage<DeviceErpmapping> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<DeviceErpmapping> page = deviceErpmappingMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, AcsDeviceErpmappingDto.class);
    }

    @Override
    public List<AcsDeviceErpmappingDto> queryAll(DeviceErpmappingQueryParam query){
        return ConvertUtil.convertList(deviceErpmappingMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), AcsDeviceErpmappingDto.class);
    }

    @Override
    public DeviceErpmapping getById(String id) {
        return deviceErpmappingMapper.selectById(id);
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(AcsDeviceErpmappingDto resources) {
        DeviceErpmapping entity = ConvertUtil.convert(resources, DeviceErpmapping.class);
        return deviceErpmappingMapper.insert(entity);
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // delCaches(ids);
        return deviceErpmappingMapper.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);
    }
    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        String device_code = (String) whereJson.get("device_code");
        String erp_code = (String) whereJson.get("erp_code");
        IPage<DeviceErpmapping> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<DeviceErpmapping> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(device_code),DeviceErpmapping::getDevice_code,device_code);
        wrapper.eq(StringUtils.isNotBlank(erp_code),DeviceErpmapping::getErp_code,erp_code);
        wrapper.orderByDesc(DeviceErpmapping::getDevice_code);
        IPage<DeviceErpmapping> IPage = deviceErpmappingMapper.selectPage(queryPage,wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(IPage, DeviceErpmapping.class));
        return json;
    }

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

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

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(AcsDeviceErpmappingDto dto) {
        String device_code = dto.getDevice_code();
        if (StrUtil.isEmpty(device_code)) {
            throw new BadRequestException("设备编号不能为空！");
        }
//        JSONObject device = WQLObject.getWQLObject("acs_device").query("device_code = '" + device_code + "'").uniqueResult(0);
        Device device= new LambdaQueryChainWrapper<>(deviceMapper)
                .eq(Device::getDevice_code,device_code)
                .one();
//        JSONObject device = JSONObject.parseObject(JSON.toJSONString(device));
        //判断该设备是否已经插入映射表
//        JSONObject map = WQLObject.getWQLObject("acs_device_erpMapping").query("device_id = '" + device.getString("device_id") + "'").uniqueResult(0);
        DeviceErpmapping map= new LambdaQueryChainWrapper<>(deviceErpmappingMapper)
                .eq(DeviceErpmapping::getDevice_id,device.getDevice_id())
                .one();
        if (map != null) {
            throw new BadRequestException("该设备已经插入过映射表，请重新选择！");
        }
        dto.setDevice_id(device.getDevice_id());
        dto.setDevice_name(device.getDevice_name());
        dto.setDevice_type(device.getDevice_type());
        dto.setDriver_code(device.getDriver_code());

        DeviceErpmapping entity = ConvertUtil.convert(dto, DeviceErpmapping.class);
        deviceErpmappingMapper.insert(entity);
    }

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

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();

        DeviceErpmapping deviceErpmapping = ConvertUtil.convert(dto, DeviceErpmapping.class);
        deviceErpmappingMapper.updateById(deviceErpmapping);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) {
        for (String device_id : ids) {
            deviceErpmappingMapper.deleteById(device_id);
        }
    }

    @Override
    public void download(List<AcsDeviceErpmappingDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AcsDeviceErpmappingDto acsDeviceErpmapping : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("设备编码", acsDeviceErpmapping.getDevice_code());
            map.put("设备名字", acsDeviceErpmapping.getDevice_name());
            map.put("设备类型", acsDeviceErpmapping.getDevice_type());
            map.put("设备驱动类型", acsDeviceErpmapping.getDriver_code());
            map.put("所属ERP设备", acsDeviceErpmapping.getErp_code());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
