package com.casic.missiles.modular.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.application.context.AbstractPermissionContext;
import com.casic.missiles.core.application.service.AbstractDictService;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.dao.AlarmNowViewMapper;
import com.casic.missiles.modular.system.dao.StatisticMapper;
import com.casic.missiles.modular.system.model.Dept;
import com.casic.missiles.modular.system.service.IStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@DS("log")
public class StatisticServiceImpl implements IStatisticsService {
    @Resource
    private StatisticMapper statisticMapper;
    @Resource
    private AlarmNowViewMapper alarmNowViewMapper;
    @Resource
    private AbstractPermissionContext permissionService;
    @Resource
    private AbstractDictService dictService;

    @Override
    public List<Map<String, Object>> wellStaticsByDept(DataScope dataScope) {
        List<Map<String, Object>> mapList = statisticMapper.wellStaticsByDept(dataScope);
        for (Map<String, Object> map : mapList) {
            map.put("pidName", permissionService.getDeptService().getDeptName(Long.valueOf(map.get("pid").toString())));
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> wellStaticsByType(DataScope dataScope) {
        String deptIds = StringUtils.strip(dataScope.getDeptIds().toString(), "[]");
        List<Map<String, Object>> mapList = statisticMapper.wellStaticsByType(deptIds);
        for (Map<String, Object> map : mapList) {
            map.put("wellTypeName", dictService.getDictNameByCode("sluicewellType", map.get("wellType").toString()));
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> deviceStaticsByType(DataScope dataScope) {
        Long deptId = permissionService.getAuthService().getLoginUser().getDeptId();
        String deviceTypes = getDeviceType(deptId);
        Map<String, String> deviceTypeMap = deviceTypeToMap(deviceTypes);
        List<Map<String, Object>> mapList = statisticMapper.deviceStaticsByType();
        List<Map<String, Object>> dataScopeFilter = mapList.stream().filter(
                map -> deviceTypeMap.containsKey(map.get("id").toString())
        ).collect(Collectors.toList());
        return dataScopeFilter;
    }

    @Override
    public List<Map<String, Object>> deviceStaticsByDept(DataScope dataScope, String deviceType) {
        List<Map<String, Object>> mapList = statisticMapper.deviceStaticsByDept(dataScope, StrUtil.isEmpty(deviceType)?-1:Long.valueOf(deviceType));
        for (Map<String, Object> map : mapList) {
            map.put("deptName", permissionService.getDeptService().getDeptName(Long.valueOf(map.get("deptid").toString())));
        }
        return mapList;
    }

    @Override

    public List<Map<String, Object>> deviceStaticsByRoad(DataScope dataScope){
          return   statisticMapper.deviceStaticsByRoad(dataScope);
    }


    @Override
    public Map<String, Object> deviceStaticsByStatus(DataScope dataScope) {
        String deptIds = StringUtils.strip(dataScope.getDeptIds().toString(), "[]");
        Map<String, Object> mapList = statisticMapper.deviceStaticsByStatus(deptIds);
        return mapList;
    }

    @Override
    public List<Map<String, Object>> deviceStaticsByStatusAndType(DataScope dataScope) {
        String deptIds = StringUtils.strip(dataScope.getDeptIds().toString(), "[]");
        List<Map<String, Object>> mapList = statisticMapper.deviceStaticsByStatusAndType(deptIds);
        return mapList;
    }

    @Override
    public List<Map<String, Object>> jobsByDept(DataScope dataScope, String beginTime, String endTime, String deviceType) throws ParseException {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<Long> deptIds = dataScope.getDeptIds();
        for (Long deptId : deptIds) {
            // 顶级不统计
            if (deptId == 0) {
                continue;
            }
            Dept dept = permissionService.getDeptService().getById(deptId);
            // 小组不统计
            if (ObjectUtil.isEmpty(dept) || "04".equals(dept.getDeptType())) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            List<Long> subDeptIds = permissionService.getDeptService().getIdsRecursionByPid(deptId, null);
            subDeptIds.add(deptId);
            String subDeptIdstr = StringUtils.strip(subDeptIds.toString(), "[]");
            map.put("deptId", deptId);
            map.put("deptName", permissionService.getDeptService().getDeptName(deptId));
            Map<String, Object> countMap = statisticMapper.jobsByDeptId(subDeptIdstr, beginTime, endTime);
            if (ObjectUtil.isNotEmpty(countMap)) {
                map.putAll(countMap);
            } else {
                map.put("beforeGet", 0);
                map.put("beforeConfirm", 0);
                map.put("inHandle", 0);
                map.put("over", 0);
                map.put("cancel", 0);
            }
            mapList.add(map);
        }
        return mapList;
    }

    @Override
   public Integer countNowAlarmRecords(DataScope dataScope,String alarmType){
        return  statisticMapper.countNowAlarmRecords( dataScope, alarmType);
   }

    @Override
    public List<Map<String, Object>> alarmsByDay(String beginTime, String endTime, DataScope dataScope) {
        String deptIds = StringUtils.strip(dataScope.getDeptIds().toString(), "[]");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
        List<Map<String, Object>> mapList = new ArrayList<>();
        try {
            Date beginDate = sdf1.parse(beginTime);
            Date endDate = sdf1.parse(endTime);
            Calendar date = Calendar.getInstance();
            date.setTime(beginDate);
            while (date.getTime().compareTo(endDate) <= 0) {
                String tmp = sdf1.format(date.getTime());
                Map<String, Object> map = alarmNowViewMapper.countAlarmsByDay(tmp, deptIds);
                map.put("date", sdf2.format(date.getTime()));
                mapList.add(map);
                date.add(Calendar.DAY_OF_MONTH, 1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mapList;
    }

    public ResponseData alarmWellListPage(DataScope dataScope, Page<Map<String, Object>> page, String beginTime, String endTime, String alarmContent) {
        ResponseData responseData = new ResponseData();
        Long deptId = permissionService.getAuthService().getLoginUser().getDeptId();
        String detypeTypes = getDeviceType(deptId);
        Map<String, String> deviceTypeMap = deviceTypeToMap(detypeTypes);
        try {
            List<Map<String, Object>> alarmWellList = statisticMapper.alarmWellListPage(dataScope, page, beginTime, endTime, alarmContent);
            List<Map<String, Object>> dataScopeFilter = alarmWellList.stream().filter(
                    map -> deviceTypeMap.containsKey(map.get("deviceType").toString())
            ).collect(Collectors.toList());
            page.setRecords(dataScopeFilter);
            responseData.setCode(200);
            responseData.setMessage("查询成功");
            responseData.setData(alarmWellList);
        } catch (DataAccessException ex) {
            log.error("主题：报警井查询出现异常，异常信息{}", ex);
            responseData.setCode(500);
            responseData.setMessage("查询异常");
        }
        return responseData;
    }

    public Object getAlarmCountByType(String beginTime, String endTime, String alarmType) {
        Long deptId = permissionService.getAuthService().getLoginUser().getDeptId();
        String detypeTypes = getDeviceType(deptId);
        ResponseData responseData = new ResponseData();
        Map<String, String> deviceTypeMap = deviceTypeToMap(detypeTypes);
        try {
            List<Map<String, Object>> alarmWellList = statisticMapper.getAlarmCountByType(beginTime, endTime, alarmType);
            List<Map<String, Object>> dataScopeFilter = alarmWellList.stream().filter(
                    map -> deviceTypeMap.containsKey(map.get("deviceType").toString())
            ).collect(Collectors.toList());
            responseData.setCode(200);
            responseData.setMessage("查询成功");
            responseData.setData(dataScopeFilter);
        } catch (DataAccessException ex) {
            log.error("主题：报警井查询出现异常，异常信息{}", ex);
            responseData.setCode(500);
            responseData.setMessage("查询异常");
        }
        return responseData;
    }


    public Object getAlarmByStatus(String beginTime, String endTime, String alarmType) {
        ResponseData responseData = new ResponseData();
        Long deptId = permissionService.getAuthService().getLoginUser().getDeptId();
        String detypeTypes = getDeviceType(deptId);
        Map<String, String> deviceTypeMap = deviceTypeToMap(detypeTypes);
        try {
            List<Map<String, Object>> alarmWellList = statisticMapper.getAlarmByStatus(beginTime, endTime, alarmType);
            List<Map<String, Object>> dataScopeFilter = alarmWellList.stream().filter(
                    map -> deviceTypeMap.containsKey(map.get("deviceType").toString())
            ).collect(Collectors.toList());
            responseData.setCode(200);
            responseData.setMessage("查询成功");
            responseData.setData(dataScopeFilter);
        } catch (DataAccessException ex) {
            log.error("主题：报警井查询出现异常，异常信息{}", ex);
            responseData.setCode(500);
            responseData.setMessage("查询异常");
        }
        return responseData;
    }

    private String getDeviceType(Long deptId) {
        List<Map<String, String>> deptTypeList = statisticMapper.getDeviceType();
        List<Map<String, String>> deptList = statisticMapper.getDeptList();
        Map<String, String> deptTypeMap = deptTypeList.stream().collect(
                Collectors.toMap(e -> String.valueOf(e.get("deptid")), e -> String.valueOf(e.get("deviceType")))
        );
        Map<Long, Long> deptMap = deptList.stream().collect(
                Collectors.toMap(e -> Long.valueOf(String.valueOf(e.get("id"))),
                                 e -> Long.valueOf(String.valueOf(e.get("pid"))))
        );
        String deviceTypes = deptTypeMap.get(String.valueOf(deptId));
        while (deptId != -1 && deviceTypes == null) {
            deptId = deptMap.get(deptId);
            deviceTypes = deptTypeMap.get(String.valueOf(deptId));
        }
        return deviceTypes;
    }

    private Map<String, String> deviceTypeToMap(String deviceTypes) {
        if(StrUtil.isEmpty(deviceTypes)){
            return null;
        }
        List<String> deviceTypeList = JSON.parseObject(deviceTypes, List.class);
        return deviceTypeList.stream().collect(
                Collectors.toMap(e -> e, e -> e)
        );
    }

}
