package com.yeejoin.precontrol.common.ws;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.access.Content;
import com.yeejoin.precontrol.common.entity.access.WebSocketAccess;
import com.yeejoin.precontrol.common.entity.access.WebSocketAccessParam;
import com.yeejoin.precontrol.common.entity.access.WebSocketAccessParamPerson;
import com.yeejoin.precontrol.common.service.IProjectDeviceService;
import com.yeejoin.precontrol.common.utils.StringUtil;

import lombok.Data;
import lombok.NoArgsConstructor;

@ServerEndpoint("/ws/{username}")
@Data
@NoArgsConstructor
@Component
public class WebSocket {

	private static int onlineCount = 0;

	private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();

	private Session session;

	private String username;

	private static String fileserver_domain;

	@Value("${fileserver.domain}")
	public void setFileserverDomain(String fileserver_domain) {
		WebSocket.fileserver_domain = fileserver_domain;
	}

	@OnOpen
	public void onOpen(@PathParam(value = "username") String username, Session session) throws IOException {

		this.username = username;

		this.session = session;

		addOnlineCount();

		clients.put(username, this);

		System.out.println("门禁设备：" + username + "已连接");

		setConfig();
	}

	private void getConfig() {
		WebSocketAccess wsa = new WebSocketAccess();
		wsa.setId(12);
		wsa.setMethod("configCentre.getConfig");
		WebSocketAccessParam wsap = new WebSocketAccessParam();
		wsap.setName("DoorTrustStrategy");
		wsa.setParams(wsap);
		String str = JSONObject.toJSONString(wsa);
		WebSocket.sendMessageAll(str);
	}

	private void setConfig() {
		WebSocketAccess wsa = new WebSocketAccess();
		wsa.setId(12);
		wsa.setMethod("configCentre.setConfig");
		WebSocketAccessParam wsap = new WebSocketAccessParam();
		wsap.setName("DoorTrustStrategy");
		Content content = new Content();
		content.setTrustMode(2);
		wsap.setContent(content);
		wsa.setParams(wsap);
		String str = JSONObject.toJSONString(wsa);
		WebSocket.sendMessageAll(str);
	}

	@OnClose
	public void onClose() throws IOException {

		clients.remove(username);

		subOnlineCount();

	}

	@OnMessage
	public void onMessage(String message) throws IOException {

		JSONObject jsonTo = JSONObject.parseObject(message);

		System.out.println(jsonTo);

	}

	@OnError
	public void onError(Session session, Throwable error) {

		error.printStackTrace();

	}

	public void sendMessageTo(String message, String To) throws IOException {

		// session.getBasicRemote().sendText(message);

		// session.getAsyncRemote().sendText(message);

		for (WebSocket item : clients.values()) {

			if (item.username.equals(To))

				item.session.getAsyncRemote().sendText(message);

		}

	}

	public static synchronized void sendMessageAll(String message) {

		sendMessageAll(message, null);

	}

	public static synchronized void sendMessageAll(String message, List<String> userNames) {
		if (StringUtil.isNotEmpty(userNames)) {
			for (WebSocket item : clients.values()) {
				if (userNames.contains(item.username)) {
					item.session.getAsyncRemote().sendText(message);
				}
			}
		} else {
			for (WebSocket item : clients.values()) {
				item.session.getAsyncRemote().sendText(message);
			}

		}
	}

	public static synchronized int getOnlineCount() {

		return onlineCount;

	}

	public static synchronized void addOnlineCount() {

		WebSocket.onlineCount++;

	}

	public static synchronized void subOnlineCount() {

		WebSocket.onlineCount--;

	}

	public static synchronized Map<String, WebSocket> getClients() {

		return clients;

	}

	public static void addPerson(Person person, List<String> sessons) {
		WebSocketAccess wsa = new WebSocketAccess();
		wsa.setId(12);
		wsa.setMethod("personnelData.savePersons");
		WebSocketAccessParam wsap = new WebSocketAccessParam();
		WebSocketAccessParamPerson wsapp = new WebSocketAccessParamPerson();
		wsapp.setBirthDay(person.getBirthday() != null ? person.getBirthday().toString() : null);
		wsapp.setType(1);
		wsapp.setCode(person.getUserId().toString());
		wsapp.setName(person.getName());
		wsapp.setCredentialNo(person.getIdNumber());
		wsapp.setSex(person.getSex() != null && person.getSex() == 1 ? "female" : "male");
		List<String> url = new ArrayList<String>();
		url.add(fileserver_domain + person.getHeadPhoto());
		wsapp.setURL(url);
		wsap.setPerson(wsapp);
		List<WebSocketAccessParam> params = new ArrayList<WebSocketAccessParam>();
		params.add(wsap);
		wsa.setParams(params);
		String str = JSONObject.toJSONString(wsa);
		WebSocket.sendMessageAll(str, sessons);
	}

	public static void delPerson(List<Object> userIds) {
		WebSocketAccess wsa = new WebSocketAccess();
		wsa.setId(12);
		wsa.setMethod("personnelData.removePersons");
		List<WebSocketAccessParam> params = new ArrayList<WebSocketAccessParam>();
		userIds.forEach(i -> {
			WebSocketAccessParam wsap = new WebSocketAccessParam();
			wsap.setCode(i.toString());
			params.add(wsap);
		});
		wsa.setParams(params);
		String str = JSONObject.toJSONString(wsa);
		WebSocket.sendMessageAll(str);
	}

}