package com.hmsoft.app;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.alibaba.fastjson.JSON;
import com.hmsoft.bizpanel.HisPubTab;
import com.hmsoft.bizpanel.MtzjTab;
import com.hmsoft.common.AppConst;
import com.hmsoft.common.BatchConst;
import com.hmsoft.common.FileConst;
import com.hmsoft.common.MsgTypeConst;
import com.hmsoft.common.util.BatchDataUtil;
import com.hmsoft.common.util.CoursePlanDataUtil;
import com.hmsoft.common.util.DialogUtil;
import com.hmsoft.model.CoursePlan;
import com.hmsoft.model.SelectedCourse;
import com.hmsoft.model.request.BizRequest;
import com.hmsoft.model.request.LoginRequest;
import com.hmsoft.model.response.LoginResponse;
import com.hmsoft.remote.rmi.exception.RemotingException;
import com.hmsoft.remote.rmi.handler.ExchangeHandler;
import com.hmsoft.remote.rmi.model.Message;
import com.hmsoft.remote.rmi.rpc.ExchangeClient;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * 
 * @author zq
 *
 */
public class Login extends Application {
	
	public static ExchangeClient CLIENT = null;
	private static Properties PROPS = new Properties();
	//private static volatile Map<String, LoginRequest> LOGIN_MAP = new HashMap<String, LoginRequest>();
	//记录删除的记录,后续可能会用到.
	//private static Map<Integer, CoursePlan> DELETED_MAP = new HashMap<Integer, CoursePlan>();
	private TextField userTextField = null;
	private PasswordField passwdField = null;
	private Text scenetitle = null;
	
	
	@Override
	public void start(final Stage primaryStage) throws Exception {
		primaryStage.setTitle("登录");
		final GridPane grid = new GridPane();
		grid.setAlignment(Pos.CENTER);
		grid.setHgap(10);
		grid.setVgap(10);
		grid.setPadding(new Insets(25));
		//文本框
		scenetitle = new Text("Welcome");
		scenetitle.setId("welcome-text");
		grid.add(scenetitle, 0, 0, 2, 1);
		//标签
		Label userName = new Label("用户名:");
		grid.add(userName, 0, 1);
		//文本输入框
		userTextField = new TextField();
		grid.add(userTextField, 1, 1);
		
		Label passwd = new Label("密码:");
		grid.add(passwd, 0, 2);
		//密码输入框
		passwdField = new PasswordField();
		grid.add(passwdField, 1, 2);
		passwdField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				if (event.getCode() == KeyCode.ENTER) {
					doLoginFunc(primaryStage);
				}
			}
		});
		//按钮及按钮布局
		final HBox hbBtn = new HBox(10);
		grid.add(hbBtn, 1, 4);
		Text actiontarget = new Text();
		actiontarget.setId("actiontarget");
		grid.add(actiontarget, 1, 6);
		//添加按钮
		this.createBtn(hbBtn, primaryStage);
		//scene
		Scene scene = new Scene(grid, 350, 200);
		primaryStage.setScene(scene);
		primaryStage.setResizable(false);
		primaryStage.setAlwaysOnTop(true);
		primaryStage.show();
		//socket thread
		this.startConnectServer();
	}

	/**
	 * 创建按钮.
	 * @param hbBtn
	 * @param primaryStage
	 */
	private void createBtn(final HBox hbBtn, final Stage primaryStage) {
		Button btnLogin = new Button("登陆");
		Button btncancel = new Button("取消");
		hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
		hbBtn.getChildren().add(btnLogin);
		hbBtn.getChildren().add(btncancel);
		btnLogin.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				doLoginFunc(primaryStage);
			}
		});
		btncancel.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				primaryStage.close();
			}
		});
	}
	
	public static void main(String[] args) {
		launch(args);
	}
	
	private void startConnectServer() {
		try {
			PROPS.load(new FileInputStream(FileConst.CONF_SERVER_PATH));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		final String IP_PORT = PROPS.getProperty(FileConst.KEY_IP, "127.0.0.1") + ":" + PROPS.getProperty(FileConst.KEY_PORT, "20880");
		new Thread(new Runnable() {

			@Override
			public void run() {
				CLIENT = new ExchangeClient(IP_PORT, new ExchangeHandler(){

					@Override
					public void connected(com.hmsoft.remote.rmi.transport.NettyChannel channel)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void disconnected(com.hmsoft.remote.rmi.transport.NettyChannel channel)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void sent(com.hmsoft.remote.rmi.transport.NettyChannel channel, Object message)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void received(com.hmsoft.remote.rmi.transport.NettyChannel channel, Object message)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						System.err.println("client: received," + message);
						if (message instanceof String) {
							
							final Message msg =  JSON.parseObject(message.toString(), Message.class);
							byte type = msg.getType();
							/*if (type == MsgTypeConst.TYPE_LOGIN_RESP_TO_CLIENT) {
								
								final LoginRequest login = JSON.parseObject(msg.getMsgBody(), LoginRequest.class);
								LOGIN_MAP.put(login.getUserName() + "_" + login.getPassWord(), login);
								
							} else */if (type == MsgTypeConst.TYPE_BIZ_RESP_TO_CLIENT) {
								
								responseToClientFunc(msg);
								
							} else if (type == MsgTypeConst.TYPE_HEARTBEAT) {
							
							}
							
						}
						
					}

					@Override
					public void caught(com.hmsoft.remote.rmi.transport.NettyChannel channel, Throwable exception)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						
					}

					@Override
					public Object reply(com.hmsoft.remote.rmi.transport.NettyChannel channel, Object request)
							throws com.hmsoft.remote.rmi.exception.RemotingException {
						Object ret = null;
						if (request instanceof Message) {
							final Message msg =  (Message)request;
							byte type = msg.getType();
							if (type == MsgTypeConst.TYPE_BIZ_RESP_TO_CLIENT) {
								
								ret = responseToClientFunc(msg);
								
							} else if (type == MsgTypeConst.TYPE_HEARTBEAT) {
							
							}
						}
		
						return ret;
					}
					
				});
			}
			
		}).start();
	}
	
	/**
	 * 接受服务端响应.
	 * @param msg
	 */
	private static Object responseToClientFunc(final Message msg) {
		Object ret = null;
		final BizRequest req = JSON.parseObject(msg.getMsgBody(), BizRequest.class);
		if (req.getReqType() == AppConst.SRV_FRESH_INIT_LIST) {//服务端开启命题征集
			MtzjTab.CURR_SELECTED_MAP.clear();
			MtzjTab.DATALIST.clear();
			List<CoursePlan> showList = req.getSourceList();
			for (CoursePlan course : showList) {
				course.setZjStatusDesc(BatchDataUtil.getStatusCaption(req.getZjStatus()));
				course.getChkBox().setSelected(false);
			}
			MtzjTab.DATALIST.addAll(showList);
			MtzjTab.TABLE.refresh();
			MtzjTab.SELECTED_DATALIST.clear();
			MtzjTab.ZJ_STATUS = req.getZjStatus();
			
			ret = 0;
		} else if (req.getReqType() == AppConst.SRV_SPECIFIC_COURSE) {//服务端指定了课程的学校
			
			List<CoursePlan> removeList = new ArrayList<CoursePlan>();
			List<CoursePlan> specificList = req.getSourceList();
			for (CoursePlan spec : specificList) {
				//不管左边是否有，都把指定的插入到右边已选择列表.如果左边有则删除左边的
				SelectedCourse selected = MtzjTab.buildSelectedCourse(spec);
				if (spec.getSchoolId().longValue() == Main.LOGIN_SCHOOL_ID.longValue()) {
					//指定给当前学校的
					if (!MtzjTab.SELECTED_DATALIST.contains(selected)) {
						selected.setIsSpecifyDesc("命题办指定");
						MtzjTab.addToSelectedTable(selected);
					} else {
						//之前已经自己选择了该课程
						for (SelectedCourse o : MtzjTab.SELECTED_DATALIST) {
							if (selected.getCoursePlanId().intValue() == o.getCoursePlanId().intValue()) {
								o.setIsSpecifyDesc("命题办指定");
								break;
							}
						}
					}
				} else {
					//当前课程是指定给其他学校，如果自己也选择了则选择列表删除
					if (MtzjTab.SELECTED_DATALIST.contains(selected)) {
						MtzjTab.SELECTED_DATALIST.remove(selected);
					}
				}
				//从左边列表查询有则删除 指定的记录
				for (CoursePlan obj : MtzjTab.DATALIST) {
					//没指定的schoolId默认为0,指定了的>0
					if (spec.getCoursePlanId().intValue() == obj.getCoursePlanId().intValue()) {
						removeList.add(obj);
						
						/*if (spec.getSchoolId().longValue() > 0) {
							DELETED_MAP.put(obj.getCoursePlanId(), obj);
							if (spec.getSchoolId().longValue() == Main.LOGIN_SCHOOL_ID.longValue()) {
								removeList.add(obj);
								SelectedCourse selected = MtzjTab.buildSelectedCourse(obj);
								selected.setIsSpecifyDesc("命题办指定");
								MtzjTab.addToSelectedTable(selected);
							} else {
								removeList.add(obj);
							}
						}*/
					}
				}
			}
			MtzjTab.SELECTED_TABLE.refresh();
			MtzjTab.DATALIST.removeAll(removeList);
			ret = 0;
		} else if (req.getReqType() == AppConst.SRV_NOTIFY_SELECT) {//服务端通知其他客户，课程被选择了，客户端锁定
			
			if (req.getSchoolId().longValue() == Main.LOGIN_SCHOOL_ID.longValue()) {
				//本学校选择的，列表不变
			} else {
				//其他学校选择了的课程，disable.本学校不能选择.
				String ids = req.getSelectIds();
				if (ids != null && ids.length() > 0) {
					String[] idArr = ids.split(",");
					final List<CoursePlan> toRemoveList = new ArrayList<CoursePlan>();
					for (String id : idArr) {
						Integer idx = Integer.parseInt(id);
						for (CoursePlan course : MtzjTab.DATALIST) {
							if (course.getCoursePlanId() == idx) {
								toRemoveList.add(course);
							}
						}
					}
					MtzjTab.DATALIST.removeAll(toRemoveList);//直接从列表删除
					MtzjTab.TABLE.refresh();
				}
			}
			ret = 0;
			
		} else if (req.getReqType() == AppConst.SRV_NOTIFY_SELECT) {//服务端通知其他客户，有课程被取消了
			
			if (req.getSchoolId() == Main.LOGIN_SCHOOL_ID) {
				//本学校取消的，列表不变
			} else {
				//其他学校
				MtzjTab.DATALIST.addAll(req.getSourceList());
			}
			ret = 0;
			
		} else if (req.getReqType() == AppConst.SRV_FINAL_PUBLISH) { //最终发布通知
			
			MtzjTab.ZJ_STATUS = BatchConst.STATUS_PUBLISHED;
			for (CoursePlan course : MtzjTab.DATALIST) {
				course.setZjStatusDesc("最终发布");
				course.getChkBox().setDisable(true);
			}
			MtzjTab.TABLE.refresh();
			//保存到最终发布文件
			CoursePlanDataUtil.writeCoursePlan(MtzjTab.SELECTED_DATALIST, req.getBatchNo());
			//更新最终发布界面下拉框
			HisPubTab.BATCH_COMBO_DATA_LIST.add(req.getBatchNo());
			ret = 0;
			
		} else if (req.getReqType() == AppConst.SRV_PUSH_NEW_LIST) {//接收最新的,客户端断开重启后连接接收新征集，登录成功后接收新征集
			
			/*if (req.getSchoolId().longValue() == Main.LOGIN_SCHOOL_ID.longValue()) {//是当前学校才更新对应的拉取.
				MtzjTab.DATALIST.clear();
				MtzjTab.CURR_SELECTED_MAP.clear();
				for (CoursePlan course : req.getSourceList()) {
					//其他学校选择了的，不显示到列表
					if ((course.getSchoolId() > 0 && course.getSchoolId().longValue() != Main.LOGIN_SCHOOL_ID.longValue())
							|| ((course.getSchSelectIds() != null && course.getSchSelectIds().length() > 0) 
									&& !course.getSchSelectIds().contains(Main.LOGIN_SCHOOL_ID.toString()))) {
						continue;
					} else {
						course.setZjStatusDesc(BatchDataUtil.getStatusCaption(req.getZjStatus()));
						//之前是命题办指定的并且指定给当前学校的，显示到已选择，且标识
						if (course.getSchoolId() > 0 && course.getSchoolId().longValue() == Main.LOGIN_SCHOOL_ID.longValue()) {
							SelectedCourse selected = MtzjTab.buildSelectedCourse(course);
							selected.setIsSpecifyDesc("命题办指定");
							selected.setConfirmDesc(course.getConfirmStatus() == 1 ? "已确认" : "否");
							MtzjTab.SELECTED_DATALIST.add(selected);
							MtzjTab.CURR_SELECTED_MAP.put(course.getCoursePlanId(), course);//保存到当前已选择MAP
						} else if (course.getSchSelectIds() != null && course.getSchSelectIds().contains(Main.LOGIN_SCHOOL_ID.toString())) {
							//之前是自己选择的,加入到已选择列表
							SelectedCourse selected = MtzjTab.buildSelectedCourse(course);
							selected.setIsSpecifyDesc("否");
							selected.setConfirmDesc(course.getConfirmStatus() == 1 ? "已确认" : "否");
							MtzjTab.SELECTED_DATALIST.add(selected);
							MtzjTab.CURR_SELECTED_MAP.put(course.getCoursePlanId(), course);//保存到当前已选择MAP
						} else {
							//System.err.println(course.toString());
							MtzjTab.DATALIST.add(course);//没有被任何学校选择的，包括本校也没选择
						}
					}
				}
				MtzjTab.TABLE.refresh();
			}*/
			
		} else if (req.getReqType() == AppConst.SRV_TRIGGER_FRESH) {//定时或手动刷新推送
			
			final List<CoursePlan> removeList = new ArrayList<CoursePlan>();
			for (CoursePlan pushCourse : req.getSourceList()) {
				for (CoursePlan localCourse : MtzjTab.DATALIST) {
					if (pushCourse.getCoursePlanId() == localCourse.getCoursePlanId()) {
						if (!pushCourse.getSchSelectIds().contains(Main.LOGIN_SCHOOL_ID.toString())) {
							removeList.add(localCourse);
						}
						break;
					}
				}
			}
			MtzjTab.DATALIST.removeAll(removeList);
			ret = 0;
			
		} else if (req.getReqType() == AppConst.SRV_DELETE_COURSE) {//管理端删除了课程
			
			MtzjTab.DATALIST.removeAll(req.getSourceList());
			ret = 0;
			
		} else if (req.getReqType() == AppConst.SRV_NOTIFY_CANCEL) {//其他客户端取消了
			
			for (CoursePlan cancelCP : req.getSourceList()) {
				SelectedCourse sc = MtzjTab.buildSelectedCourse(cancelCP);
				if (!MtzjTab.DATALIST.contains(cancelCP) && !MtzjTab.SELECTED_DATALIST.contains(sc)) {
					MtzjTab.DATALIST.add(cancelCP);
				}
			}
			ret = 0;
		}
		
		return ret;
	}
	
	private void doLoginFunc(Stage primaryStage) {
		String userName = userTextField.getText();
		String passWord = passwdField.getText();
		if (userName.trim().length() == 0 || passWord.trim().length() == 0) {
			DialogUtil.showAlertDialog(primaryStage, AlertType.WARNING, "提示", "用户名或者密码不能为空!");
	        return;
		}
		//请求服务端验证用户名密码.
		final LoginRequest login = new LoginRequest(userName, passWord);
		final String json = JSON.toJSONString(login);
		final Message message = new Message(MsgTypeConst.TYPE_LOGIN_REQ_TO_MGE, json);
		try {
			if (CLIENT == null) {
				System.err.println("111");
			}
			Object obj = CLIENT.requestTwoWay(message);
			if (obj instanceof Message) {
				Message resMsg = (Message)obj;
				final LoginResponse res = JSON.parseObject(resMsg.getMsgBody(), LoginResponse.class);
				//收到登录返回
				if (res.getStatus() == 0) {//登录成功
					//登录成功切换场景
					scenetitle.setText("成功!");
					scenetitle.setFill(Color.RED);
					final Main main = new Main();
					main.start(new Stage());
					Main.LOGIN_SCHOOL_ID = res.getSchoolId();
					Main.LOGIN_SCHOOL_NAME = res.getSchoolName();
					Main.MAIN_STAGE.setTitle("命题征集客户端 1.0" + " - " + Main.LOGIN_SCHOOL_NAME);
					primaryStage.hide();
					try {
						//登录成功获取最新征集列表
						MtzjTab.fetchNewList();
					} catch (RemotingException e) {
						e.printStackTrace();
					}
				} else {
					//登录失败.
					scenetitle.setText("失败,用户名或密码错误!");
					scenetitle.setFill(Color.RED);
				}
			}
		} catch (RemotingException e) {
			e.printStackTrace();
		}
	}
}
