package org.nl.acs.device.rest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nl.acs.device.device_driver.DriverTypeEnum;
import org.nl.acs.device.device_driver.standard_inspect.OpcPlcDto;
import org.nl.common.logging.annotation.Log;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService;
import org.nl.acs.device.service.dto.DeviceDto;
import org.nl.acs.device.service.dto.DeviceQueryParam;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author jiaolm
* @date 2023-05-09
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "设备服务管理")
@RequestMapping("/api/device")
public class DeviceController {

    private final DeviceService deviceService;

    /*
    @Log("导出设备服务")
    @ApiOperation("导出设备服务")
    @GetMapping(value = "/download")
    //@PreAuthorize("@el.check('device:list')")
    public void download(HttpServletResponse response, DeviceQueryParam query) throws IOException {
        deviceService.download(deviceService.queryAll(query), response);
    }*/
    @GetMapping
    @Log("查询设备")
    @ApiOperation("查询设备")
    //@PreAuthorize("@el.check('device:list')")
    public ResponseEntity<Object> query(@RequestParam Map whereJson, Pageable page) {
        return new ResponseEntity<>(deviceService.queryAll(whereJson, page), HttpStatus.OK);
    }

    @GetMapping("/protocol")
    @Log("查询设备协议")
    @ApiOperation("查询设备协议")
    //@PreAuthorize("@el.check('device:list')")
    public ResponseEntity<Object> protocol(@RequestParam Map whereJson, Pageable page) {
        return new ResponseEntity<>(deviceService.queryDeviceProtocol(whereJson, page), HttpStatus.OK);
    }

    @Log("导出设备协议")
    @ApiOperation("导出设备协议")
    @GetMapping(value = "/protocol/download")
    //@PreAuthorize("@el.check('device:list')")
    public void downDeviceDBload(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
        deviceService.downDeviceDBload(deviceService.queryDeviceProtocol(whereJson), response);
    }

    @Log("导出设备协议")
    @ApiOperation("导出设备协议CSV")
    @GetMapping(value = "/protocol/downloadCSV")
    //@PreAuthorize("@el.check('device:list')")
    public void downDeviceDBloadCSV(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
        deviceService.downDeviceDBloadCSV(deviceService.queryDeviceProtocol(whereJson), response);
    }

    @PostMapping
    @Log("新增设备")
    @ApiOperation("新增设备")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> create(@Validated @RequestBody DeviceDto dto) {
        deviceService.create(dto);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改设备")
    @ApiOperation("修改设备")
    //@PreAuthorize("@el.check('device:edit')")
    public ResponseEntity<Object> update(@Validated @RequestBody DeviceDto dto) {
        deviceService.update(dto);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log("删除设备")
    @ApiOperation("删除设备")
    //@PreAuthorize("@el.check('device:del')")
    @DeleteMapping
    public ResponseEntity<Object> delete(@RequestBody String[] ids) {

        deviceService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("导出设备")
    @ApiOperation("导出设备")
    @GetMapping(value = "/download")
    //@PreAuthorize("@el.check('device:list')")
    public void download(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
        deviceService.download(deviceService.queryAll(whereJson), response);
    }

    @GetMapping("/selectList")
    @Log("下拉选设备")
    @ApiOperation("下拉选设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectList() {
        return new ResponseEntity<>(deviceService.selectList(), HttpStatus.OK);
    }

    @GetMapping("/region/{region}")
    @Log("根据区域查询设备")
    @ApiOperation("根据区域查询设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectList(@PathVariable String region) {
        return new ResponseEntity<>(deviceService.selectDeviceListByRegion(region), HttpStatus.OK);
    }

    @GetMapping("/selectListOne")
    @Log("查询区域一设备")
    @ApiOperation("查询区域一设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectListOne() {
        return new ResponseEntity<>(deviceService.selectDeviceListOne(), HttpStatus.OK);
    }

    @GetMapping("/selectListTwo")
    @Log("查询区域二设备")
    @ApiOperation("查询区域二设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectListTwo() {
        return new ResponseEntity<>(deviceService.selectDeviceListTwo(), HttpStatus.OK);
    }

    @GetMapping("/selectListThree")
    @Log("查询区域三设备")
    @ApiOperation("查询区域三设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectListThree() {
        return new ResponseEntity<>(deviceService.selectDeviceListThree(), HttpStatus.OK);
    }

    @GetMapping("/type/{type}")
    @Log("根据设备类型查询已配置设备")
    @ApiOperation("根据类型查询设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectListByType(@PathVariable String type) {
        return new ResponseEntity<>(deviceService.selectDeviceListByType(type), HttpStatus.OK);
    }

    @GetMapping("/selectDeviceDevicerInfo/{status}")
    @Log("根据状态查询设备信息")
    @ApiOperation("根据区域查询设备信息")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectDeviceDevicerInfo(@PathVariable String status) {
        return new ResponseEntity<>(deviceService.selectDeviceDevicerInfo(status), HttpStatus.OK);
    }

    @PostMapping("/callAgv")
    @Log("呼叫请求")
    @ApiOperation("呼叫请求")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> callAgv(@RequestBody JSONObject json) {
        deviceService.callAgv(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/addMaterial")
    @Log("添加物料信息")
    @ApiOperation("添加物料信息")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> addMaterial(@RequestBody JSONObject json) {
        deviceService.addMaterial(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/changeDeviceStatus")
    @Log("改变设备状态")
    @ApiOperation("改变设备状态")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> changeDeviceStatus(@RequestBody JSONObject json) {
        deviceService.changeDeviceStatus(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/changeFenceStatus")
    @Log("改变电子围栏状态")
    @ApiOperation("改变电子围栏状态")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> changeFenceStatus(@RequestBody JSONObject json) {
        deviceService.changeFenceStatus(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/responseAgv")
    @Log("响应请求")
    @ApiOperation("响应请求")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> responseAgv(@RequestBody JSONObject json) {
        deviceService.responseAgv(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/autoCreateTask")
    @Log("自动创建接任务")
    @ApiOperation("自动创建接任务")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> autoCreateTask(@RequestBody JSONObject json) {
        deviceService.autoCreateTask(json);

        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/cleanTask")
    @Log("清除设备状态为空位")
    @ApiOperation("清除设备状态为空位")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> cleanTask(@RequestBody JSONObject json) {
        deviceService.cleanTask(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PostMapping("/cleanMaterial")
    @Log("清除设备物料信息")
    @ApiOperation("清除设备物料信息")
    //@PreAuthorize("@el.check('device:add')")
    public ResponseEntity<Object> cleanMaterial(@RequestBody JSONObject json) {
        deviceService.cleanMaterial(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @GetMapping("/selectDriverCodeList/{device_code}")
    @Log("下拉选设备驱动")
    @ApiOperation("下拉选设备驱动")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectDriverCodeList(@PathVariable String device_code) {
        DeviceDto device = deviceService.findByCode(device_code);
        return new ResponseEntity<>(DriverTypeEnum.getListByType(device.getDevice_type()), HttpStatus.OK);
    }

    @ApiOperation("查询")
    @GetMapping({"/{device_code}"})
    public ResponseEntity<Object> query(@PathVariable String device_code) {
        final JSONObject model = new JSONObject();
        DeviceDto device = deviceService.findByCode(device_code);
        model.put("device", device);
        return new ResponseEntity(model, HttpStatus.OK);
    }

    @ApiOperation("查询货架扩展信息")
    @GetMapping({"/queryStorageExtra/{storage_code}"})
    public ResponseEntity<Object> queryStorageExtra(@PathVariable String storage_code) {
        return new ResponseEntity(deviceService.queryStorageExtra(storage_code), HttpStatus.OK);
    }


//    @PutMapping({"/getOpcPlcs"})
//    @Log("获取plc列表")
//    @ApiOperation("获取plc列表")
//    public ResponseEntity<Object> getOpcPlcs(@RequestBody Map map) throws Exception {
//        final JSONObject model = new JSONObject();
//        Map<String, String> form = (Map) map.get("form");
//        String opc_server_id = form.get("opc_server_id");
//        JSONArray plcs = WQLObject.getWQLObject("acs_opc_plc").query("opc_server_id = '" + opc_server_id + "'").getResultJSONArray(0);
//        List<OpcPlcDto> list =                                                                                  plcs.toJavaList(OpcPlcDto.class);
//        model.put("opcPlcs", list);
//        return new ResponseEntity(model, HttpStatus.OK);
//    }

    @PostMapping({"/updateConfig"})
    @Log("配置设备驱动")
    @ApiOperation("配置设备驱动")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> updateConfig(@RequestBody Map map) {
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
        deviceService.updateConfig(jsonObject);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @PostMapping({"/driverConfig"})
    @Log("配置驱动查询")
    @ApiOperation("配置驱动查询")
    public ResponseEntity<Object> queryDriverConfigByDeviceId(@RequestBody Map map) {
        return new ResponseEntity(deviceService.queryDriverConfigByDeviceId((String) map.get("device_id"), (String) map.get("driver_code")), HttpStatus.OK);
    }

    @ApiOperation("测试读DB值")
    @PostMapping({"/testRead"})
    public ResponseEntity<Object> testRead(@RequestBody Map map) {
        return new ResponseEntity(deviceService.testRead(map), HttpStatus.OK);
    }

    @ApiOperation("测试写DB值")
    @PostMapping({"/testWrite"})
    public ResponseEntity<Object> testWrite(@RequestBody Map map) {
        deviceService.testWrite(map);
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @ApiOperation("查询条码")
    @GetMapping({"/queryScanner/{device_code}"})
    public ResponseEntity<Object> queryScannerByCode(@PathVariable String device_code) throws Exception {
        String bcr = deviceService.queryScannerByCode(device_code);
        return new ResponseEntity(bcr, HttpStatus.OK);
    }

    @GetMapping("/selectConveyorList")
    @Log("下拉选输送设备")
    @ApiOperation("下拉选输送设备")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> selectConveyorList() {
        return new ResponseEntity<>(deviceService.selectConveyorList(), HttpStatus.OK);
    }

    @Log("查询缓存所有指令")
    @ApiOperation("查询缓存指令")
    @PostMapping(value = "/findAllStorageCellFromCache")
    public ResponseEntity<Object> findAllInstFromCache() {
        return new ResponseEntity<>(deviceService.findAllStorageCellFromCache(), HttpStatus.OK);
    }

    @Log("查询缓存所有设备")
    @ApiOperation("查询缓存设备")
    @PostMapping(value = "/findCacheDevice")
    public ResponseEntity<Object> findCacheDevice() {
        return new ResponseEntity<>(deviceService.findCacheDevice(), HttpStatus.OK);
    }

    @Log("更新条码")
    @ApiOperation("更新条码")
    @PostMapping(value = "/updateBarcode")
    public ResponseEntity<Object> updateBarcode(@RequestBody JSONObject json) throws Exception {
        deviceService.updateBarcode(json);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @GetMapping({"/queryDBInfoByDriverCode/{driverCode}"})
    @Log("根据驱动编码获取db信息")
    @ApiOperation("根据驱动编码获取db信息")
    public ResponseEntity<Object> queryDBInfoByDriverCode(@PathVariable String driverCode) {
        return new ResponseEntity(deviceService.queryDBInfoByDriverCode(driverCode), HttpStatus.OK);
    }

    @Log("导出设备db")
    @ApiOperation("导出设备")
    @PostMapping(value = "/downloadProtocolConfig")
    //@PreAuthorize("@el.check('device:list')")
    public void downloadProtocolConfig(HttpServletResponse response, @RequestBody JSONObject whereJson) throws IOException {
        deviceService.downloadProtocolConfig(whereJson, response);
    }

    @GetMapping("/getAllDriverCodeList")
    @Log("协议配置下拉选设备驱动")
    @ApiOperation("协议配置下拉选设备驱动")
    //@PreAuthorize("@el.check('routePlan:list')")
    public ResponseEntity<Object> getAllDriverCodeList() {
        return new ResponseEntity<>(DriverTypeEnum.getList(), HttpStatus.OK);
    }

    @Log("导出Smart设备协议CSV")
    @ApiOperation("导出Smart设备协议CSV")
    @GetMapping(value = "/protocol/downloadSmartCSV")
//@PreAuthorize("@el.check('device:list')")
    public void downDeviceDBloadOumulongCSV(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
        deviceService.downDeviceDBloadSmartCSV(deviceService.queryDeviceProtocol(whereJson), response);
    }

    @Log("导出FX5U设备协议CSV")
    @ApiOperation("导出FX5U设备协议CSV")
    @GetMapping(value = "/protocol/downloadFX5UCSV")
//@PreAuthorize("@el.check('device:list')")
    public void downDeviceDBloadFX5UCSV(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
        deviceService.downDeviceDBloadFX5UCSV(deviceService.queryDeviceProtocol(whereJson), response);
    }

    @PostMapping("/excelImport")
    @Log("excel导入")
    @ApiOperation("excel导入")
    public ResponseEntity<Object> excelImport(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        deviceService.excelImport(file, request);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
