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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.application.context.AbstractPermissionContext;
import com.casic.missiles.core.base.controller.ExportController;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.core.model.auth.AuthUser;
import com.casic.missiles.core.page.PageFactory;
import com.casic.missiles.core.util.EhcacheConstant;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.alarm.model.JobExcelDto;
import com.casic.missiles.modular.alarm.model.JobListParam;
import com.casic.missiles.modular.alarm.service.IAlarmJobService;

import com.casic.missiles.modular.alarm.service.ISysDictService;
import com.casic.missiles.modular.system.enums.DeviceExportEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 控制器
 *
 * @author dev
 * @Date 2019-05-17 10:48:36
 */
@Controller
@Slf4j
@RequestMapping("/job")
public class AlarmJobController extends ExportController {


    @Autowired
    private IAlarmJobService alarmJobService;
    @Resource
    private AbstractPermissionContext iCommonPermissionService;
    @Autowired
    private ISysDictService iSysDictService;

    @Value("${smartcity.office.maxRowsExcel}")
    private int maxRowsExcel;
    @Value("${smartcity.leaderRoleName}")
    private String sLeader;
    @Value("${smartcity.memberRoleName}")
    private String sMember;
    @Value("${smartcity.adminRoleName}")
    private String sAdmin;
    @Value("${smartcity.opRoleName}")
    private String sOperation;
    @Value("${smartcity.config.config-path}")
    private String templatePath;


    /**
     * 统计接口，统计工单状态的数量
     *
     * @param httpServletRequest
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "/countByJobStatus")
    @ResponseBody
    public Object countByJobStatus(HttpServletRequest httpServletRequest) throws ParseException {
        String beginTime = httpServletRequest.getParameter("beginTime");
        String endTime = httpServletRequest.getParameter("endTime");
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        Map<String, Object> retObj = new HashMap<>();
        //pc角色
        if (alarmJobService.checkPcRole(currentUser.getRoleTips())) {
            String alarmType = null;
            //operation和admin可以看两种异常，其他只能看一种
            if (!currentUser.getRoleTips().contains(sOperation) && !currentUser.getRoleTips().contains(sAdmin)) {
                alarmType = "1";
            }
            retObj.put("beforeGet", alarmJobService.countByDataScope(dataScope, alarmType, "0", beginTime, endTime));
            retObj.put("beforeConfirm", alarmJobService.countByDataScope(dataScope, alarmType, "1", beginTime, endTime));
            retObj.put("inHandle", alarmJobService.countByDataScope(dataScope, alarmType, "2", beginTime, endTime));
            retObj.put("over", alarmJobService.countByDataScope(dataScope, alarmType, "3", beginTime, endTime));
            retObj.put("cancel", alarmJobService.countByDataScope(dataScope, alarmType, "4", beginTime, endTime));
        } else {
            //app角色
            Integer beforeGet = alarmJobService.countByResponse("1", "0", currentUser.getDeptId(), beginTime, endTime);
            retObj.put("beforeGet", beforeGet);

            Integer myBeforeConfirm = alarmJobService.countByUser("1", "1", currentUser.getId(), beginTime, endTime);
            Integer myInHandle = alarmJobService.countByUser("1", "2", currentUser.getId(), beginTime, endTime);
            Integer myOver = alarmJobService.countByUser("1", "3", currentUser.getId(), beginTime, endTime);
            Integer myCancel = alarmJobService.countByUser("1", "4", currentUser.getId(), beginTime, endTime);

            if (currentUser.getRoleTips().contains(sLeader)) {
                Integer beforeConfirm = alarmJobService.countByResponse("1", "1", currentUser.getDeptId(), beginTime, endTime);
                Integer inHandle = alarmJobService.countByResponse("1", "2", currentUser.getDeptId(), beginTime, endTime);
                Integer over = alarmJobService.countByResponse("1", "3", currentUser.getDeptId(), beginTime, endTime);
                Integer cancel = alarmJobService.countByResponse("1", "4", currentUser.getDeptId(), beginTime, endTime);

                retObj.put("beforeConfirm", myBeforeConfirm + "/" + beforeConfirm);
                retObj.put("inHandle", myInHandle + "/" + inHandle);
                retObj.put("over", myOver + "/" + over);
                retObj.put("cancel", myCancel + "/" + cancel);
            } else {
                retObj.put("beforeConfirm", myBeforeConfirm);
                retObj.put("inHandle", myInHandle);
                retObj.put("over", myOver);
                retObj.put("cancel", myCancel);
            }
        }

        return ResponseData.success(retObj);
    }

    /**
     * 获取分页列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object listPage(HttpServletRequest httpServletRequest) {
        String keywords = httpServletRequest.getParameter("keywords");
        String beginTime = httpServletRequest.getParameter("beginTime");
        String endTime = httpServletRequest.getParameter("endTime");
        String jobStatusStr = httpServletRequest.getParameter("jobStatus");
        String alarmTypeStr = httpServletRequest.getParameter("alarmType");
        String alarmContentStr = httpServletRequest.getParameter("alarmContentType");
        Page<Map<String, Object>> page = PageFactory.defaultPage();
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> retList = new ArrayList<>();
        if (alarmJobService.checkPcRole(currentUser.getRoleTips())) {
            // pc角色
            //operation和admin能查设备异常，其他只能查数据异常
            if (!currentUser.getRoleTips().contains(sOperation) && !currentUser.getRoleTips().contains(sAdmin)) {
                alarmTypeStr = "1";
            }
            retList = alarmJobService.jobList(page, keywords, beginTime, endTime, jobStatusStr, alarmTypeStr, alarmContentStr, dataScope, currentUser.getId());
        } else {
            //app角色
            long leaderId = 0L;
            if (currentUser.getRoleTips().contains(sLeader)) {
                // 组长，查组内全部
                leaderId = currentUser.getId();
                if (StrUtil.isNotEmpty(jobStatusStr)) {
                    //learder&&jobStatus=1,2,3时，关闭传入的sort，按sql排序(自己的排在前)
                    page.setSearchCount(!alarmJobService.checkJobStatus(jobStatusStr));
                }
            }
            retList = alarmJobService.jobListApp(page, keywords, beginTime, endTime, jobStatusStr, alarmTypeStr, alarmContentStr, currentUser.getDeptId(), currentUser.getId(), leaderId);
        }
        retList.forEach(this::alarmJobWrapper);
        page.setRecords(retList);
        return ResponseData.success(super.packForBT(page));
    }

    private void alarmJobWrapper(Map<String, Object> map) {
        // 设置人员姓名
        for (String key : map.keySet()) {
            if (key.contains("getJobPerson") || key.contains("jobBelongTo") ||
                    key.contains("handleJobPerson") || key.contains("confirmJobPerson")) {
                Object object = map.get(key);
                if (!ObjectUtil.isEmpty(object)) {
                    String newVal = EhcacheConstant.retBean().getUsernameById(Long.parseLong(String.valueOf(object)));
                    map.replace(key, newVal);
                }
            }
        }

        //设置闸井相关字段
        String wellCode = map.get("wellCode").toString();
        Map<String, Object> wellInfoMap = EhcacheConstant.retBean().getWellInfoViaCode(wellCode);
        // 设置权属单位、负责人、联系电话
        String deptidStr = wellInfoMap.get("deptid").toString();
        long deptid = StrUtil.isEmpty(deptidStr) ? -1 : Long.valueOf(deptidStr);
        map.put("deptName", EhcacheConstant.retBean().getDeptNameById(deptid));
        if (deptid > 0) {
            Long staffstr = EhcacheConstant.retBean().getUserByDept(deptid);
            if (ObjectUtil.isEmpty(staffstr)) {
                wellInfoMap.replace("staff", "");
                wellInfoMap.replace("tel", "");
            } else {
                Map<String, Object> userInfoMap = EhcacheConstant.retBean().getUserInfoById(staffstr);
                if (!ObjectUtil.isEmpty(userInfoMap)) {
                    wellInfoMap.putAll(userInfoMap);
                }
            }
        }
        map.putAll(wellInfoMap);

        // 告警类型
        String alarmTypeStr = map.get("alarmType").toString();
        map.put("alarmTypeName", EhcacheConstant.retBean().getAlarmTypeNameByCodeNum(alarmTypeStr));

        // 告警内容
        String alarmContentNameStr = map.get("alarmContentName").toString();
        map.put("alarmContent", EhcacheConstant.retBean().getAlarmContentByName(alarmContentNameStr));

        // 告警值加单位
        if (ObjectUtil.isNotEmpty(map.get("alarmValue"))) {
            String alarmValue = map.get("alarmValue").toString();
            String alarmContentName = map.get("alarmContentName").toString();
            if ("液位超限".equals(alarmContentName)) {
                alarmValue += "m";
                map.replace("alarmValue", alarmValue);
            }
            if ("浓度超限".equals(alarmContentName)) {
                alarmValue += "%LEL";
                map.replace("alarmValue", alarmValue);
            }
            if ("疑似开挖".equals(alarmContentName)) {
                alarmValue += "mg";
                map.replace("alarmValue", alarmValue);
            }
        }

        // 工单状态
        String jobStatusStr = map.get("jobStatus").toString();
        map.put("jobStatusName", EhcacheConstant.retBean().getJobStatusNameByCodeNum(jobStatusStr));

        // 告警值
        if (alarmContentNameStr.contains("井盖") || "2".equals(alarmTypeStr)) {
            map.replace("alarmValue", "--");
        }

        // 流转记录（工单详情用）
        if (map.containsKey("flow")) {
            String flow = (String) map.get("flow");
            flow = "[" + flow.replaceFirst(",", "") + "]";
            List<Map> list = new ArrayList<>();
            JSONArray jsonArray = JSONArray.parseArray(flow);
            list = jsonArray.toJavaList(Map.class);
            map.replace("flow", list);
        }
    }

    /**
     * 工单查询接口 APP用
     */
    @RequestMapping(value = "/searchList")
    @ResponseBody
    public Object jobListSearch(@RequestBody JobListParam jobListParam) {
        Page<Map<String, Object>> page = PageFactory.defaultPage();
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> retList = new ArrayList<>();
        if (alarmJobService.checkPcRole(currentUser.getRoleTips())) {
            // pc角色
            retList = alarmJobService.jobListSearch(page, jobListParam, dataScope, currentUser.getId());
        } else {
            //app角色
            long leaderId = 0L;
            if (currentUser.getRoleTips().contains(sLeader)) {
                // 组长，查组内全部
                leaderId = currentUser.getId();
                if (StrUtil.isNotEmpty(jobListParam.getJobStatus())) {
                    //learder&&jobStatus=1,2,3时，关闭传入的sort，按sql排序(自己的排在前)
                    page.setSearchCount(!alarmJobService.checkJobStatus(jobListParam.getJobStatus()));
                }
            }
            retList = alarmJobService.jobListSearchApp(page, jobListParam, currentUser.getDeptId(), currentUser.getId(), leaderId);
        }
        retList.forEach(this::alarmJobWrapper);
        page.setRecords(retList);
        Map<String, Object> retMap = new HashMap<>();
        return ResponseData.success(super.packForBT(page));
    }

    /**
     * 获取超时未接收工单
     */
    @RequestMapping(value = "/overtimeGetList")
    @ResponseBody
    public Object overtimeGetList(HttpServletRequest httpServletRequest) {
        String keywords = httpServletRequest.getParameter("keywords");
        String beginTime = httpServletRequest.getParameter("beginTime");
        String endTime = httpServletRequest.getParameter("endTime");
        String alarmTypeStr = httpServletRequest.getParameter("alarmType");
        String alarmContentStr = httpServletRequest.getParameter("alarmContentType");

        Page<Map<String, Object>> page = PageFactory.defaultPage();
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> retList = new ArrayList<>();
        if (alarmJobService.checkPcRole(currentUser.getRoleTips())) {
            // pc角色
            //operation和admin能查设备异常，其他只能查数据异常
            if (!currentUser.getRoleTips().contains(sOperation) && !currentUser.getRoleTips().contains(sAdmin)) {
                alarmTypeStr = "1";
            }
            retList = alarmJobService.jobListDelayRe(page, keywords, beginTime, endTime, alarmTypeStr, alarmContentStr, dataScope, currentUser.getId());
        } else {
            // app角色
            Long leaderId = 0L;
            if (currentUser.getRoleTips().contains(sLeader)) {
                // 组长，查组内全部
                leaderId = currentUser.getId();
            }
            retList = alarmJobService.jobListDelayReApp(page, keywords, beginTime, endTime, alarmTypeStr, alarmContentStr, currentUser.getDeptId(), currentUser.getId(), leaderId);
        }
        retList.forEach(this::alarmJobWrapper);
        page.setRecords(retList);

        return ResponseData.success(super.packForBT(page));
    }

    /**
     * 获取超时未处理工单
     */
    @RequestMapping(value = "/overtimeHandleList")
    @ResponseBody
    public Object overtimeHandleList(HttpServletRequest httpServletRequest) {
        String keywords = httpServletRequest.getParameter("keywords");
        String beginTime = httpServletRequest.getParameter("beginTime");
        String endTime = httpServletRequest.getParameter("endTime");
        String alarmTypeStr = httpServletRequest.getParameter("alarmType");
        String alarmContentStr = httpServletRequest.getParameter("alarmContentType");

        Page<Map<String, Object>> page = PageFactory.defaultPage();
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> retList = new ArrayList<>();
        if (alarmJobService.checkPcRole(currentUser.getRoleTips())) {
            // pc角色
            //operation和admin能查设备异常，其他只能查数据异常
            if (!currentUser.getRoleTips().contains(sOperation) && !currentUser.getRoleTips().contains(sAdmin)) {
                alarmTypeStr = "1";
            }
            retList = alarmJobService.jobListDelayPro(page, keywords, beginTime, endTime, alarmTypeStr, alarmContentStr, dataScope, currentUser.getId());
        } else {
            // app角色
            Long leaderId = 0L;
            if (currentUser.getRoleTips().contains(sLeader)) {
                // 组长，查组内全部
                leaderId = currentUser.getId();
            }
            retList = alarmJobService.jobListDelayProApp(page, keywords, beginTime, endTime, alarmTypeStr, alarmContentStr, currentUser.getDeptId(), currentUser.getId(), leaderId);
        }
        retList.forEach(this::alarmJobWrapper);
        page.setRecords(retList);

        return ResponseData.success(super.packForBT(page));
    }


    @RequestMapping(value = "/export")
    public void exportJob(HttpServletRequest httpServletRequest
            , HttpServletResponse httpServletResponse) throws IOException {

        Page<Map<String, Object>> page = PageFactory.defaultPage();

        page.setMaxLimit((long) maxRowsExcel);
        page.setSize(maxRowsExcel);
        page.setSearchCount(false);
        page.offset();
        String keywords = httpServletRequest.getParameter("keywords");
        String beginTime = httpServletRequest.getParameter("beginTime");
        String endTime = httpServletRequest.getParameter("endTime");
        String jobStatusStr = httpServletRequest.getParameter("jobStatus");
        String alarmTypeStr = httpServletRequest.getParameter("alarmType");
        String alarmContentStr = httpServletRequest.getParameter("alarmContentType");
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> jobExpList = alarmJobService.jobList(page, keywords, beginTime, endTime, jobStatusStr, alarmTypeStr, alarmContentStr, dataScope, currentUser.getId());
        jobExpList.forEach(this::alarmJobWrapper);
        List<JobExcelDto> jobExcelDtoList = new ArrayList<>();
        jobExpList.stream().forEach(
                alarmExp -> {
                    JobExcelDto jobExcelDto = mapToObjcet(alarmExp);

                    jobExcelDtoList.add(jobExcelDto);
                }
        );
        super.exportExcel(JobExcelDto.class, jobExcelDtoList, DeviceExportEnum.HARMFULDATA_EXPORT.getFileName());
    }

    private JobExcelDto mapToObjcet(Map<String, Object> alarmExp) {
        JobExcelDto jobExcelDto = new JobExcelDto();
        jobExcelDto.setJobCode(alarmExp.get("jobCode").toString());
        jobExcelDto.setWellCode(alarmExp.get("wellCode").toString());
        jobExcelDto.setDevcode(alarmExp.get("devcode").toString());
        jobExcelDto.setDeptName(alarmExp.get("deptName") == null ? "" : alarmExp.get("deptName").toString());
        jobExcelDto.setPosition(alarmExp.get("position") == null ? "" : alarmExp.get("position").toString());
        jobExcelDto.setAlarmTypeName(alarmExp.get("alarmTypeName") == null ? "" : alarmExp.get("alarmTypeName").toString());
        jobExcelDto.setAlarmContentName(alarmExp.get("alarmContentName") == null ? "" : alarmExp.get("alarmContentName").toString());
        jobExcelDto.setAlarmValue(alarmExp.get("alarmValue") == null ? "" : alarmExp.get("alarmValue").toString());
        jobExcelDto.setCreateTime(alarmExp.get("createTime").toString());
        jobExcelDto.setJobStatusName(alarmExp.get("jobStatusName") == null ? "" : alarmExp.get("jobStatusName").toString());
        jobExcelDto.setHandleJobPerson(alarmExp.get("staff").toString());
        jobExcelDto.setGetJobTime(alarmExp.get("getJobTime") == null ? "" : alarmExp.get("getJobTime").toString());
        return jobExcelDto;
    }

    /**
     * 接收工单
     */
    @RequestMapping(value = "/getJob")
    @ResponseBody
    public Object getJob(Long id) {

        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();

        if (alarmJobService.getJob(id, currentUser.getId())) {
            return ResponseData.success();
        } else {
            return ResponseData.error("接单失败");
        }
    }

    /**
     * 确认工单,并保存图片
     */
    @RequestMapping(value = "/confirmJob")
    @ResponseBody
    public Object confirmJob(@RequestParam(value = "id", required = true) Long id,
                             @RequestParam(value = "firstState", required = true) String firstState,
                             @RequestParam(value = "firstStatePhotos", required = true) String firstStatePhotos,
                             @RequestParam(value = "needHandle", required = true) String needHandle) {
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        if (alarmJobService.confirmJob(id, currentUser.getId(), firstState, firstStatePhotos, needHandle)) {
            return ResponseData.success();
        } else {
            return ResponseData.error("确认失败");
        }
    }

    /**
     * 转单
     */
    @RequestMapping(value = "/transferJob")
    @ResponseBody
    public Object transferJob(@RequestParam(value = "id", required = true) Long id,
                              @RequestParam(value = "transferPerson", required = true) String transferPerson) {
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
//        String dbTime = iSysDictService.getDBtime();
        Date dbTime = new Date();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("from", currentUser.getName());
        jsonObject.put("to", EhcacheConstant.retBean().getUsernameById(Long.valueOf(transferPerson)));
        jsonObject.put("time", dateFormat.format(dbTime));

        if (alarmJobService.transferJob(id, Long.valueOf(transferPerson), jsonObject.toString())) {
            return ResponseData.success();
        } else {
            return ResponseData.error("转单失败");
        }
    }


    /**
     * 保存工单信息及图片
     */
    @RequestMapping(value = "/saveJob")
    @ResponseBody
    public Object saveJob(@RequestParam(value = "id", required = true) Long id,
                          @RequestParam(value = "handleMessage", required = true) String handleMessage,
                          @RequestParam(value = "handlePhotos", required = true) String handlePhotos) {

        if (alarmJobService.saveJob(id, handleMessage, handlePhotos)) {
            return ResponseData.success();
        } else {
            return ResponseData.error("保存失败");
        }
    }

    /**
     * 结束工单并消警
     */
    @RequestMapping(value = "/overJob")
    @ResponseBody
    public Object overJob(@RequestParam(value = "id", required = true) Long id,
                          @RequestParam(value = "handleMessage", required = true) String handleMessage,
                          @RequestParam(value = "handlePhotos", required = true) String handlePhotos) {

        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();

        if (alarmJobService.overJob(id, currentUser.getId(), handleMessage, handlePhotos)) {
            return ResponseData.success();
        } else {
            return ResponseData.error("保存失败");
        }
    }


    /**
     * 确认工单
     */
    @RequestMapping(value = "/handleJob")
    @ResponseBody
    public Object handleJob(@RequestParam(value = "id", required = true) Long id) {
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        if (alarmJobService.handleJob(id, currentUser.getId())) {
            return ResponseData.success();
        } else {
            return ResponseData.error("保存失败");
        }
    }

    /**
     * 工单详情
     */
    @RequestMapping(value = "/info")
    @ResponseBody
    public Object jobInfo(@RequestParam(value = "id", required = true) Long id) {
        DataScope dataScope = iCommonPermissionService.getAuthService().getLoginUserDataScope();
        AuthUser currentUser = iCommonPermissionService.getAuthService().getLoginUser();
        List<Map<String, Object>> retList = alarmJobService.jobInfo(id, dataScope, currentUser.getId());
        retList.forEach(this::alarmJobWrapper);
        return ResponseData.success(retList);
    }


    /***
     * 更新sink生成工单的接单时间，及建立超期未接工单的处理任务
     * @param id
     * @return
     */
    @RequestMapping(value = "/updateSinkJob")
    @ResponseBody
    public Map<String, Object> updateSinkJob(@RequestParam(value = "id", required = true) String id,
                                             @RequestParam(value = "msg", required = true) String msg,
                                             @RequestParam(value = "wellCode", required = true) String wellCode) {
        Map<String, Object> retMap = new HashMap<>();
        try {
            alarmJobService.updateSinkJob(id, URLDecoder.decode(msg, "UTF-8"), wellCode);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retMap;
    }


}
