package com.mx.cneeds.server.datashow.web.device;

import com.mx.cneeds.common.constant.ResultCode;
import com.mx.cneeds.common.converter.RequestParamterConverter;
import com.mx.cneeds.common.dto.*;
import com.mx.cneeds.common.result.R;
import com.mx.cneeds.common.vo.*;
import com.mx.cneeds.server.datashow.client.DeviceClient;
import com.mx.cneeds.server.datashow.client.UserClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;

/**
 * @ClassName DeviceController
 * @Author zzrdark
 * @Date 2020-03-05 14:42
 * @Description TODO
 **/

@RestController
@Slf4j
@RequestMapping("/device")
public class DeviceController {

    @Autowired
    private DeviceClient deviceClient;

    @Autowired
    private UserClient userClient;

    @GetMapping("/device/getChannel_nums")
    public R getChannel_nums(String imei){

        AndroidDeviceChannelVo channelVo = new AndroidDeviceChannelVo();
        DeviceInfoDto deviceInfoDto = null;
        try {
            deviceInfoDto = deviceClient.queryDeviceByImei(imei);
            if (deviceInfoDto == null){
//                log.debug("ResultCode:"+ResultCode.NOTFOUND_IMEI);
                return R.error(ResultCode.NOTFOUND_IMEI,"没有该imei的设备");
            }
        }catch (Exception e) {
            return R.error(ResultCode.NOTFOUND_IMEI,"没有该imei的设备");
        }

        if (deviceInfoDto.getChannelNums() == null || deviceInfoDto.getChannelRules() == null) {
            return R.error(ResultCode.NOTSET_CHANNEL,"该设备没有设置渠道商号");
        }

        BeanUtils.copyProperties(deviceInfoDto,channelVo);
        return new R().put("data",channelVo);
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:add') or hasRole('admin')")
    @PostMapping("/device/saveChannel")
    public R saveChannel_nums(DeviceChannelVo channelVo){
        DevicesDto devicesDto = new DevicesDto();
        BeanUtils.copyProperties(channelVo,devicesDto);
        deviceClient.updateDeviceChannelBatch(devicesDto);

        return new R().put("data",channelVo);
    }




    @PreAuthorize("hasRole('configManagement:productSeries:list') or hasRole('admin')")
    @PostMapping("/series/list")
    public R seriesList(@RequestParam(required = false) Integer page,
                        @RequestParam(required = false) Integer pageSize,
                        @RequestParam(required = false) String sort,
                        @RequestParam(required = false) String seriesNum){

        String orderField = null;
        String order = null;

        if (page==null || page==0){
            page = new Integer(1);
        }
        if (pageSize==null || pageSize==0){
            pageSize = new Integer(10);
        }

        if (StringUtils.isNotEmpty(sort) && StringUtils.isNotBlank(sort.trim())){
            if (sort.contains("+")){
                order = new String("asc");
            }
            if (sort.contains("-")){
                order = new String("desc");
            }
            orderField = sort.substring(1);
            orderField = RequestParamterConverter.toLine(orderField);
        }


        PageDto pageDto = deviceClient.seriesList(page,pageSize,orderField,order,seriesNum);

        return new R().put("data",pageDto);
    }

    @PreAuthorize("hasRole('configManagement:productSeries:list') or hasRole('admin')")
    @PostMapping("/series/listAll")
    public R selectSeries(){
        List<SeriesDto> seriesDtos = deviceClient.seriesListAll();

        return new R().put("data",seriesDtos);
    }

    @PreAuthorize("hasRole('configManagement:productSeries:add') or hasRole('admin')")
    @PostMapping("/series/add")
    public R addSeries(SeriesVo seriesVo){
        SeriesDto querySeries = deviceClient.querySeries(seriesVo.getSeriesNum());
        if (querySeries != null){
            return R.error(ResultCode.DATA_REPEATITION,"系列号重复");
        }

        SeriesDto seriesDto = new SeriesDto();

        BeanUtils.copyProperties(seriesVo,seriesDto);
        deviceClient.addSeries(seriesDto);
        return R.ok();

    }

    @PreAuthorize("hasRole('configManagement:productSeries:edit') or hasRole('admin')")
    @PostMapping("/series/edit")
    public R editSeries(SeriesVo seriesVo){

        SeriesDto seriesDto = new SeriesDto();

        BeanUtils.copyProperties(seriesVo,seriesDto);
        deviceClient.updateSeries(seriesDto);
        return R.ok();

    }

    @PreAuthorize("hasRole('configManagement:productSeries:delete') or hasRole('admin')")
    @PostMapping("/series/delete")
    public R deleteSeries(@RequestParam(value = "ids",required = false) List<Long> ids){
        deviceClient.deleteSeries(ids);
        return R.ok();

    }


    @PreAuthorize("hasRole('deviceManagement:device:list') or hasRole('admin')")
    @PostMapping("/device/list")
    public R deviceList(@RequestParam(required = false) Integer page,
                        @RequestParam(required = false) Integer pageSize,
                        @RequestParam(required = false) String sort,
                        @RequestParam(required = false) Long seriesId,
                        @RequestParam(required = false) String imei){

        String orderField = null;
        String order = null;

        if (page==null || page==0){
            page = new Integer(1);
        }
        if (pageSize==null || pageSize==0){
            pageSize = new Integer(10);
        }

        if (StringUtils.isNotEmpty(sort) && StringUtils.isNotBlank(sort.trim())){
            if (sort.contains("+")){
                order = new String("asc");
            }
            if (sort.contains("-")){
                order = new String("desc");
            }
            orderField = sort.substring(1);
            orderField = RequestParamterConverter.toLine(orderField);
        }
        PageDto pageDto = deviceClient.deviceList(page,pageSize,orderField,order,seriesId,imei);

        return new R().put("data",pageDto);
    }

    @PreAuthorize("hasRole('deviceManagement:device:add') or hasRole('admin')")
    @PostMapping("/device/importDevice")
    public R importDevice(DevicesVo devicesVo){
        DevicesDto devicesDto = new DevicesDto();

        BeanUtils.copyProperties(devicesVo,devicesDto);
        deviceClient.importDevice(devicesDto);
        return R.ok();

    }

    @PreAuthorize("hasRole('deviceManagement:device:edit') or hasRole('admin')")
    @PostMapping("/device/updateDeviceSeriesBatch")
    public R updateDeviceSeriesBatch(DevicesVo devicesVo){
        DevicesDto devicesDto = new DevicesDto();

        BeanUtils.copyProperties(devicesVo,devicesDto);
        deviceClient.updateDeviceSeriesBatch(devicesDto);
        return R.ok();

    }

    @PreAuthorize("hasRole('deviceManagement:device:delete') or hasRole('admin')")
    @PostMapping("/device/delete")
    public R deleteDevice(@RequestParam(value = "ids",required = false) List<Long> ids){
        deviceClient.deleteDevice(ids);
        return R.ok();

    }

    @PreAuthorize("hasRole('deviceManagement:device:list') or hasRole('admin')")
    @PostMapping("/device/queryDeviceByImei")
    public R queryDeviceByImei(@RequestBody DeviceInfoDto dto){
        log.debug("queryDeviceByImei: imei:" + dto.getImei());
        DeviceInfoDto deviceInfoDto = deviceClient.queryDeviceByImei(dto.getImei());
        if (deviceInfoDto == null){
            R.error(ResultCode.NOTFOUND_IMEI,"没有该imei的设备");
        }
        return R.ok().put("data",deviceInfoDto);
    }


    @PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')")
    @PostMapping("/deviceChannel/list")
    public R deivceChannelList(@RequestParam(required = false) Integer page,
                        @RequestParam(required = false) Integer pageSize,
                        @RequestParam(required = false) String sort,
                               @RequestParam(required = false) String channelNum){

        String orderField = null;
        String order = null;

        if (page==null || page==0){
            page = new Integer(1);
        }
        if (pageSize==null || pageSize==0){
            pageSize = new Integer(10);
        }

        if (StringUtils.isNotEmpty(sort) && StringUtils.isNotBlank(sort.trim())){
            if (sort.contains("+")){
                order = new String("asc");
            }
            if (sort.contains("-")){
                order = new String("desc");
            }
            orderField = sort.substring(1);
            orderField = RequestParamterConverter.toLine(orderField);
        }


        PageDto pageDto = deviceClient.deviceChannelList(page,pageSize,orderField,order,channelNum);

        return new R().put("data",pageDto);
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:add') or hasRole('admin')")
    @PostMapping("/deviceChannel/add")
    public R addDeviceChannel(ChannelVo vo){
        DeviceChannelDto dto = deviceClient.queryDeviceChannel(vo.getChannelNum());
        if (dto != null){
            return R.error(ResultCode.DATA_REPEATITION,"渠道号重复");
        }

        DeviceChannelDto deviceChannelDto = new DeviceChannelDto();

        BeanUtils.copyProperties(vo,deviceChannelDto);
        deviceClient.addDeviceChannel(deviceChannelDto);
        return R.ok();

    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:edit') or hasRole('admin')")
    @PostMapping("/deviceChannel/edit")
    public R editSeries(ChannelVo vo){
        DeviceChannelDto deviceChannelDto = new DeviceChannelDto();
        BeanUtils.copyProperties(vo,deviceChannelDto);
        deviceClient.updateDeviceChannel(deviceChannelDto);
        return R.ok();
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')")
    @PostMapping("/deviceChannel/delete")
    public R deleteDeviceChannel(@RequestParam(value = "ids",required = false) List<Long> ids){
        deviceClient.deleteDeviceChannels(ids);
        return R.ok();
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')")
    @PostMapping("/deviceChannel/queryDeviceChannelAll")
    public R queryDeviceChannelAll(){
        List<DeviceChannelDto> deviceChannelDtos = deviceClient.queryDeviceChannelAll();
        return R.ok().put("data",deviceChannelDtos);
    }

    /**
     * 删除(还原)设置的渠道号
     * @param deviceId
     * @return
     */
    @PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')")
    @PostMapping("/deviceChannel/deleteSettingDeviceChannel")
    public R deleteSettingDeviceChannel(Long deviceId){
        deviceClient.deleteSettingDeviceChannel(deviceId);
        return R.ok();
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')")
    @PostMapping("/deviceChannel/updateSettingDeviceChannel")
    public R updateSettingDeviceChannel(DeviceInfoVo vo){
        DeviceInfoDto dto = new DeviceInfoDto();
        BeanUtils.copyProperties(vo,dto);
        deviceClient.updateSettingDeviceChannel(dto);
        return R.ok();
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')")
    @PostMapping("/deviceChannel/queryTotalStatisticsDeviceChannel")
    public R queryTotalStatisticsDeviceChannel(@RequestParam(value="channelIds", required = false) List<Long> channelIds){

        if (channelIds == null){
            channelIds = new LinkedList<>();
        }

        List<DeviceChannelStatisticsDto> list = deviceClient.queryTotalStatisticsDeviceChannel(channelIds);

        list.forEach(dto -> {
            DepartmentDto departmentDto = userClient.deptInfo(dto.getDeptId());
            dto.setDeptName(departmentDto.getName());
        });

        return R.ok().put("data",list);
    }

    @PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')")
    @PostMapping("/device/uploadDeivceChannelExcel")
    public R uploadDeivceChannelExcel(@RequestBody UploadDeviceChannelExcelVo vo){
        UploadDeviceChannelExcelDto dto = new UploadDeviceChannelExcelDto();
        BeanUtils.copyProperties(vo,dto);
        deviceClient.uploadDeivceChannelExcel(dto);
        return R.ok();
    }

    @PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')")
    @PostMapping("/device/uploadDeivceExcel")
    public R uploadDeivceExcel(@RequestBody UploadDeviceChannelExcelVo vo){
        UploadDeviceChannelExcelDto dto = new UploadDeviceChannelExcelDto();
        BeanUtils.copyProperties(vo,dto);
        deviceClient.uploadDeivceExcel(dto);
        return R.ok();
    }


    @RequestMapping(value = "/device/downloadDeviceUploadFile", method = RequestMethod.GET)
    public ResponseEntity<InputStreamResource> downloadDeviceUploadFile(){

        ResponseEntity<InputStreamResource> response = null;
        try {
            ClassPathResource classPathResource = new ClassPathResource("template/order-Info.xlsx");

            InputStream inputStream = classPathResource.getInputStream();
            //File file = new File(path);

            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Content-Disposition",
                    "attachment; filename = 模板文件.xlsx");
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
            response = ResponseEntity.ok().headers(headers)
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(new InputStreamResource(inputStream));
        } catch (FileNotFoundException e1) {
            log.error("找不到指定的文件", e1);
        } catch (IOException e) {
            log.error("获取不到文件流", e);
        }
        return response;
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')")
    @RequestMapping("/device/queryDeviceChannelSetting")
    public R queryDeviceChannelSetting(@RequestBody List<String> imeis){

        if (imeis != null || imeis.size() != 0){
            List<String> imeiList = deviceClient.queryDeviceChannelSetting(imeis);
            return R.ok().put("data",imeiList);
        }

        return R.error(ResultCode.PARAMERROR,"参数错误");
    }

    @PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')")
    @RequestMapping("/deviceChannel/deleteStatisticsDeviceChannel")
    public R deleteStatisticsDeviceChannel(StatisticsDeviceChannelVo vo){
        if (vo == null){
            return R.error(ResultCode.PARAMERROR,"参数错误");
        }
        StatisticsDeviceChannelDto dto = new StatisticsDeviceChannelDto();
        BeanUtils.copyProperties(vo,dto);
        deviceClient.deleteStatisticsDeviceChannel(dto);
        return R.ok();
    }

    @RequestMapping("/device/uploadNewDeviceInfo")
    public R uploadNewDeviceInfo(DeviceInfoVo vo){
        if (vo.getImei() == null || vo.getImei().isEmpty()){
            return  R.error(ResultCode.PARAMERROR,"没有传入imei");
        }

        DeviceInfoDto dto = new DeviceInfoDto();

        BeanUtils.copyProperties(vo,dto);


        if (vo.getActiveTime() != null && !vo.getActiveTime().isEmpty()){
            SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                dto.setActiveTime(sDateFormat.parse(vo.getActiveTime()));
            } catch (ParseException e) {
                return R.error(ResultCode.PARAMERROR,"时间参数有误");
            }
        }

        // 先检查是否有该imei设备 ，如果没有则返回没有该设备的状态码
        DeviceInfoDto deviceInfoDto = deviceClient.queryDeviceByImei(vo.getImei());

        if (deviceInfoDto == null){
            return R.error(ResultCode.NOTFOUND_IMEI,"系统没有该设备");
        }

        // 再进行设置
        deviceClient.updateDevice(dto);
        return R.ok();
    }




}
