package cn.com.capcloud.api.action.myself.system;

import cn.com.capcloud.api.action.service.ApiDao;
import cn.com.capcloud.api.action.service.ApiService;
import cn.com.capcloud.api.action.service.util.ReflectionUtil;
import cn.com.capcloud.api.action.service.util.TextUtil;
import cn.com.capcloud.ccui.core.common.json.JackJSON;
import cn.com.capcloud.ccui.core.common.json.JackJSONArray;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import cn.com.capcloud.core.cache.KHCRedisCache;
import cn.com.capcloud.core.cache.BaseConfigStaticCache;
import cn.com.capcloud.core.noentitydb.BaseService;
import cn.com.capcloud.core.noentitydb.DefaultAction;
import cn.com.capcloud.core.system.user.User;
import cn.com.capcloud.core.system.user.UserService;
import cn.com.capcloud.core.util.TblLogNames;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class MenuAction extends DefaultAction {
    //系统配置(KEY)
    private static final String SYSTEM_SETTINGS_DS_SYSTEM_CONFIG_JSON="system.settings.ds.system.config.json";
    @Autowired
    private BaseService baseService;
    @Autowired
    private UserService userService;
    @Autowired
    private ApiService apiService;
    @Autowired
    private KHCRedisCache khcRedisCache;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Value("${rzth.ccui.version:}")
    private String ccuiVersion;
    private static MenuAction action;
    @PostConstruct
    public void init(){
        action=this;
        action.baseService=this.baseService;
        action.userService=this.userService;
        action.apiService =this.apiService;
        action.khcRedisCache =this.khcRedisCache;
        action.mongoTemplate=this.mongoTemplate;
        action.ccuiVersion=this.ccuiVersion;
    }

    @Override
    public JackJSONArray saveAfter(String jsonStr, JackJSONObject retJson, HttpServletRequest request, JackJSONArray array) {
        action.khcRedisCache.deleteAllMenu();//更新缓存
        return super.saveAfter(jsonStr, retJson, request, array);
    }

    @Override
    public String deleteBefore(String jsonStr, JackJSONObject retJson, HttpServletRequest request) {
        JackJSONArray pkIds=JackJSONObject.fromObject(jsonStr).getJackJSONArray("pkIds");
        for (int i = 0; i < pkIds.size(); i++) {
            String queryCountSql="SELECT count(1) FROM tbl_system_menurole WHERE menu_id="+pkIds.getJackJSONObject(i).get("pkId");
            Integer count=this.getJdbcTemplate().queryForObject(queryCountSql,Integer.class);
            if(count>0){
                retJson.putAll(JackJSONObject.fromObject(action.apiService.getReturnDataByCode("7011")));
                retJson.put("message",retJson.get("message")+" 原因是当前菜单分配了角色");
                return "-1";
            }
            queryCountSql="SELECT count(1) FROM tbl_system_menu WHERE STATUS=0 AND FIND_IN_SET(menu_parent_id,tree_menu('"+pkIds.getJackJSONObject(i).get("pkId")+"'))";
            count=this.getJdbcTemplate().queryForObject(queryCountSql,Integer.class);
            if(count>0){
                retJson.putAll(JackJSONObject.fromObject(action.apiService.getReturnDataByCode("7011")));
                retJson.put("message",retJson.get("message")+" 原因是当前菜单有子菜单");
                return "-1";
            }
        }
        return "0";
    }

    @Override
    public String deleteAfter(String jsonStr, JackJSONObject retJson, HttpServletRequest request) {
        action.khcRedisCache.deleteAllMenu();//更新缓存
        return super.deleteAfter(jsonStr, retJson, request);
    }

    public Map<String,Object> getMenu(String jsonStr, JackJSONObject retJson, HttpServletRequest request){
        Map<String,Object> retMap=new HashMap<>();
        User user=action.userService.getUser(request);
        Sort sort = Sort.by(
                Sort.Order.desc("create_time")
        );
        Query query;
        Criteria criteria=new Criteria();
        criteria.and("user_id").is(user.getId());
        query=new Query(criteria);
        query.limit(1);
        query.with(sort);
        Map<String,Object> systemConfigMap= JackJSON.parseObject(String.valueOf(BaseConfigStaticCache.get(SYSTEM_SETTINGS_DS_SYSTEM_CONFIG_JSON)), HashMap.class);
        String passwordValidDayNum=String.valueOf(systemConfigMap.get("password_valid_day_num"));//密码更新策略
        String passwordRemindDayNum=String.valueOf(systemConfigMap.get("password_remind_day_num"));//密码提醒策略
        if(!passwordValidDayNum.equals("null")&&!passwordValidDayNum.equals("0")&&passwordValidDayNum.length()>0){
            List<Map> listMap=action.mongoTemplate.find(query, Map.class, TblLogNames.TBL_LOG_USER_PASSWORD_UPDATE);
            if(listMap.size()>0){
                Map map=listMap.get(0);
                String createTime=String.valueOf(map.get("create_time"));
                try {
                    DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
                    Date star = dft.parse(createTime);//开始时间
                    Date endDay=new Date();//结束时间
                    Long starTime=star.getTime();
                    Long endTime=endDay.getTime();
                    Long num=endTime-starTime;//时间戳相差的毫秒数
                    Integer updateDayNum=Integer.valueOf(String.valueOf(num/24/60/60/1000));
                    if(Integer.valueOf(passwordValidDayNum)<updateDayNum){
                        retMap.put("passwordStatus","1");
                        retMap.put("passwordMessage","根据密码安全策略，您的密码已过期，请更新密码！");
                    }else if(!passwordRemindDayNum.equals("null")&&passwordRemindDayNum.length()>0){
                        Integer day=Integer.valueOf(passwordValidDayNum)-updateDayNum;
                        if(day<=Integer.valueOf(passwordRemindDayNum)){
                            retMap.put("passwordStatus","2");
                            retMap.put("passwordMessage","根据密码安全策略，您的密码还有"+day+"天将过期，过期后将影响部分功能无法正常使用，请及时更新密码！");
                        }else{
                            retMap.put("passwordStatus","0");
                            retMap.put("passwordMessage","");//密码在安全策略中，无需任何提示
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else{
                retMap.put("passwordStatus","1");
                retMap.put("passwordMessage","根据密码安全策略，您的密码已过期，请更新密码！");
            }
        }else{
            retMap.put("passwordStatus","0");
            retMap.put("passwordMessage","");//默认无密码安全策略
        }
        List<Map<String,Object>> menuList= JackJSON.parseObject(TextUtil.nullToStrFilter(action.khcRedisCache.getMenuByParentId(user.getId(),"21")), ArrayList.class);
        retMap.put("message","查询成功");
        retMap.put("menuList",menuList);
        retMap.put("userName",user.getUserName());
        retMap.put("userId",user.getId());
        retMap.put("orgId",user.getOrgId());
        retMap.put("orgName",this.getJdbcTemplate().queryForObject("select org_name from tbl_system_org where id='"+user.getOrgId()+"'",String.class));
        String menuRenderType=String.valueOf(systemConfigMap.get("menu_render_type"));//菜单渲染类型
        retMap.put("menuRenderType",menuRenderType);
        //判断当前用户是否有借调用户，或为借调用户，是则右上角可以切换。
        if(user.getParentId()!=null&&user.getParentId().length()>0){//当前用户是借调用户有上级id
            retMap.put("isUserSecondment","Y");
        }else{//当前用户为主用户，需要查询是否有借调用户
            String queryUserNumSql="SELECT COUNT(1) FROM tbl_system_user WHERE parent_id='"+user.getId()+"'";
            Integer userNum=this.getJdbcTemplate().queryForObject(queryUserNumSql,Integer.class);
            if(userNum>0){
                retMap.put("isUserSecondment","Y");
            }else{
                retMap.put("isUserSecondment","N");
            }
        }
        Boolean isRolePzgly=action.userService.isExistsRole("1", user.getId());
        if(isRolePzgly){
            retMap.put("isKhcAdmin","Y");
        }else{
            retMap.put("isKhcAdmin","N");
        }
        if(action.ccuiVersion.equals("")){
            retMap.put("version","2.0.0");
        }else{
            retMap.put("version",action.ccuiVersion);
        }
        return retMap;
    }
    //查询菜单提示数量
    public Map<String,Object> getMenuShowNum(String jsonStr, JackJSONObject retJson, HttpServletRequest request){
        JackJSONObject json= JackJSONObject.fromObject(jsonStr);
        Map<String,Object> retMap=new HashMap<>();
        Map<String,Object> map=new HashMap<>();
        String uuid= String.valueOf(json.get("uuid"));
        String sql="select * from tbl_system_menu where uuid='"+uuid+"'";
        List<Map<String, Object>> list= this.getJdbcTemplate().queryForList(sql);
        String showNumDataType=String.valueOf(list.get(0).get("show_num_data_type"));
        if(showNumDataType.equals("2")){
            String mSql=String.valueOf(list.get(0).get("m_sql"));
            mSql=mSql.replaceAll("&nbsp;"," ");
            mSql=mSql.replaceAll("&quot;","'");
            Integer count=this.getJdbcTemplate().queryForObject(mSql,Integer.class);
            list.get(0).put("data",count);
        }else{
            String className=String.valueOf(list.get(0).get("my_action_class"));
            String methodName=String.valueOf(list.get(0).get("method_name"));
            Map<String, Object> valueMap= ReflectionUtil.mySelfMethodRetMap(className,methodName,jsonStr,retJson,request);
            list.get(0).put("data",valueMap.get("data"));
        }
        retMap.put("message","查询成功");
        retMap.put("menuInfo",list.get(0));
        return retMap;
    }
    //测试接口，能访问说明token是合法有效的
    public Map<String,Object> test(String jsonStr, JackJSONObject retJson, HttpServletRequest request){
        Map<String,Object> map=new HashMap<>();
        map.put("message","成功访问");
        return map;
    }

    public Map<String,Object> getMenuByRoleId(String jsonStr, JackJSONObject retJson, HttpServletRequest request){
        JackJSONObject json= JackJSONObject.fromObject(jsonStr);
        String roleId= String.valueOf(json.get("role_id"));
        Map<String,Object> retMap=new HashMap<>();
        List<Map<String,Object>> menuList= JackJSON.parseObject(TextUtil.nullToStrFilter(ApiDao.getMenuByParentIdAndRoleId(Long.valueOf(roleId),"21",getJdbcTemplate())), ArrayList.class);
        retMap.put("message","查询成功");
        retMap.put("menuList",menuList);
        return retMap;
    }

    public Map<String,Object> getMenuByUserId(String jsonStr, JackJSONObject retJson, HttpServletRequest request){
        JackJSONObject json= JackJSONObject.fromObject(jsonStr);
        String userId= String.valueOf(json.get("user_id"));
        Map<String,Object> retMap=new HashMap<>();
        List<Map<String,Object>> menuList= JackJSON.parseObject(TextUtil.nullToStrFilter(ApiDao.getMenuByParentId(Long.valueOf(userId),"21",getJdbcTemplate())), ArrayList.class);
        retMap.put("message","查询成功");
        retMap.put("menuList",menuList);
        return retMap;
    }
}

