package com.yeejoin.amos.maintenance.business.controller;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.maintenance.business.constants.XJConstant;
import com.yeejoin.amos.maintenance.business.dao.repository.IMsgSubscribeDao;
import com.yeejoin.amos.maintenance.business.param.MsgInfoPageParam;
import com.yeejoin.amos.maintenance.business.param.NoticePublishParam;
import com.yeejoin.amos.maintenance.business.param.UserMsgInitParam;
import com.yeejoin.amos.maintenance.business.service.intfc.IAppService;
import com.yeejoin.amos.maintenance.business.service.intfc.IMessageService;
import com.yeejoin.amos.maintenance.business.service.intfc.IMsgSubscribeService;
import com.yeejoin.amos.maintenance.business.service.intfc.IRouteService;
import com.yeejoin.amos.maintenance.business.util.ClazzFieldUtil;
import com.yeejoin.amos.maintenance.business.util.CommonResponse;
import com.yeejoin.amos.maintenance.business.util.CommonResponseUtil;
import com.yeejoin.amos.maintenance.business.util.DaoCriteria;
import com.yeejoin.amos.maintenance.business.util.MsgParamUtils;
import com.yeejoin.amos.maintenance.business.vo.MsgVo;
import com.yeejoin.amos.maintenance.common.enums.CheckEmailEnum;
import com.yeejoin.amos.maintenance.common.enums.CheckTypeEnum;
import com.yeejoin.amos.maintenance.common.enums.MsgTypeEnum;
import com.yeejoin.amos.maintenance.core.common.request.CommonPageable;
import com.yeejoin.amos.maintenance.core.common.request.CommonRequest;
import com.yeejoin.amos.maintenance.core.framework.Permission;
import com.yeejoin.amos.maintenance.dao.entity.Msg;
import com.yeejoin.amos.maintenance.dao.entity.MsgSubscribe;
import com.yeejoin.amos.maintenance.quartz.IJobService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;



/**
 * 消息订阅接口   --- 手机
 * @author gaodongdong
 *
 */
@RestController
@RequestMapping("/api/msgSubscribe")
@Api(value = "手机--消息订阅",tags = "消息模块api")
public class MsgController extends AbstractBaseController {

	private final Logger log = LoggerFactory.getLogger(MsgController.class);
	
	@Autowired
	private IRouteService routeService;
	@Autowired
	private IMsgSubscribeService msgSubscribeService;
	
	@Autowired
	private IMessageService iMsgService;
	
	@Autowired 
	private IJobService jobService;
	@Autowired
    private IAppService iAppService;
	
	@Autowired
	private IMsgSubscribeDao msgSubscribeDao;
	/*@Autowired
	private IUserService iUserService;
	*/
	
	/**
	 * 获取用户当前所选择公司的消息订阅信息
	 * @return
	 */
	@Permission
	@ApiOperation(value="获取用户当前所选择公司的消息订阅信息", notes="获取用户当前所选择公司的消息订阅信息")
	@GetMapping(value="/querySubscribe", produces = "application/json;charset=UTF-8")
	public CommonResponse queryMsgSetting() {
		try {
			AgencyUserModel userModel = getUserInfo();
        String userId = userModel.getUserId();
        ReginParams reginParams = getSelectedOrgInfo();
        String loginOrgCode = getLoginOrgCode(reginParams);
		String deptId=null;
		if( reginParams.getDepartment()!=null){
			deptId = reginParams.getDepartment().getDepartmentDesc();
		}

		/*if(XJConstant.ROLE_NAME_SUPERADMIN.equals(roleTypeName) || XJConstant.ROLE_NAME_ADMIN.equals(roleTypeName)){
			orgCode = param.getUserOrgCode();
		}else if(XJConstant.ROLE_NAME_DEPTADMIN.equals(roleTypeName)){
			deptId = param.getDepartmentId();
			userId = param.getUserId();
		}else if(XJConstant.ROLE_NAME_PERSON.equals(roleTypeName)){
			userId = param.getUserId();
		}*/
		List<HashMap<String, Object>> routeList = routeService.queryRouteListByOrgCode(loginOrgCode,userId,deptId);
		
		List<Map<String, Object>> checkType = CheckTypeEnum.getEnumList();
		List<Map<String, Object>> emailType = CheckEmailEnum.getEnumList();
		UserMsgInitParam userInitParam = new UserMsgInitParam();
		userInitParam.setOrgCode(loginOrgCode);
		userInitParam.setUserId( userModel.getUserId());
		List<MsgSubscribe> msgSubs = iAppService.saveUserMsgInit(userInitParam); // 获取搜友消息推送类型
		if(ObjectUtils.isEmpty(msgSubs)){
			
		}
		emailType = setupSelectItem(emailType, msgSubs); //标记已经选择的邮件消息推送类型
		checkType = setupSelectItem(checkType, msgSubs); // 标记已经选择的检查类型消息
		
		/**
		 * 获取所有已经选择的路线id数组
		 */
		String sRoutes = "";
		for (MsgSubscribe msg : msgSubs) {
			if ("route".equals(msg.getMsgType())) {
				sRoutes = msg.getAttribute1();
			}
		}
		List<Map<String, Object>> respRoute = new ArrayList<>();
		if (!ObjectUtils.isEmpty(sRoutes)) {
			String[] aRoutes = sRoutes.split(",");
			for (HashMap<String, Object> route : routeList) {
				for (String s : aRoutes) {
					if (!ObjectUtils.isEmpty(s) && s.equals(route.get("id"))) {
						route.put("selected", true);
						respRoute.add(route);
						break;	
					} else {
						respRoute.add(route);
					}
				}
			} //将已经选择的路线标记位已选择
			
		}
		
		Map<String, Object> response = new HashMap<>();
		response.put("route", respRoute);
		response.put("email", emailType);

        response.put("check", checkType);
        
        List< Map<String, Object>> listf =new ArrayList<>();
        if(msgSubs!=null&&msgSubs.size()>0){
			for (MsgSubscribe msg : msgSubs) {
				listf.add(objectToMap1(msg)); 
			}
		}
        
        
		response.put("checkPlan", listf);
		return CommonResponseUtil.success(response);
	   } catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return CommonResponseUtil.failure();
		}
		
	}
	
	/**
	 * 保存用户消息订阅信息
	 * @param subscribe
	 * @return
	 */
	@Permission
	@ApiOperation(value="保存用户消息订阅信息", notes="保存用户消息订阅信息")
	@PostMapping(value="/saveSubscribe",produces = "application/json;charset=UTF-8")
	public CommonResponse saveSubscribe(@ApiParam(value = "消息订阅信息", required = false) @RequestBody(required = true) List<MsgSubscribe> subscribe) {
		try {
			AgencyUserModel userModel = getUserInfo();
	        String userId = userModel.getUserId();
	        ReginParams reginParams = getSelectedOrgInfo();
	        String orgCode = getLoginOrgCode(reginParams);
			for (MsgSubscribe s: subscribe) {
				s.setOrgCode(orgCode);
				s.setUserId(userModel.getUserId());
			}
			
			//查询当前用户是否已保存
			
			List<MsgSubscribe>  lits=msgSubscribeService.queryMsgSubscribes(userId);
//			if(lits!=null&&lits.size()>0){
//			//删除
//				List<Long> userIds=new ArrayList<>();
//				userIds.add(Long.valueOf(userId));
//				msgSubscribeDao.delMsgSubscribeByUserId(userIds);
//			}
//
			
			msgSubscribeService.saveSubscribe(subscribe);
		} catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
		
		return CommonResponseUtil.success();
	}
	
	private List<Map<String, Object>> setupSelectItem(List<Map<String, Object>> type, List<MsgSubscribe> msgSubs) {
		for (Map map : type) {
			for (MsgSubscribe msg : msgSubs) {
				if (!msg.getMsgType().equals(map.get("ower"))) continue;
				if (map.get("code").equals(msg.getAttribute1())) {
					map.put("selected", true);
					break;
				}
			}
		}
		return type;
	}
	
    private Map<String, Object> objectToMap(Object obj) throws Exception {    
        if(obj == null)  
            return null;      
        
        Map<String, Object> map = new HashMap<String, Object>();   
  
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());    
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();    
        for (PropertyDescriptor property : propertyDescriptors) {    
            String key = property.getName();    
            if (key.compareToIgnoreCase("class") == 0) {   
                continue;  
            }  
            Method getter = property.getReadMethod();  
            Object value = getter!=null ? getter.invoke(obj) : null;  
            map.put(key, value);  
        }    
  
        return map;  
    } 
    
    /**
     * 根据登陆用户APP获取未读消息个数
     * @return
     */
    @Permission
    @ApiOperation(value="APP根据登陆用户获取未读消息个数", notes="APP根据登陆用户获取未读消息个数")
	@GetMapping(value="/unreadCount",produces = "application/json;charset=UTF-8")
	public CommonResponse getUnreadCount() {
		try {
			AgencyUserModel user = getUserInfo();
			int count = msgSubscribeService.getUnreadCount(user);
			return CommonResponseUtil.success(count);
		} catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
		
	}
    
    /**
     * 获取消息类型
     * @return
     */
    @Permission
    @ApiOperation(value="APP获取消息类型", notes="APP获取消息类型")
	@GetMapping(value="/MsgType",produces = "application/json;charset=UTF-8")
	public CommonResponse getMsgType() {
		try {
			return CommonResponseUtil.success(MsgTypeEnum.getEnumList());
		} catch (Exception e) {
			return CommonResponseUtil.failure("获取消息类型失败");
		}
		
	}
    
    /**
     * 根据条件获取消息列表
     * @param queryRequests
     * @param commonPageable
     * @return
     */
    @Permission
	@ApiOperation(value = "APP 根据条件获取消息列表", notes = "APP 根据条件获取消息列表")
	@PostMapping(value = "/msgList", produces = "application/json;charset=UTF-8")
	public CommonResponse queryMsgList(
			@ApiParam(value = "查询条件", required = false) @RequestBody(required = false) List<CommonRequest> queryRequests,
			@ApiParam(value = "分页参数", required = true, defaultValue = "pageNumber=0&pageSize=10") CommonPageable commonPageable) {
		try {
			
			AgencyUserModel user = getUserInfo();
            ReginParams reginParams = getSelectedOrgInfo();
            String loginOrgCode = getLoginOrgCode(reginParams);
            String roleTypeName = getRoleTypeName(reginParams);
			CommonRequest request = new CommonRequest();
			CommonRequest request1 = new CommonRequest();
			request.setName("userId");
			request.setValue(user.getUserId());
			request1.setName("status");
			request1.setValue(XJConstant.IS_SENT);
			queryRequests.add(request1);
			queryRequests.add(request);
			 List< Map<String, Object>> listf =new ArrayList<>();
            List<DaoCriteria> criterias = buildDaoCriterias(queryRequests, false, loginOrgCode, roleTypeName);
			Page<Msg> msgList = msgSubscribeService.queryMsgList(criterias, commonPageable);
			List<Msg> li= msgList.getContent();
			if(li!=null&&li.size()>0){
				for (Msg msg : li) {
					listf.add(objectToMap1(msg)); 
				}
			}
			 Page< Map<String, Object>>  pd=new PageImpl<>(listf, msgList.getPageable(), msgList.getTotalElements());
			return CommonResponseUtil.success(pd);
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return CommonResponseUtil.failure("件获取消息列表失败");
		}
	}
	
	public static Map<String, Object> objectToMap1(Object obj) throws IllegalAccessException {
   	 Map<String, Object> map = new HashMap<String,Object>();
   	  if(obj!=null){
       for (Field field : ClazzFieldUtil.getAllFields(obj)) {
           field.setAccessible(true);
           String fieldName = field.getName();
           Object value = nvl(field.get(obj));
           if("userId".equals(fieldName)){
        	   map.put(fieldName, Long.valueOf(value.toString()));
           }else{
        	   map.put(fieldName, value);
           }
          
       }
       return map;
   }
   return map;
   }

   
   public static Object nvl(Object param) {  
       return param != null ? param : null;  
   } 
	
	
	
	
	/**
	 * 根据条件查询消息列表
	 * @param queryRequests
	 * @param commonPageable
	 * @return
	 */
   @Permission
	@ApiOperation(value = "根据条件获取消息列表", notes = "APP 根据条件获取消息列表")
	@PostMapping(value = "/list", produces = "application/json;charset=UTF-8")
	public CommonResponse querylist(
			@ApiParam(value = "查询条件", required = false) @RequestBody(required = false) List<CommonRequest> queryRequests,
			@ApiParam(value = "分页参数", required = true, defaultValue = "pageNumber=0&pageSize=10") CommonPageable commonPageable) {
		try {
			  ReginParams reginParams = getSelectedOrgInfo();
	            String loginOrgCode = getLoginOrgCode(reginParams);
	            String roleTypeName = getRoleTypeName(reginParams);
	            HashMap<String, Object> paramMap = buildMybatisCriterias(loginOrgCode, roleTypeName);
	         if(XJConstant.ROLE_NAME_DEPTADMIN.equals(roleTypeName)||XJConstant.ROLE_NAME_PERSON.equals(roleTypeName))
	            paramMap.put("userId",getUserId());
			MsgInfoPageParam param = MsgParamUtils.fillMsgInfoParam(queryRequests, commonPageable, paramMap);
			Page<MsgVo> dataList = iMsgService.queryMsgInfoList(param);
			return CommonResponseUtil.success(dataList);
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return CommonResponseUtil.failure("件获取消息列表失败");
		}
	}
	
	/**
	 * 修改消失为已读
	 * @param msgId
	 * @return
	 */
   @Permission
	@ApiOperation(value = "修改消失为已读", notes = "修改消失为已读")
	@PostMapping(value = "/isRead", produces = "application/json;charset=UTF-8")
	public CommonResponse isRead(
			@ApiParam(value = "消息id", required = true) @RequestBody  Long msgId) {		
		try {
			Msg msg = msgSubscribeService.isRead(msgId);
			return CommonResponseUtil.success(msg);
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return CommonResponseUtil.failure("修改消失为已读失败");
		}
	}
	
	/**
	 * 通知发布
	 * 
	 * @return
	 */
   @Permission
	@ApiOperation(value = "通知发布", notes = "通知发布")
	@PostMapping(value = "/noticePublish", produces = "application/json;charset=UTF-8")
	public CommonResponse noticePublish(@ApiParam(value = "通知信息", required = true) @RequestBody NoticePublishParam msg) {
		try {
			AgencyUserModel user = getUserInfo();
            msg.setCreateBy(user.getUserId());
            ReginParams reginParams = getSelectedOrgInfo();
            msg.setUserName(user.getRealName());
            String loginOrgCode = getLoginOrgCode(reginParams);
            msg.setOrgCode(loginOrgCode);
            List<Msg> msgList = iMsgService.publishNotice(getToken(),getProduct(),getAppKey(),msg);
			msgList.forEach(m->{
				jobService.msgAddJob(m);
			});
			
			return CommonResponseUtil.success();
		} catch (Exception e) {
			return CommonResponseUtil.failure("通知发布失败！");
		}
	}
}
