package com.casic.missiles.modular.web.controller;

import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
import com.casic.missiles.modular.web.service.IBusNbDeviceService;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.base.response.ErrorResponseData;
import com.casic.missiles.core.base.response.ResponseData;
import com.casic.missiles.core.base.response.SuccessResponseData;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.controller.DeviceController;
import com.casic.missiles.modular.system.model.BusNbDevice;
import io.swagger.annotations.ApiOperation;
import org.hswebframework.expands.office.excel.ExcelIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 控制器
 *
 * @author dev123
 * @Date 2018-11-19 13:15:14
 */
@RestController
@RequestMapping("/nbdevice")
public class BusNbDeviceController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(DeviceController.class);
    @Autowired
    private IBusNbDeviceService busNbDeviceService;

    /**
     * 获取列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String devcode) {
        SuccessResponseData successResult = new SuccessResponseData();
        successResult.setMessage("success");

        List<BusNbDevice> busNbDeviceList = busNbDeviceService.getListByDevcode(devcode);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (null == busNbDeviceList || busNbDeviceList.isEmpty() == true) {
            dataMap.put("total", 0);
            dataMap.put("rows", new ArrayList<BusNbDevice>());
        } else {
            dataMap.put("total", busNbDeviceList.size());
            dataMap.put("rows", busNbDeviceList);
        }

        successResult.setData(dataMap);
        return successResult;
    }


    /**
     * 单个NB设备注册
     *
     * @param nbDeviceId      NB设备编号
     * @param devcode         厂家设备编号
     * @param verifyCode      模块IMEI号
     * @param nodeid          设备唯一标识
     * @param timeout         超时时间
     * @param name            设备名称
     * @param manufacturerId   厂商id
     * @param manufacturerName 厂商名称
     * @param deviceType      设备类型
     * @param model           设备型号
     * @param protocalType    设备协议类型
     * @param isSecure        设备安全模式
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Object add(@RequestParam(required = false) String nbDeviceId,
                      @RequestParam(required = true) String devcode,
                      @RequestParam(required = true) String verifyCode,
                      @RequestParam(required = true) String nodeid,
                      @RequestParam(required = true) String timeout,
                      @RequestParam(required = true) String name,
                      @RequestParam(required = true) String manufacturerId,
                      @RequestParam(required = true) String manufacturerName,
                      @RequestParam(required = true) String deviceType,
                      @RequestParam(required = true) String model,
                      @RequestParam(required = true) String protocalType,
                      @RequestParam(required = true) String isSecure) {
        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setMessage("success");

        // 为对象赋值
        BusNbDevice busNbDevice = new BusNbDevice();
        busNbDevice.setNbDeviceId(nbDeviceId);
        busNbDevice.setDevcode(devcode);
        busNbDevice.setVerifyCode(verifyCode);
        busNbDevice.setNodeid(nodeid);
        try {
            busNbDevice.setTimeout(Integer.parseInt(timeout));
        } catch (Exception ex) {
            busNbDevice.setTimeout(0);
        }
        busNbDevice.setName(name);
        busNbDevice.setManufacturerId(manufacturerId);
        busNbDevice.setManufacturerName(manufacturerName);
        busNbDevice.setDeviceType(deviceType);
        busNbDevice.setModel(model);
        busNbDevice.setProtocalType(protocalType);
        busNbDevice.setIsSecure(isSecure);

        // 首先在电信NB平台上注册设备
        // 保存记录入数据库
        resultData = busNbDeviceService.registDevice(busNbDevice);

        return resultData;
    }

    /**
     * 修改NB注册设备信息
     *
     * @param id              记录ID
     * @param nbDeviceId      NB设备编号
     * @param devcode         厂家设备编号
     * @param verifyCode      模块IMEI号
     * @param nodeid          NB设备名称
     * @param timeout         超时时间
     * @param name            设备名称
     * @param manufacturerId   厂商id
     * @param manufacturerName 厂商名称
     * @param deviceType      设备类型
     * @param model           设备型号
     * @param protocalType    设备协议类型
     * @param isSecure        设备安全模式
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Object update(@RequestParam(required = true) String id,
                         @RequestParam(required = false) String nbDeviceId,
                         @RequestParam(required = true) String devcode,
                         @RequestParam(required = true) String verifyCode,
                         @RequestParam(required = true) String nodeid,
                         @RequestParam(required = true) String timeout,
                         @RequestParam(required = true) String name,
                         @RequestParam(required = true) String manufacturerId,
                         @RequestParam(required = true) String manufacturerName,
                         @RequestParam(required = true) String deviceType,
                         @RequestParam(required = true) String model,
                         @RequestParam(required = true) String protocalType,
                         @RequestParam(required = true) String isSecure) {
        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setMessage("success");

        // 为对象赋值
        BusNbDevice busNbDevice = busNbDeviceService.selectById(Long.parseLong(id));
        if (null != busNbDevice) {
            busNbDevice.setId(Long.parseLong(id));
//            busNbDevice.setNbDeviceId(nbDeviceId);
//            busNbDevice.setDevcode(devcode);
//            busNbDevice.setVerifyCode(verifyCode);
//            busNbDevice.setNodeid(nodeid);
            try {
                busNbDevice.setTimeout(Integer.parseInt(timeout));
            } catch (Exception ex) {
                busNbDevice.setTimeout(0);
            }
            busNbDevice.setName(name);
            busNbDevice.setManufacturerId(manufacturerId);
            busNbDevice.setManufacturerName(manufacturerName);
            busNbDevice.setDeviceType(deviceType);
            busNbDevice.setModel(model);
            busNbDevice.setProtocalType(protocalType);
            busNbDevice.setIsSecure(isSecure);

            // 首先在电信平台上更新设备信息
            // 更新记录入数据库
            resultData = busNbDeviceService.updateDevice(busNbDevice);
        } else {
            resultData.setMessage("更新失败，未找到NB设备");
        }

        return resultData;
    }

    /**
     * 删除注册NB设备
     *
     * @param ids 记录ID
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Object delete(@RequestParam(required = true) List<Integer> ids) {
        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setMessage("success");
        resultData.setCode(200);

        String errorDev = "删除失败的设备[";

        for (Integer id : ids) {
            // 查找设备
            BusNbDevice busNbDevice = busNbDeviceService.selectById(id);
            if (null != busNbDevice) {
                // 删除记录
                SuccessResponseData tmpResult = busNbDeviceService.deleteDevice(busNbDevice.getNbDeviceId());
                if (tmpResult.getCode() != 200) {
                    errorDev += busNbDevice.getDevcode() + ";";
                }
            }
        }

        if (errorDev.equalsIgnoreCase("") == false) {
            resultData.setMessage(errorDev + "]");
        }

        return resultData;
    }

    @ApiOperation("批量导入NB设备")
    @PostMapping(value = "/batchImport")
//    @Permission
    public Object batchImport(@RequestParam("file") MultipartFile file) {
        List<BusNbDevice> results = new ArrayList<>();
        //设置表头与字段映射,可通过反射获取
        Map<String, String> mapper = new HashMap<>();
        mapper.put("设备编号", "devcode");//判断唯一
        mapper.put("设备名称", "name");
        mapper.put("设备唯一标识", "nodeid");
        mapper.put("验证码", "verifyCode");
        mapper.put("超时时间", "timeout");
        mapper.put("厂商ID", "manufacturerId");
        mapper.put("厂商名称", "manufacturerName");
        mapper.put("设备类型","deviceType");//需要转换
        mapper.put("设备型号","model");//需要转换
        mapper.put("设备协议类型","protocalType");
        mapper.put("设备安全模式","isSecure");

        try {
            try (InputStream in = file.getInputStream()) {
                ExcelIO.read(in, mapper, BusNbDevice.class, (row) -> {
                    //仅读取第一个sheet
                    if (row.getSheet() == 0) {
                        if (row.getResult() != null) {
                            BusNbDevice busNbDevice = row.getResult();
                            //过滤设备编号及设备名称都为空的数据 (判定为空行不导入该行)
                            if (!ToolUtil.isAllEmpty(busNbDevice.getDevcode(), busNbDevice.getNodeid(), busNbDevice.getVerifyCode())) {
                                results.add(busNbDevice);
                            }
                        }
                    } else {
                        //其他sheet停止读取
                        logger.info("当前sheet" + row.getSheet() + ",停止读取");
                        row.shutdown();
                    }
                });

                for (int i = 0; i < results.size(); i++) {
                    SuccessResponseData resultData = busNbDeviceService.registDevice(results.get(i));

                    if (resultData.getCode() != 200) {
                        return ResponseData.error("第" + (i+1) + "行导入NB设备失败，"+ resultData.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            return catchMybatisPlusException(e, "导入NB设备失败");
        }

        return ResponseData.success();
    }

    private ResponseData catchMybatisPlusException(Exception e, String errorMsg) {
        if (e instanceof MybatisPlusException) {
            MybatisPlusException mybatisPlusException = (MybatisPlusException) e;
            String message = mybatisPlusException.getCause().getCause().getCause().getMessage();
            if (message.contains("Duplicate entry '")) {
                return new ErrorResponseData("设备编号或唯一标识重复" );
            }
        }
        logger.error(errorMsg, e);
        return new ErrorResponseData(errorMsg);
    }
}
