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

import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
import com.casic.missiles.modular.system.constant.BusWellConst;
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.base.response.SuccessResponseData;
import com.casic.missiles.core.common.annotion.BussinessLog;
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.log.LogObjectHolder;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.dict.BusWellDict;
import com.casic.missiles.modular.system.dto.BatchExportDataDto;
import com.casic.missiles.modular.system.dto.HasWellDto;
import com.casic.missiles.modular.system.enmus.SluicewellExportEnum;
import com.casic.missiles.modular.system.util.Utility;
import com.casic.missiles.quartz.job.MyJob;
import com.casic.missiles.quartz.service.IQuartzManager;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.hswebframework.expands.office.excel.ExcelIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.mapper.EntityWrapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import com.casic.missiles.core.common.constant.factory.PageFactory;
import com.casic.missiles.modular.system.model.BusWellInfo;
import com.casic.missiles.modular.system.service.IBusWellInfoService;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * 控制器
 *
 * @author dev
 * @Date 2019-05-13 19:20:29
 */
@Controller
@RequestMapping("/well")
public class BusWellInfoController extends ExportController {
    private static final Logger logger = LoggerFactory.getLogger(BusWellInfoController.class);

    @Autowired
    private ICommonPermissionService permissionService;

    @Autowired
    private IBusWellInfoService busWellInfoService;

    @Autowired
    public IQuartzManager quartzManager;

    @Value("${smartcity.config.export-path}")
    private String exportPath;


    /**
     * 获取列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Object list(String keywords, String wellType, String deptid, String bfzt, String areaId) {

        Page<BusWellInfo> page = new PageFactory<BusWellInfo>().defaultPage();
        //查询数据权限 使用默认DEPTID 字段
        DataScope dataScope = permissionService.getCurrUserDataScope();
        List<String> roleTipes = permissionService.getCurrLoginUser().getRoleTips();
        if (roleTipes.contains("leader") || roleTipes.contains("member")) {
            dataScope.setScopeName("responsibleDept");
            List<Long> responsibleDeptIds = new ArrayList<>();
            responsibleDeptIds.add(permissionService.getCurrLoginUser().getDeptId());
            dataScope.setDeptIds(responsibleDeptIds);
        }
        areaId += "%";
        List<BusWellInfo> list = busWellInfoService.selectDataScopePage(dataScope, page, keywords, wellType, deptid, bfzt, areaId);
        page.setRecords(list);
        return new SuccessResponseData(super.packForBT(page));
    }

    /**
     * 获取分页列表
     */
    @RequestMapping(value = "/listPage")
    @ResponseBody
    public Object listPage(String condition) {
        Page<BusWellInfo> page = new PageFactory<BusWellInfo>().defaultPage();
        EntityWrapper<BusWellInfo> query = new EntityWrapper<>();
        page = busWellInfoService.selectPage(page, query);
        return super.packForBT(page);
    }

    /**
     * 新增
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    @BussinessLog(value = "添加井", key = BusWellConst.SLUICEWELL_ADD_LOG_KEY, dict = BusWellDict.class)
    public Object add(BusWellInfo busWellInfo) {

        Utility.convertCoordinate(busWellInfo);

        try {
            if(ToolUtil.isEmpty(busWellInfo.getResponsibleDept())){
                busWellInfo.setResponsibleDept(busWellInfo.getDeptid());
            }

//            List<User> deptTopRoleUsers = permissionService.getRoleUsersByTips(busWellInfo.getResponsibleDept(),"leader",true);
//            if(ToolUtil.isNotEmpty(deptTopRoleUsers)){
//                busWellInfo.setStaff(deptTopRoleUsers.get(0).getId().toString());
//            }

            busWellInfoService.insert(busWellInfo);
        } catch (Exception e) {
            GunsException gunsException = new GunsException(GunsExceptionEnum.REQUEST_NULL);
            String errorMsg = "井添加失败";
            if (e instanceof DuplicateKeyException) {
                errorMsg = "井编号重复";
            } else if (e instanceof GunsException) {
                GunsException gunException = (GunsException) e;
                errorMsg = gunException.getMessage();
            }
            logger.error("井添加失败", e);
            gunsException.setMessage(errorMsg);
            throw gunsException;
        }

        return ResponseData.success();
    }

    /**
     * 批量删除
     */
    @PostMapping(value = "/delete")
    @ResponseBody
    @BussinessLog(value = "删除井信息")
    public Object delete(@RequestParam List<Long> ids) {
        List<Long> notDelIds = busWellInfoService.deleteBatchByIds(ids);
        if(notDelIds.size() > 0){
            String message = "";
            for(Long notDelId : notDelIds){
                BusWellInfo busWellInfo = busWellInfoService.selectById(notDelId);
                message += busWellInfo.getWellCode() + ",";
            }
            return ResponseData.error(message + "以上井存在绑定设备，请先解绑后再删除井！");
        }

        return ResponseData.success();
    }

    /**
     * 修改闸井信息
     */
    @RequestMapping(value = "/update")
    @ResponseBody
    @BussinessLog(value = "修改井信息", key = BusWellConst.SLUICEWELL_ADD_LOG_KEY, dict = BusWellDict.class)
    public Object update(BusWellInfo busWellInfo) {
        if (ToolUtil.isEmpty(busWellInfo.getId())) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }

        BusWellInfo oldBusWellInfo = this.busWellInfoService.selectById(busWellInfo.getId());
        LogObjectHolder.me().set(oldBusWellInfo);

        Utility.convertCoordinate(busWellInfo);

        if(ToolUtil.isEmpty(busWellInfo.getResponsibleDept())){
            busWellInfo.setResponsibleDept(busWellInfo.getDeptid());
        }

//        List<User> deptTopRoleUsers = permissionService.getRoleUsersByTips(busWellInfo.getResponsibleDept(),"leader",true);
//        if(ToolUtil.isNotEmpty(deptTopRoleUsers)){
//            busWellInfo.setStaff(deptTopRoleUsers.get(0).getId().toString());
//        }

        busWellInfoService.updateById(busWellInfo);
        return ResponseData.success();
    }

    /**
     * 详情
     */
    @RequestMapping(value = "/detail/{busWellInfoId}")
    @ResponseBody
    public Object detail(@PathVariable("busWellInfoId") String busWellInfoId) {

        return ResponseData.success(busWellInfoService.selectById(busWellInfoId));
    }

    /**
     * 获取闸井详情
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @ResponseBody
    public Object info(Integer id) {
        if (ToolUtil.isEmpty(id)) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }

        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setData(busWellInfoService.selectById(id));

        return resultData;
    }


    /**
     * 获取闸井设备数据
     */
    @RequestMapping(value = "/watchDataByWell", method = RequestMethod.GET)
    @ResponseBody
    public Object watchDataByWell(Long id) {
        if (ToolUtil.isEmpty(id)) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }
        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setData(busWellInfoService.getWatchDatas(id));

        return resultData;
    }

    /**
     * 根据布防状态统计闸井数量接口
     */
    @RequestMapping(value = "/countByBfzt", method = RequestMethod.GET)
    @ResponseBody
    public Object countByBfzt() {
        DataScope dataScope = permissionService.getCurrUserDataScope();
        List<String> roleTipes = permissionService.getCurrLoginUser().getRoleTips();
        List<Long> deptIds = null;
        Boolean isApp = false;
        if (roleTipes.contains("leader") || roleTipes.contains("member")) {
            deptIds = permissionService.getSubDepts(permissionService.getCurrLoginUser().getDeptId(), null);
            deptIds.add(permissionService.getCurrLoginUser().getDeptId());
            isApp = true;
        }else{
            deptIds = dataScope.getDeptIds();
            isApp = false;
        }
        SuccessResponseData resultData = new SuccessResponseData();
        busWellInfoService.getBfztCountData(deptIds,isApp);


        resultData.setData(busWellInfoService.getBfztCountData(deptIds,isApp));
        return resultData;
    }

    /**
     * 闸井布防撤防接口
     */
    @RequestMapping(value = "/bfcf", method = RequestMethod.POST)
    @ResponseBody
    public Object bfcf(Long wellId, String bfzt) {
        if (ToolUtil.isEmpty(wellId) || ToolUtil.isEmpty(bfzt)) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }

        BusWellInfo busWellInfo = new BusWellInfo();
        busWellInfo.setId(wellId);
        busWellInfo.setBfzt(bfzt);
        busWellInfoService.updateById(busWellInfo);
        return ResponseData.success();
    }

    /**
     * 闸井批量布防撤防接口
     */
    @RequestMapping(value = "/batchBfcf", method = RequestMethod.POST)
    @ResponseBody
    public Object batchBfcf(String keywords, String wellType, String deptid, String bfzt) {

        DataScope dataScope = permissionService.getCurrUserDataScope();
        List<Long> deptIds = dataScope.getDeptIds();
        busWellInfoService.updateBatchBfcf(keywords, wellType, deptid, bfzt, deptIds);

        return ResponseData.success();
    }

    /**
     * 获取布防类型（APP用）
     */
    @RequestMapping(value = "/bfType", method = RequestMethod.GET)
    @ResponseBody
    public Object bfType(Long id) {
        if (ToolUtil.isEmpty(id)) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }
        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setData(busWellInfoService.getWatchDatas(id));

        return resultData;
    }


    /**
     * 批量导入闸井接口
     */
    @RequestMapping(value = "/batchImport", method = RequestMethod.POST)
    @ResponseBody
    public Object batchImport(@RequestParam("file") MultipartFile file) throws Exception {

        List<BusWellInfo> results = new ArrayList<>();
        //设置表头与字段映射,可通过反射获取
        Map<String, String> mapper = new HashMap<>();
        mapper.put("井编号", "wellCode");//判断唯一
        mapper.put("井名称", "wellName");
        mapper.put("井深", "deep");
        mapper.put("区", "qu");
        mapper.put("街道", "area");
        mapper.put("详细地址", "position");
        mapper.put("经度", "coordinateX");
        mapper.put("纬度", "coordinateY");
        mapper.put("井类型", "wellType");
        mapper.put("权属单位代码", "deptid");
        mapper.put("井维护单位代码", "responsibleDept");
        try {
            try (InputStream in = file.getInputStream()) {
                ExcelIO.read(in, mapper, BusWellInfo.class, (row) -> {
                    //读取sheet
                    if (row.getSheet() == 0) {
                        if (row.getResult() != null) {
                            BusWellInfo busWellInfo = row.getResult();
                            results.add(busWellInfo);
                        }
                    } else {
                        //其他sheet停止读取
                        logger.info("当前sheet" + row.getSheet() + ",停止读取");
                        row.shutdown();
                    }
                });
                List<String> list = busWellInfoService.addWellBatch(results);

                if (!ToolUtil.isEmpty(list)) {
                    //获取第校验报错信息
                    return new ErrorResponseData(list.get(0));
                }
            }
        } catch (MybatisPlusException e) {
            logger.error("导入井列表失败", e);
            String message = e.getCause().getCause().getCause().getMessage();
            if (message.contains("Duplicate entry '")) {
                return new ErrorResponseData("导入井列表失败，井编号" + message.replaceAll("Duplicate entry '", "").replaceAll("' for key 'WELL_CODE'", "") + "已存在");
            }
            return new ErrorResponseData("导入井列表失败");

        } catch (Exception e) {
            logger.error("导入井列表失败", e);
            return new ErrorResponseData("导入井列表失败");
        }
        return ResponseData.success();
    }


    @ApiOperation("批量导出井接口")
    @RequestMapping(value = "/batchExport", method = RequestMethod.GET)
    @ResponseBody
    public void batchExport(HttpServletResponse response, String keywords, String wellType, String deptid) throws IOException {

        Page<BatchExportDataDto> page = new PageFactory<BatchExportDataDto>().defaultPage();
        page.setSearchCount(false);
        page.setCurrent(1);
        page.setSize(Integer.MAX_VALUE);
        DataScope dataScope = permissionService.getCurrUserDataScope();
        List<BatchExportDataDto> list = busWellInfoService.getBatchExportData(dataScope, page, wellType, deptid, keywords);
        list.forEach(batchExportDataDto -> {
            batchExportDataDto.setBfztName(permissionService.getDictNameByCode("bfzt", batchExportDataDto.getBfzt()));
//            batchExportDataDto.setDeviceCount(busWellInfoService.getDeviceCountData(batchExportDataDto.getId()));
//            batchExportDataDto.setDeptName(busWellInfoService.getDeptNameData(batchExportDataDto.getDeptId()));
            batchExportDataDto.setWellTypeName(permissionService.getDictNameByCode(BusWellConst.SLUICEWELL_TYPE, batchExportDataDto.getWellType()));
            batchExportDataDto.setDeptName(permissionService.getDeptName(batchExportDataDto.getDeptId()));

        });

        List<Object> res = new ArrayList<>();
        res.addAll(list);
        //获取导出文件header
        super.exportExcel(SluicewellExportEnum.DEVICE_EXPORT, res);

        //super.exportExcel(SluicewellExportEnum.SLUICEWELLDATA_EXPORT, list, response);
    }

    /**
     * 获取闸井是否存在接口
     */
    @RequestMapping(value = "/selectOne", method = RequestMethod.GET)
    @ResponseBody
    public Object selectOne(String wellCode) {
        if (StringUtils.isEmpty(wellCode)) {
            throw new GunsException(GunsExceptionEnum.REQUEST_NULL);
        }

        HasWellDto hasWellDto = new HasWellDto();
        hasWellDto.setHasWell(busWellInfoService.isExistWellCode(wellCode));

        SuccessResponseData resultData = new SuccessResponseData();
        resultData.setData(hasWellDto);
        return resultData;
    }

    /**
     * 全部坐标转换接口
     * @return
     */
    @RequestMapping(value = "/changeCoordinates", method = RequestMethod.GET)
    @ResponseBody
    public Object changeCoordinates(int startNumber){
        Boolean result = busWellInfoService.changeCoordinates(startNumber);
        if(result==true){
            return  new SuccessResponseData(200,"转换成功",null);

        }else{
            return  new SuccessResponseData(200,"转换失败",null);
        }
    }

//    @RequestMapping(value = "/quartz")
//    @ResponseBody
//    public void quartz() {
//
//        //quartzManager.resumeJob();
//        quartzManager.addJob("test8", MyJob.class,120);
//
//        return;
//    }


    /**
     * 根据井编号获取井信息
     * @return
     */
    @RequestMapping(value = "/getWellByCode", method = RequestMethod.GET)
    @ResponseBody
    public Object getWellByCode(String wellCode){
        EntityWrapper<BusWellInfo> wrapper = new EntityWrapper<>();
        wrapper.eq("WELL_CODE",wellCode);
        wrapper.eq("valid",1);
        return  new SuccessResponseData(busWellInfoService.selectOne(wrapper));
    }

}
