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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.casic.missiles.core.application.service.AbstractDictService;
import com.casic.missiles.modular.system.constant.BusWellConst;
import com.casic.missiles.core.base.controller.ExportController;
import com.casic.missiles.model.response.ErrorResponseData;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.model.response.SuccessResponseData;
import com.casic.missiles.core.common.annotion.BussinessLog;
import com.casic.missiles.core.application.context.AbstractPermissionContext;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.model.exception.ServiceException;
import com.casic.missiles.model.exception.enums.CoreExceptionEnum;
import com.casic.missiles.model.log.LogObjectHolder;
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.util.Utility;
import com.casic.missiles.quartz.service.IQuartzManager;
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.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

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

import com.casic.missiles.core.page.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.annotation.Resource;
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);

    @Resource
    private AbstractPermissionContext permissionService;

    @Resource
    private IBusWellInfoService busWellInfoService;
    @Resource
    private AbstractDictService dictService;
    @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) {

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

    /**
     * 获取分页列表
     */
    @RequestMapping(value = "/listPage")
    @ResponseBody
    public Object listPage(String condition) {
        Page<BusWellInfo> page = PageFactory.defaultPage();
        QueryWrapper<BusWellInfo> query = new QueryWrapper<>();
        page = busWellInfoService.page(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(null==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.save(busWellInfo);
        } catch (Exception e) {
            ServiceException gunsException = new ServiceException(CoreExceptionEnum.REQUEST_NULL);
            String errorMsg = "井添加失败";
            if (e instanceof DuplicateKeyException) {
                errorMsg = "井编号重复";
            } else if (e instanceof ServiceException) {
                ServiceException gunException = (ServiceException) e;
                errorMsg = gunException.getMessage();
            }
            logger.error("井添加失败", e);
            gunsException.setErrorMessage(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.getById(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 (null == busWellInfo.getId()) {
            throw new ServiceException(CoreExceptionEnum.REQUEST_NULL);
        }

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

        Utility.convertCoordinate(busWellInfo);

        if(ObjectUtil.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.getById(busWellInfoId));
    }

    /**
     * 获取闸井详情
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @ResponseBody
    public Object info(Long id) {
        if (null == id) {
            throw new ServiceException(CoreExceptionEnum.REQUEST_NULL);
        }

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

        return resultData;
    }






    /**
     * 闸井布防撤防接口
     */
    @RequestMapping(value = "/bfcf", method = RequestMethod.POST)
    @ResponseBody
    public Object bfcf(Long wellId, String bfzt) {
        if (null ==wellId || StrUtil.isEmpty(bfzt)) {
            throw new ServiceException(CoreExceptionEnum.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.getAuthService().getLoginUserDataScope();
        List<Long> deptIds = dataScope.getDeptIds();
        busWellInfoService.updateBatchBfcf(keywords, wellType, deptid, bfzt, deptIds);

        return ResponseData.success();
    }



    /**
     * 批量导入闸井接口
     */
    @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()) {
                results = this.importExcel(BusWellInfo.class,file,null,null);

                List<String> list = busWellInfoService.addWellBatch(results);

                if (!CollectionUtil.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();
    }


    @RequestMapping(value = "/batchExport", method = RequestMethod.GET)
    @ResponseBody
    public void batchExport(HttpServletResponse response, String keywords, String wellType, String deptid) throws IOException {

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

        });
        //获取导出文件header
//        DEVICE_EXPORT(new ArrayList() {{
//            add(new Header("井编号", "wellCode"));
//            add(new Header("井名称", "wellName"));
//            add(new Header("井深", "deep"));
//            add(new Header("详细地址", "position"));
//            add(new Header("井类型", "wellTypeName"));
//            add(new Header("权属单位", "deptName"));
//            add(new Header("设备数量", "deviceCount"));
//            add(new Header("布防状态", "bfztName"));
//        }}, "sluicewell.xlsx", "井数据导出");SluicewellExportEnum.DEVICE_EXPORT
        super.exportExcel(BatchExportDataDto.class, list,"");

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

    /**
     * 获取闸井是否存在接口
     */
    @RequestMapping(value = "/selectOne", method = RequestMethod.GET)
    @ResponseBody
    public Object selectOne(String wellCode) {
        if (StrUtil.isEmpty(wellCode)) {
            throw new ServiceException(CoreExceptionEnum.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){
        QueryWrapper<BusWellInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("WELL_CODE",wellCode);
        wrapper.eq("valid",1);
        return  new SuccessResponseData(busWellInfoService.getOne(wrapper));
    }

}
