package com.pingpang.websocketchat.send;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pingpang.config.SpringContextUtil;
import com.pingpang.redis.service.RedisService;
import com.pingpang.service.UserGroupService;
import com.pingpang.service.UserMsgService;
import com.pingpang.service.UserService;
import com.pingpang.util.JsonFilterUtil;
import com.pingpang.util.StringUtil;
import com.pingpang.websocketchat.ChannelManager;
import com.pingpang.websocketchat.ChartUser;
import com.pingpang.websocketchat.ChatInit;
import com.pingpang.websocketchat.ChatType;
import com.pingpang.websocketchat.Message;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

public abstract class ChatSend implements Runnable {

	// 用户信息处理
	protected  UserService userService = (UserService)SpringContextUtil.getBean(ChatInit.class).userService;

	// 消息信息处理
	protected  UserMsgService userMsgService= (UserMsgService)SpringContextUtil.getBean(ChatInit.class).userMsgService;

	// redis操作
	protected  RedisService redisService= (RedisService)SpringContextUtil.getBean(ChatInit.class).redisService;

	//群聊信息的获取
	protected  UserGroupService userGroupService= (UserGroupService)SpringContextUtil.getBean(ChatInit.class).userGroupService;
	
	// 日志操作
	protected Logger logger = LoggerFactory.getLogger(ChatSend.class);

	//保存图片地址
    public static String PATH;
	
    //线程池调用
    //public InheritableThreadLocal<Map<String,Object>> threadLocal = new InheritableThreadLocal<Map<String,Object>>();
    
    private Message message;//当前处理的消息
    private ChannelHandlerContext ctx;
    
    public void setChatSend(Message message, ChannelHandlerContext ctx) {
    	this.message=message;
    	this.ctx=ctx;
    };
    
    
	// 获取JSON工具
	protected final ObjectMapper getMapper() {
		ObjectMapper mapper = new ObjectMapper();
		JsonFilterUtil.addFilterForMapper(mapper);
		return mapper;
	}

	/**
	 * admin发送的信息
	 * @param msg
	 * @param cmd
	 * @return
	 */
	public Message getAdmessag(String msg,String cmd) {
		Message message=new Message();
		message.setMsg(msg);
		ChartUser admin = new ChartUser();
		admin.setUserCode("admin");
		admin.setUserName("管理员");
		message.setFrom(admin);
		
		message.getFrom().setUserPassword("");
		message.setFrom(userService.getUser(message.getFrom()));
		
		message.setCmd(cmd);
		message.setCreateDate(StringUtil.format(new Date()));
		return message;
	}
	/**
	 * 数据校验
	 * @param msg
	 * @param ctx
	 * @return
	 * @throws Exception 
	 */
	public boolean isSend(Message message, ChannelHandlerContext ctx)throws Exception {
		
		
		if (null != message) {
			//logger.info("当前处理信息:"+message.toString());
			// 用户未登录不允许绑定操作
			if (ChatType.BIND.equals(message.getCmd())) {
				ChartUser cu = (ChartUser) userService.getUserMap(message.getFrom().getUserCode());
				if (null == cu) {
					logger.info("未登录用户不允许绑定:" + message.toString());
					return false;
				}
			} else {
				// 防止非当前用户进行操作
				/**
				 * 集群处理修改关闭
				if (!ctx.channel().equals(ChannelManager.getChannel(message.getFrom().getUserCode()))) {
					logger.info("非当前用户操作:" + message.toString());
					return false;
				}
                */
				// 当用户不是在线状态直接打回
				ChartUser fromUser = ChannelManager.getChartUser(message.getFrom().getUserCode());
				//判断广播消息 因为管理员没绑定信息
				if(!(null==fromUser && "admin".equals(message.getFrom().getUserCode()))) {
					String userStatus=fromUser.getUserStatus();
					if("-1".equals(userStatus)) {//用户已经注销了
						message=getAdmessag("系统消息此用户已被注销","-1");
						message.setAccept(fromUser);
						userMsgService.addMsg(message);
						ctx.writeAndFlush(new TextWebSocketFrame(this.getMapper().writeValueAsString(message)));
						return false;
					}else if("2".equals(userStatus)) {//用户禁言
						
						Set<String> checkList=new HashSet<String>();
						checkList.add(ChatType.SINGLE);
						checkList.add(ChatType.GROUP);
						checkList.add(ChatType.AUDIO_QUERY);
						checkList.add(ChatType.AUDIO_MAGIC);
						
						if (checkList.contains(message.getCmd())) {
							message=getAdmessag("系统消息此用户已被禁言","3");
							message.setAccept(fromUser);
							userMsgService.addMsg(message);
							ctx.writeAndFlush(new TextWebSocketFrame(this.getMapper().writeValueAsString(message)));
							return false;
						}
					}
				}
				
			}
			
			//this.redisService.SendMsg(message);
			
			/**
			if(!ChannelManager.isExitChannel(message.getAccept()) && (ChatType.SINGLE.equals(message.getCmd()) || ChatType.GROUP.equals(message.getCmd()))) {
				this.redisService.SendMsg(message);
			}else {
			}
			*/
			try {
				send(message,ctx);
			}catch(Exception e) {
				e.printStackTrace();
			    logger.error("信息发送异常!", e);
				
				Channel cl = ChannelManager.getChannel(message.getFrom().getUserCode());
                 
				message.setMsg("发送异常，信息已记录");
				ChartUser admin = new ChartUser();
				admin.setUserCode("admin");
				admin.setUserName("管理员");
				message.setFrom(admin);
				message.setCmd("2");
				message.setCreateDate(StringUtil.format(new Date()));
				cl.writeAndFlush(new TextWebSocketFrame(this.getMapper().writeValueAsString(message)));
			}
			
			return true;
		}
		
		logger.info("当前处理信息为空!!!");
		return false;
	}
	
	/**
	   *    广播消息
	   *  接收用户不存在   
	 * @param message
	 */
	public void sendOtherServerMsg(Message message) {
		if(!ChannelManager.isExitChannel(message.getAccept()) && (ChatType.SINGLE.equals(message.getCmd()) || ChatType.GROUP.equals(message.getCmd()))) {
			this.redisService.SendMsg(message);
		}
	}

	// 发送消息
	public abstract void send(Message message, ChannelHandlerContext ctx) throws Exception;

	@Override
	public void run() {
//		Message message=(Message) threadLocal.get().get("message");
//		ChannelHandlerContext ctx=(ChannelHandlerContext) threadLocal.get().get("ctx");
		try {
			this.isSend(message, ctx);
		} catch (Exception e) {
			logger.error("信息发送异常!", e);
		}
	}
	
	
}
