package com.casic.missiles.modular.web.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.casic.missiles.core.base.response.SuccessResponseData;
import com.casic.missiles.core.common.service.ICommonPermissionService;
import com.casic.missiles.core.exception.GunsException;
import com.casic.missiles.core.exception.GunsExceptionEnum;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.dao.BusNbDeviceMapper;
import com.casic.missiles.modular.system.model.BusNbDevice;
import com.casic.missiles.modular.system.model.ConfigNbCucc;
import com.casic.missiles.modular.system.model.Device;
import com.casic.missiles.modular.web.service.IBusNbDeviceService;
import com.casic.missiles.modular.web.service.IConfigNbCuccService;
import com.casic.missiles.nbiot.Authentication;
import com.casic.missiles.nbiot.DeviceRegister;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lwh123
 * @since 2018-11-16
 */
@Service
@Transactional
public class BusNbDeviceServiceImpl extends ServiceImpl<BusNbDeviceMapper, BusNbDevice> implements IBusNbDeviceService {

    @Autowired
    private Validator validator;
    @Autowired
    private ICommonPermissionService permissionService;

    @Autowired
    private IConfigNbCuccService configNbCuccService;

    @Override
    public List<BusNbDevice> getListByDevcode(String devcode) {
        return this.baseMapper.getListByDevcode(devcode);
    }

    @Override
    public SuccessResponseData registDevice(BusNbDevice busNbDevice) {
        // 返回的默认值
        SuccessResponseData result = new SuccessResponseData();
        result.setCode(200);
        result.setMessage("注册成功");

        // 查找登录用户所在的部门
        Long deptid = permissionService.getCurrLoginUser().getDeptId();
        if (null == deptid) {
            // 没有找到登录用户部门，直接抛出异常
            throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
        }

        // 首先判断本地数据库中是否已经有相同的nodeid
        List<BusNbDevice> tmpList = this.baseMapper.getByNodeId(busNbDevice.getNodeid());
        if (null == tmpList || tmpList.isEmpty() == true) {
            // 返回结果为空说明本地库中不存在，执行注册操作

            // 判定devcode是否重复
            List<BusNbDevice> tmp2List = this.baseMapper.getByDevcode(busNbDevice.getDevcode());
            if (null != tmp2List && tmp2List.isEmpty() == false) {
                result.setCode(500);
                result.setMessage("注册失败，设备编号重复");

                return result;
            }

            // 查询部门所对应的电信平台配置参数
            ConfigNbCucc cucc = configNbCuccService.getConfigByDept(deptid);
            if (null == cucc) {
                result.setCode(500);
                result.setMessage("注册失败，未找到部门电信平台配置参数");

                return result;
            }

            String accessToken = null;
            try {
                // 1首先在NB平台鉴权
                SuccessResponseData accessResult = Authentication.doAuth(cucc.getBaseUrl(), cucc.getAppid(), cucc.getAppkey());

                if (accessResult.getCode() == 200) {
                    accessToken = (String) accessResult.getMessage();
                } else {
                    //获取token失败,大概率因为证书找不到
                    result.setCode(500);
                    result.setMessage("注册失败，NB平台鉴权失败");
                    return result;
                }

                // 2注册直联设备，获取deviceId
                SuccessResponseData regresult = DeviceRegister.registerDevice(cucc.getAppid(), cucc.getAppkey(), accessToken, cucc.getBaseUrl(), busNbDevice);
                if (regresult.getCode() == 200) {
                    // 在电信NB平台注册成功
                    String nbDeviceId = (String) regresult.getMessage();
                    if (null == nbDeviceId) {
                        // 获取平台返回的nbDeviceId失败则直接抛出异常
                        throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
                    }

                    busNbDevice.setNbDeviceId(nbDeviceId);

                    // 在NB平台修改设备信息
                    SuccessResponseData modresult = DeviceRegister.modifyDevice(cucc.getAppid(), cucc.getAppkey(), accessToken, cucc.getBaseUrl(), busNbDevice);
                    if (modresult.getCode() == 204) {
                        // 修改成功，插入本地数据库
                        boolean success = insert(busNbDevice);

                        if (success == false) {
                            result.setCode(500);
                            result.setMessage("注册失败，本地数据库添加失败");
                            return result;
                        }

                        return result;
                    } else {
                        result.setCode(500);
                        result.setMessage("注册失败，NB平台修改设备信息失败");
                        return result;
                    }
                } else {
                    result.setCode(500);
                    result.setMessage("注册失败，NB平台注册失败");
                    return result;
                }
            } catch (Exception ex) {
                throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
            }
        } else {
            result.setCode(500);
            result.setMessage("注册失败，设备唯一标识重复");

            return result;
        }
    }

    @Override
    public SuccessResponseData registerDevices(File file) {
        return null;
    }

    @Override
    public SuccessResponseData updateDevice(BusNbDevice busNbDevice) {
        // 返回的默认值
        SuccessResponseData result = new SuccessResponseData(200,null,"更新成功");

        // 查找登录用户所在的部门
        Long deptid = permissionService.getCurrLoginUser().getDeptId();
        if (null == deptid) {
            // 没有找到登录用户部门，直接抛出异常
            throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
        }

        // 查询部门所对应的电信平台配置参数
        ConfigNbCucc cucc = configNbCuccService.getConfigByDept(deptid);
        if (null == cucc) {
            result.setCode(500);
            result.setMessage("更新失败，未找到部门电信平台配置参数");

            return result;
        }

        String accessToken = null;
        try {
            // 1首先在NB平台鉴权
            SuccessResponseData accessResult = Authentication.doAuth(cucc.getBaseUrl(), cucc.getAppid(), cucc.getAppkey());

            if (accessResult.getCode() == 200) {
                accessToken = (String) accessResult.getMessage();
            } else {
                // 获取token失败,大概率因为证书找不到
                result.setCode(500);
                result.setMessage("更新失败，NB平台鉴权失败");
                return result;
            }

            // 2修改设备信息
            SuccessResponseData modresult = DeviceRegister.modifyDevice(cucc.getAppid(), cucc.getAppkey(), accessToken, cucc.getBaseUrl(), busNbDevice);
            if (modresult.getCode() == 204) {
                //在库里更新设备信息
                boolean success = updateById(busNbDevice);

                if (success == false) {
                    result.setCode(500);
                    result.setMessage("更新失败，本地数据库更新失败");
                    return result;
                }

                return result;
            } else {
                result.setCode(500);
                result.setMessage("更新失败，电信平台更新失败");
            }
        } catch (Exception ex) {
            throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
        }

        return result;
    }

    @Override
    public SuccessResponseData deleteDevice(String nbDeviceId) {
        SuccessResponseData result = new SuccessResponseData(200,null,"删除成功");

        // 查找登录用户所在的部门
        Long deptid = permissionService.getCurrLoginUser().getDeptId();
        if (null == deptid) {
            // 没有找到登录用户部门，直接抛出异常
            throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
        }

        // 查询部门所对应的电信平台配置参数
        ConfigNbCucc cucc = configNbCuccService.getConfigByDept(deptid);
        if (null == cucc) {
            result.setCode(500);
            result.setMessage("删除失败，未找到部门电信平台配置参数");

            return result;
        }

        String accessToken = null;
        try {
            // 1首先在NB平台鉴权
            SuccessResponseData accessResult = Authentication.doAuth(cucc.getBaseUrl(), cucc.getAppid(), cucc.getAppkey());

            if (accessResult.getCode() == 200) {
                accessToken = (String) accessResult.getMessage();
            } else {
                // 获取token失败,大概率因为证书找不到
                result.setCode(500);
                result.setMessage("删除失败，NB平台鉴权失败");
                return result;
            }

            // 2删除设备信息
            SuccessResponseData delresult = DeviceRegister.deleteDevice(cucc.getAppid(), cucc.getAppkey(), accessToken, cucc.getBaseUrl(), nbDeviceId);
            if (delresult.getCode() == 204) {
                //在库里更新设备信息
                boolean success = baseMapper.deleteByNbDeviceId(nbDeviceId);//在库里删除设备

                if (success == false) {
                    result.setCode(500);
                    result.setMessage("删除失败，本地数据库删除失败");
                    return result;
                }

                return result;
            } else {
                result.setCode(500);
                result.setMessage(delresult.getMessage());
            }
        } catch (Exception ex) {
            throw new GunsException(GunsExceptionEnum.SERVER_ERROR);
        }

        return result;
    }

    @Override
    public List<String> addDeviceBatch(List<BusNbDevice> results) {
        List<String> list = new ArrayList<>();
        BeanPropertyBindingResult beanPropertyBindingResult = new BeanPropertyBindingResult(Device.class, "NB设备导入校验");
        if (!ToolUtil.isEmpty(results)) {
            final Integer[] index = {0};
            results.forEach(nbDevice -> {
                index[0]++;
                validator.validate(nbDevice, beanPropertyBindingResult);
                if (beanPropertyBindingResult.hasErrors()) {
                    List<FieldError> errors = beanPropertyBindingResult.getFieldErrors();
                    errors.forEach(error -> {
                                list.add("第 " + index[0] + "行，".concat(error.getDefaultMessage()));
                                return;
                            }
                    );
                    return;
                }
            });

            if (ToolUtil.isNotEmpty(list)) {
                return list;
            }
            //导入NB相关信息
            this.insertBatch(results);

        } else {
            list.add("导入数据不能为空");
        }

        return list;
    }
}
