package com.yihu.jw.base.endpoint.device;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yihu.jw.base.dao.device.DeviceDao;
import com.yihu.jw.base.dao.device.DeviceDetailDao;
import com.yihu.jw.base.service.device.DeviceManageService;
import com.yihu.jw.base.service.device.DmDeviceService;
import com.yihu.jw.base.service.device.WlyyPatientDeviceService;
import com.yihu.jw.base.service.device.YsDeviceService;
import com.yihu.jw.entity.care.device.Device;
import com.yihu.jw.entity.care.device.DeviceDetail;
import com.yihu.jw.patient.dao.BasePatientDao;
import com.yihu.jw.restmodel.ResponseContant;
import com.yihu.jw.restmodel.iot.device.WlyyPatientDeviceVO;
import com.yihu.jw.restmodel.web.Envelop;
import com.yihu.jw.restmodel.web.ObjEnvelop;
import com.yihu.jw.restmodel.web.PageEnvelop;
import com.yihu.jw.restmodel.web.endpoint.EnvelopRestEndpoint;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jxl.Sheet;
import jxl.Workbook;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Bing on 2021/9/22.
 */
@RestController
@RequestMapping(value = "baseDevice",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Api(value = "设备管理", description = "设备管理", tags = {"设备管理"})
public class DeviceManageEndpoint extends EnvelopRestEndpoint {
    private static Logger logger = LoggerFactory.getLogger(DeviceManageEndpoint.class);

    @Autowired
    private DeviceDetailDao deviceDetailDao;
    @Autowired
    private DeviceDao deviceDao;
    @Autowired
    private DeviceManageService deviceManageService;
    @Autowired
    private WlyyPatientDeviceService patientDeviceService;
    @Autowired
    private DmDeviceService dmDeviceService;
    @Autowired
    private YsDeviceService ysDeviceService;
    @Autowired
    private BasePatientDao patientDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("findWlyyDevices")
    @ApiOperation("获取设备列表")
    public PageEnvelop<DeviceDetail> findDevices(
            @ApiParam(name = "fields", value = "返回的字段，为空返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "过滤器，为空检索所有条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序，规则参见说明文档")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size){
        try {
            List<DeviceDetail> list = deviceManageService.search(fields,filters,sorts,page,size);
            int count = (int) deviceManageService.getCount(filters);
            return success(list, count, page, size, DeviceDetail.class);
        }catch (Exception e){
            return failedPageEnvelopException2(e);
        }

    }

    @PostMapping("delWlyyDevice")
    @ApiOperation("删除设备")
    public Envelop delWlyyDevice(@ApiParam(name = "id")@RequestParam(value = "id")String id){
        try {
            deviceDetailDao.delete(Long.parseLong(id));
            return success(id);
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @PostMapping("saveWlyyDevice")
    @ApiOperation("保存/修改设备")
    public Envelop saveDevice(@ApiParam(name="json")@RequestParam(value = "json")String json){
        try {
            JSONObject response = deviceManageService.saveWlyyDevice(json);
            if (1==response.getInteger(ResponseContant.resultFlag)){
                return success("修改成功") ;
            }
            else {
                return Envelop.getError(response.getString(ResponseContant.resultMsg)) ;
            }
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @GetMapping(value = "getUserDevice")
    @ApiOperation("居民设备查询")
    public PageEnvelop<WlyyPatientDeviceVO> getUserDevice(
            @ApiParam(name = "id", value = "id")
            @RequestParam(value = "id", required = false) String id,
            @ApiParam(name = "userName", value = "userName")
            @RequestParam(value = "userName", required = false) String userName,
            @ApiParam(name = "userIdcard", value = "userIdcard")
            @RequestParam(value = "userIdcard", required = false) String userIdcard,
            @ApiParam(name = "categoryCode", value = "userIdcard")
            @RequestParam(value = "categoryCode", required = false) String categoryCode,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size){
        try {
            return patientDeviceService.getUserDevice(id,userName,userIdcard,categoryCode,page,size);
        }catch (Exception e){
            return failedPageEnvelopException2(e);
        }
    }

    @PostMapping("delPatientDevice")
    @ApiOperation("删除患者设备-解绑")
    public Envelop delPatientDevice(@ApiParam(name = "id")
                                    @RequestParam(value = "id", required = false) String id){
        try {
            patientDeviceService.delPatientDevice(id);
            return success();
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @GetMapping("findDmDeviceDict")
    @ApiOperation("获取设备字典")
    public PageEnvelop<Device> findDmDeviceDict(@ApiParam(name = "fields", value = "返回的字段，为空返回全部字段")
                                    @RequestParam(value = "fields", required = false) String fields,
                                    @ApiParam(name = "filters", value = "过滤器，为空检索所有条件")
                                    @RequestParam(value = "filters", required = false) String filters,
                                    @ApiParam(name = "sorts", value = "排序，规则参见说明文档")
                                    @RequestParam(value = "sorts", required = false) String sorts,
                                    @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
                                    @RequestParam(value = "page") int page,
                                    @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
                                    @RequestParam(value = "size") int size){
        try {
            if (StringUtils.isBlank(filters)){
                filters="del=1";
            }else {
                filters+=";del=1";
            }
            List<Device> list = dmDeviceService.search(fields, filters, sorts,page,size);
            int count = (int) dmDeviceService.getCount(filters);
            return success(list, count, page, size);
        }catch (Exception e){
            return failedPageEnvelopException2(e);
        }
    }

    @PostMapping("delDmDevice")
    @ApiOperation("删除设备字典定义")
    public Envelop delDmDevice(@ApiParam(name = "id")
                             @RequestParam(value = "id", required = false) String id){
        try {
            dmDeviceService.delete(Long.parseLong(id));
            return success();
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @PostMapping("saveDmDevice")
    @ApiOperation("保存设备字典定义")
    public Envelop saveDmDevice(@ApiParam(name="json")@RequestParam(value = "json")String json){
        try {
            JSONObject response = dmDeviceService.saveDmDevice(json);
            if (1==response.getInteger(ResponseContant.resultFlag)){
                return success("修改成功") ;
            }
            else {
                return Envelop.getError(response.getString(ResponseContant.resultMsg)) ;
            }
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @PostMapping(value = "/importDeviceFromExcel", produces = "application/json;charset=UTF-8")
    @ApiOperation("设备数据导入")
    public ObjEnvelop importFromExcel(HttpServletRequest request, @ApiParam(value = "文件", required = true)
    @RequestParam(value = "file", required = true) MultipartFile file,HttpServletResponse response) {
        List errorLs = new ArrayList<>();
        List correctLs = new ArrayList<>();
        Map<String, String> errorMsgMapTotal = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> deviceCodes = new ArrayList<>();
        try {
            request.setCharacterEncoding("UTF-8");
            InputStream inputStream = file.getInputStream();
            Workbook rwb = Workbook.getWorkbook(inputStream);
            Sheet[] sheets = rwb.getSheets();
            int rows;
            int row;
            String manufacturer=null;//厂商名称
            String deviceName; //设备名称
            String deviceModel; //设备型号
            String deviceCode;  //设备SN
            String sim;  //sim卡号
            String iccid;  //iccid卡号
            String imsi;  //imsi卡号

            Sheet sheet = sheets[0];    //第一张表
            rows = sheet.getRows();

            for (int j = 1; j < rows; j++) {
                if (sheet.getRow(j).length == 0) {
                    continue;
                }
                String errorMsg = "";
                DeviceDetail deviceDetail = new DeviceDetail();
                Map<String, String> errorMsgMap = deviceDetail.getErrorMsgMap();
                row = j;
                manufacturer = sheet.getCell(0, row).getContents().trim();    //0 厂商名称
                deviceName = sheet.getCell(1, row).getContents().trim();  //1 设备名称
                deviceModel = sheet.getCell(2, row).getContents().trim();   //2 设备型号
                deviceCode = sheet.getCell(3, row).getContents().trim(); //3 设备SN
                sim = sheet.getCell(4, row).getContents().trim();  //4 sim卡号
                iccid = sheet.getCell(5, row).getContents().trim();  //4 iccid卡号
                imsi = sheet.getCell(6, row).getContents().trim();  //4 imsi卡号
                if (org.apache.commons.lang.StringUtils.isBlank(deviceCode)){
                    continue;
                }
                if (deviceCodes.contains(deviceCode)){
                    errorMsgMapTotal.put(deviceCode,"设备SN码重复");
                    errorMsgMap.put("deviceCode", "设备SN码重复！;");
                    errorMsg += "设备SN码重复！;";
                }
                deviceCodes.add(deviceCode);
                if (org.apache.commons.lang.StringUtils.isBlank(manufacturer)){
                    errorMsgMapTotal.put(deviceCode,"厂商名称不能为空");
                    errorMsgMap.put("manufacturer", "厂商名称不能为空！;");
                    errorMsg += "厂商名称不能为空！;";
                }
                if (org.apache.commons.lang.StringUtils.isBlank(deviceName)){
                    errorMsgMapTotal.put(deviceCode,"设备名称不能为空");
                    errorMsgMap.put("deviceName", "设备名称不能为空！;");
                    errorMsg += "设备名称不能为空！;";
                }
                if (org.apache.commons.lang.StringUtils.isBlank(deviceModel)){
                    errorMsgMapTotal.put(deviceCode,"设备型号不能为空");
                    errorMsgMap.put("deviceModel", "设备型号不能为空！;");
                    errorMsg += "设备型号不能为空！;";
                }
                //名称、设备类型、设备型号判断
                if (0==deviceDao.findTotalByName(deviceName)){
                    errorMsgMapTotal.put(deviceCode,"设备名称不存在");
                    errorMsgMap.put("deviceName", "设备名称不存在！;");
                    errorMsg += "设备名称不存在！;";
                }
                if (0==deviceDao.findTotalByModel(deviceModel)){
                    errorMsgMapTotal.put(deviceCode,"设备型号不存在");
                    errorMsgMap.put("deviceModel", "设备型号不存在！;");
                    errorMsg += "设备型号不存在！;";
                }

                if (deviceDetailDao.findByDeviceCode(deviceCode).size()>0){
                    errorMsgMapTotal.put(deviceCode,"该设备SN码已存在");
                    errorMsgMap.put("deviceCode", "该设备SN码已存在！;");
                    errorMsg += "该设备SN码已存在！;";
                }
                if (org.apache.commons.lang.StringUtils.isNotBlank(sim) && deviceDetailDao.findBySim(sim).size()>0){
                    errorMsgMapTotal.put(deviceCode,"该sim卡号已存在");
                    errorMsgMap.put("sim", "该sim卡号已存在！;");
                    errorMsg += "该sim卡号已存在！;";
                }
                if (org.apache.commons.lang.StringUtils.isNotBlank(iccid) && deviceDetailDao.findByIccid(iccid).size()>0){
                    errorMsgMapTotal.put(deviceCode,"该iccid卡号已存在");
                    errorMsgMap.put("iccid", "该iccid卡号已存在！;");
                    errorMsg += "该iccid卡号已存在！;";
                }
                if (org.apache.commons.lang.StringUtils.isNotBlank(imsi) && deviceDetailDao.findByImsi(imsi).size()>0){
                    errorMsgMapTotal.put(deviceCode,"该imsi卡号已存在");
                    errorMsgMap.put("imsi", "该imsi卡号已存在！;");
                    errorMsg += "该imsi卡号已存在！;";
                }
                if (!StringUtils.isEmpty(errorMsg.trim())) {
                    deviceDetail.setErrorMsg(errorMsg);
                    errorLs.add(deviceDetail);
                    continue;
                }
                if ("CS-C6Wi-3E4WFR".equals(deviceModel)){//监控器 直播地址开通->关闭视频加密 后续暂时先于APP操作
                    ysDeviceService.videoOpen(deviceCode,null);
                }
                deviceDetail.setApplyDate(sdf.format(new Date()));
                deviceDetail.setManufacturer(manufacturer);
                deviceDetail.setDeviceName(deviceName);
                deviceDetail.setDeviceModel(deviceModel);
                deviceDetail.setDeviceCode(deviceCode);
                deviceDetail.setSim(sim);
                Device device = deviceDao.findByModel(deviceModel);
                if (device!=null){
                    deviceDetail.setDeviceType(device.getDeviceType());
                    deviceDetail.setCategoryCode(device.getCategoryCode());//设备类型判断
                    if ("1".equals(device.getIsMultiUser())){
                        deviceDetail.setBindingCount("{\"1\":\"0\",\"2\":\"0\"}");
                    }else if ("0".equals(device.getIsMultiUser())){
                        deviceDetail.setBindingCount("{\"1\":\"0\"}");
                    }
                }
                correctLs.add(deviceDetail);
            }

            deviceDetailDao.save(correctLs);
            //包装导入结果（导入成功数量、错误对象集合）
            Map<String, Object> map = new HashMap<>();
            map.put("successNum", correctLs.size());
            map.put("failedNum", rows-1 - correctLs.size() );
            map.put("errorData", JSON.toJSONString(errorMsgMapTotal, SerializerFeature.WriteMapNullValue));
            map.put("errorData", errorLs);

            return ObjEnvelop.getSuccess("success",JSON.toJSONString(map,SerializerFeature.WriteMapNullValue));
        } catch (Exception e) {
            failedObjEnvelopException2(e);
        }
        return ObjEnvelop.getSuccess("success",correctLs.size());
    }

    @GetMapping(value = "downLoadDeviceModelExcel", produces = "application/json;charset=UTF-8")
    @ApiOperation(("模板下载"))
    public void downLoadDeviceModelExcel(HttpServletResponse response) {
        try {
            response.setContentType("octets/stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + new String("deviceImport.xls"));
            OutputStream os = response.getOutputStream();
            deviceManageService.write(os, new ArrayList());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /***初始化设备表 设备类型字段****/
    @PostMapping("initCategoryCode")
    @ApiOperation("设备库存表新增字段初始化")
    public Envelop initCategoryCode(){
        try {
            deviceManageService.initCategoryCode();
            return success();
        }catch (Exception e){
            return failedException2(e);
        }
    }

    @GetMapping("findDmDeviceDictName")
    @ApiOperation("根据设备类型查询设备名称以及型号")
    public ObjEnvelop findDmDeviceDictName(@ApiParam(name = "code", value = "category_code")
                                               @RequestParam(value = "code", required = false) String code,
                                           @ApiParam(name = "name", value = "name", required = false)
                                               @RequestParam(value = "name", required = false) String name){

            try{
                return ObjEnvelop.getSuccess("查询成功",deviceManageService.findDmDeviceDictName(code,name)) ;
            }catch (Exception e) {
                return failedObjEnvelopException2(e);
            }

    }

}
