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

import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.plugins.Page;
import com.casic.missiles.modular.system.constant.ModularDictConst;
import com.casic.missiles.modular.system.enums.DeviceExportEnum;
import com.casic.missiles.modular.system.model.BusConcentrator;
import com.casic.missiles.modular.system.service.IBusConcentratorService;
import com.casic.missiles.core.base.controller.ExportController;
import com.casic.missiles.core.base.response.ErrorResponseData;
import com.casic.missiles.core.base.response.ResponseData;
import com.casic.missiles.core.common.annotion.BussinessLog;
import com.casic.missiles.core.common.annotion.Permission;
import com.casic.missiles.core.common.constant.factory.PageFactory;
import com.casic.missiles.core.common.service.ICommonPermissionService;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.core.exception.GunsException;
import com.casic.missiles.core.exception.GunsExceptionEnum;
import com.casic.missiles.core.util.DateUtil;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.dict.ConcentDict;
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.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 控制器
 *
 * @author dev
 * @Date 2019-06-03 10:02:11
 */
@Controller
@RequestMapping("/concentrator")
public class BusConcentratorController extends ExportController {
    private static final Logger logger = LoggerFactory.getLogger(DeviceController.class);
    @Autowired
    private IBusConcentratorService busConcentratorService;

    @Autowired
    private ICommonPermissionService permissionService;


    @ApiOperation("获取集中器列表")
    @GetMapping(value = "/list")
    @Permission
    @ResponseBody
    public Object list(String keywords, String status) {
        DataScope dataScope = permissionService.getCurrUserDataScope();
        Page<BusConcentrator> page = new PageFactory().defaultPage();
        page.setRecords(busConcentratorService.selectConcentratorPage(page, dataScope, keywords, status));
        if (ToolUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(busConcentrator -> {
                busConcentrator.setStatusName(permissionService.getDictNameByCode(ModularDictConst.ONLINESTATUS, busConcentrator.getStatus()));
                busConcentrator.setDeptName(permissionService.getDeptName(busConcentrator.getDeptid()));
                busConcentrator.setLasttimeFormat(DateUtil.format(busConcentrator.getLasttime(), "yyyy-MM-dd HH:mm:ss"));
            });
        }
        return ResponseData.success(super.packForBT(page));
    }


    /**
     * 新增
     */
    @PostMapping(value = "/add")
    @BussinessLog(value = "新增集中器", key = "concencode,simid,position,lat,lng", dict = ConcentDict.class)
    @Permission
    @ResponseBody
    public Object add(@Valid BusConcentrator busConcentrator, BindingResult result) {
        if (result.hasErrors()) {
            return ResponseData.error(result.getFieldErrors().get(0).getDefaultMessage());
        }
        if (ToolUtil.isEmpty(busConcentrator.getDeptid())) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }
        try {
            if (ToolUtil.isEmpty(busConcentrator.getSetupdate())) {
                busConcentrator.setSetupdate(new Date());
            }
            busConcentratorService.insert(busConcentrator);
        } catch (Exception e) {
            GunsException gunsException = new GunsException(GunsExceptionEnum.REQUEST_NULL);
            String errorMsg = "集中器添加失败";
            e.printStackTrace();
            if (e instanceof DuplicateKeyException) {
                errorMsg = "集中器编号重复";
            } else if (e instanceof GunsException) {
                GunsException gunException = (GunsException) e;
                errorMsg = gunException.getMessage();
            }
            gunsException.setMessage(errorMsg);
            throw gunsException;
        }
        return ResponseData.success();
    }

    /**
     * 删除
     */
    @PostMapping(value = "/delete")
    @Permission
    @ResponseBody
    @BussinessLog("删除集中器")
    public Object delete(@RequestParam List<Long> ids) {
        busConcentratorService.deleteByIds(ids);
        return ResponseData.success();
    }


    @ApiOperation("修改集中器")
    @RequestMapping(value = "/update")
    @BussinessLog(value = "修改集中器", key = "concencode,simid,position,lat,lng", dict = ConcentDict.class)
    @Permission
    @ResponseBody
    public Object update(@Valid BusConcentrator busConcentrator, BindingResult result) {
        if (result.hasErrors()) {
            return ResponseData.error(result.getFieldErrors().get(0).getDefaultMessage());
        }
        if (ToolUtil.isEmpty(busConcentrator.getId())) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }
        try {
            busConcentratorService.updateById(busConcentrator);
        } catch (Exception e) {
            GunsException gunsException = new GunsException(GunsExceptionEnum.REQUEST_NULL);
            String errorMsg = "集中器修改失败";
            if (e instanceof GunsException) {
                GunsException gunException = (GunsException) e;
                errorMsg = gunException.getMessage();
            } else if (e instanceof DuplicateKeyException) {
                errorMsg = "集中器编号重复";
            }
            gunsException.setMessage(errorMsg);
            throw gunsException;
        }
        return ResponseData.success();
    }

    @ApiOperation("集中器列表导出")
    @RequestMapping(value = "/batchExport")
    @Permission
    @ResponseBody
    public void batchExport(HttpServletResponse response, String keywords, String status) throws IOException {
        DataScope dataScope = permissionService.getCurrUserDataScope();
        Page<BusConcentrator> page = new PageFactory().defaultPage();
        page.setCurrent(1);
        page.setSize(Integer.MAX_VALUE);
        page.setRecords(busConcentratorService.selectConcentratorPage(page, dataScope, keywords, status));

        if (ToolUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(busConcentrator -> {
                busConcentrator.setStatusName(permissionService.getDictNameByCode(ModularDictConst.ONLINESTATUS, busConcentrator.getStatus()));
                busConcentrator.setDeptName(permissionService.getDeptName(busConcentrator.getDeptid()));
                busConcentrator.setLasttimeFormat(DateUtil.format(busConcentrator.getLasttime(), "yyyy-MM-dd HH:mm:ss"));
                busConcentrator.setSetupdateFormat(DateUtil.format(busConcentrator.getSetupdate(), "yyyy-MM-dd"));
            });
        }
        super.exportExcel(DeviceExportEnum.BUSCONCENTRATOR_EXPORT, page.getRecords(), response);

    }

    @ApiOperation("批量导入集中器")
    @RequestMapping(value = "/batchImport", method = RequestMethod.POST)
    @Permission
    @ResponseBody
    public Object batchImport(@RequestParam("file") MultipartFile file) {
        List<BusConcentrator> results = new ArrayList<>();
        //设置表头与字段映射,可通过反射获取
        Map<String, String> mapper = new HashMap<>();
        mapper.put("集中器编号", "concencode");//判断唯一
        mapper.put("集中器SIM卡号", "simid");
        mapper.put("安装位置", "position");//
        mapper.put("权属单位", "deptid");//
        mapper.put("纬度", "lat");//需要转换
        mapper.put("经度", "lng");
        mapper.put("安装时间", "setupdateFormat");
        try {
            try (InputStream in = file.getInputStream()) {
                ExcelIO.read(in, mapper, BusConcentrator.class, (row) -> {
                    //仅读取第一个sheet
                    if (row.getSheet() == 0) {
                        if (row.getResult() != null) {
                            BusConcentrator busConcentrator = row.getResult();
                            //过滤设备编号及设备名称都为空的数据 (判定为空行不导入该行)
                            if (!ToolUtil.isAllEmpty(busConcentrator.getConcencode(), busConcentrator.getSimid())) {
                                results.add(busConcentrator);
                            }
                        }
                    } else {
                        //其他sheet停止读取
                        logger.info("当前sheet" + row.getSheet() + ",停止读取");
                        row.shutdown();
                    }
                });

                List<String> list = busConcentratorService.addDeviceBatch(results);

                if (!ToolUtil.isEmpty(list)) {
                    //获取第校验报错信息
                    return new ErrorResponseData(list.get(0));
                }

            }
        } catch (Exception e) {
            return catchMybatisPlusException(e, "导入集中器失败");
        }

        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("集中器编号重复:" + message.replaceAll("Duplicate entry '", "").replaceAll("' for key 'CONCENCODE'", ""));
            }
        }
        logger.error(errorMsg, e);
        return new ErrorResponseData(errorMsg);
    }

}
