package com.hmsoft.bizpanel;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.hmsoft.app.Login;
import com.hmsoft.app.Main;
import com.hmsoft.common.AppConst;
import com.hmsoft.common.BatchConst;
import com.hmsoft.common.MsgTypeConst;
import com.hmsoft.common.util.BatchDataUtil;
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.remote.rmi.exception.RemotingException;
import com.hmsoft.remote.rmi.model.Message;
import org.apache.commons.beanutils.BeanUtils;
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * 命题征集
 * @author zq
 *
 */
public class MtzjTab extends Tab {

	public static final TableView<CoursePlan> TABLE = new TableView<CoursePlan>();//征集中表格
	public static final ObservableList<CoursePlan> DATALIST = FXCollections.observableArrayList();
	public static final TableView<SelectedCourse> SELECTED_TABLE = new TableView<SelectedCourse>();//已选择的表格
	public static final ObservableList<SelectedCourse> SELECTED_DATALIST = FXCollections.observableArrayList();
	public static final Map<Integer, CoursePlan> CURR_SELECTED_MAP = new HashMap<Integer, CoursePlan>();//当前学校选择的课程,取消时回填
	public static byte ZJ_STATUS = BatchConst.STATUS_COLLECTING;//默认征集中
	//public static final Map<Integer, CoursePlan> OTHER_SELECTED_MAP = new HashMap<Integer, CoursePlan>();//其他学校已经选择的
	
	public MtzjTab(final Stage stage) {
		super();
		this.setText("命题征集");
		this.setId("collectTabId");
		this.setClosable(false);
		//Grid
		GridPane gp = new GridPane();
		gp.setPadding(new Insets(20));
		gp.setHgap(5);
		gp.setVgap(5);
		//创建按钮
		this.createBtn(gp, stage);
		//创建表格
		double totalW = stage.getWidth() - 70;
		double totalH = stage.getHeight() - 170;
		double leftW = Math.round(totalW * 0.55);
		double rigthW = Math.round(totalW * 0.45);
		this.createMtzjTable(gp, stage, leftW, totalH);
		this.createSelectedTable(gp, stage, rigthW, totalH);
		//grid内容
		this.setContent(gp);
	}
	
	private void createBtn(final GridPane gp, final Stage stage) {
		
		//提交选择
		Button btnSubmit = new Button();
		btnSubmit.setText("提交选择");
		//取消选择
		Button btnFeedBack = new Button();
		btnFeedBack.setText("确认反馈");
		
		//支持选择和取消,如果checkbox 为空则是取消
		btnSubmit.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				if (ZJ_STATUS != BatchConst.STATUS_COLLECTING) {
					return;
				}
				try {
					StringBuilder ids = new StringBuilder();
					final List<CoursePlan> selectList = new ArrayList<CoursePlan>();
					ObservableList<CoursePlan> items = DATALIST;
					for (int m=0; m<items.size(); m++) {
						final CoursePlan course = items.get(m);
						if (course.getChkBox().isSelected() && course.getChkBox().isDisabled() == false) {
							if (!checkIsAlreadySelected(course)) {
								ids.append(course.getCoursePlanId());
								ids.append(",");
								selectList.add(course);
								CURR_SELECTED_MAP.put(course.getCoursePlanId(), course);
							}
						}
					}
					if (ids.length() > 0) {
						final BizRequest req = new BizRequest();
						req.setReqType(AppConst.SCH_SELECT_COURSE);//选择
						req.setSelectIds(ids.substring(0, ids.length() - 1));
						req.setSchoolId(Main.LOGIN_SCHOOL_ID);
						req.setSchoolName(Main.LOGIN_SCHOOL_NAME);
						final String json = JSON.toJSONString(req);
						final Message msg = new Message(MsgTypeConst.TYPE_BIZ_REQ_TO_MGE, json);
						//IFuture future = 
						try {
							Object obj = Login.CLIENT.requestTwoWay(msg);
							if (obj != null) {
								//左边删除选择的
								deleteFromMainTable(selectList);
								//加入到右边已选择列表
								addToSelectedTable(selectList);
								//输出
								DialogUtil.showAlertDialog(stage, AlertType.INFORMATION, "成功", "提交成功!");
							}
						} catch(Exception e) {
							//TODO ...重试
						}

					} else {
						DialogUtil.showAlertDialog(stage, AlertType.WARNING, "提示", "请选择课程!");
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		
		//确认反馈
		btnFeedBack.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				if (ZJ_STATUS != BatchConst.STATUS_PUBLISHED) {
					DialogUtil.showAlertDialog(stage, AlertType.WARNING, "提示", "命题办发布后再确认!");
					return;
				}
				if (DialogUtil.confirm("是否提交反馈？", stage)) {
					try {
						StringBuilder idsSb = new StringBuilder();
						for (SelectedCourse stc : SELECTED_DATALIST) {
							idsSb.append(stc.getCoursePlanId()).append(",");
						}
						//send
						final BizRequest req = new BizRequest();
						req.setReqType(AppConst.SCH_CONFIRM_OK);//确认
						req.setSchoolId(Main.LOGIN_SCHOOL_ID);
						req.setSchoolName(Main.LOGIN_SCHOOL_NAME);
						req.setSelectIds(idsSb.length() > 0 ? idsSb.substring(0, idsSb.length() - 1) : "");
						final String json = JSON.toJSONString(req);
						final Message msg = new Message(MsgTypeConst.TYPE_BIZ_REQ_TO_MGE, json);
						//IFuture future = 
						Object obj = Login.CLIENT.requestTwoWay(msg);
						if (obj != null) {
							for (SelectedCourse stc : SELECTED_DATALIST) {
								stc.setConfirmDesc("已确认");
							}
							SELECTED_TABLE.refresh();
							DialogUtil.showAlertDialog(stage, Alert.AlertType.INFORMATION, "成功", "反馈成功!");
						}
					} catch (RemotingException e) {
						e.printStackTrace();
						//TODO ....
					}
				}
			}
		});
		
		//加入容器
		gp.add(btnSubmit, 0, 0);
		gp.add(btnFeedBack, 1, 0);
	}

	@SuppressWarnings("unchecked")
	private void createMtzjTable(final GridPane gp, final Stage stage, final double width, final double height) {
		//表格宽度
		TABLE.setMinWidth(width);
		TABLE.setMinHeight(height);
		TABLE.setEditable(true);
		//表格列
		final TableColumn<CoursePlan, CheckBox> checkBoxCol = new TableColumn<CoursePlan, CheckBox>("选择");
		checkBoxCol.setCellValueFactory(new PropertyValueFactory<CoursePlan, CheckBox>("chkBox"));
		checkBoxCol.setMinWidth(10);
		
		final TableColumn<CoursePlan, Integer> coursePlanId = new TableColumn<CoursePlan, Integer>("ID");
		coursePlanId.setCellValueFactory(new PropertyValueFactory<CoursePlan, Integer>("coursePlanId"));
		coursePlanId.setMinWidth(10);
		final TableColumn<CoursePlan, String> courseCode = new TableColumn<CoursePlan, String>("课程代码");
		courseCode.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("courseCode"));
		courseCode.setMinWidth(30);
		final TableColumn<CoursePlan, String> courseName = new TableColumn<CoursePlan, String>("课程名称");
		courseName.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("courseName"));
		courseName.setMinWidth(50);
		final TableColumn<CoursePlan, String> outlineName = new TableColumn<CoursePlan, String>("课程大纲");
		outlineName.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("outlineName"));
		outlineName.setMinWidth(60);
		final TableColumn<CoursePlan, String> bookName = new TableColumn<CoursePlan, String>("教材名称");
		bookName.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("bookName"));
		bookName.setMinWidth(60);
		final TableColumn<CoursePlan, String> bianZhu = new TableColumn<CoursePlan, String>("编著");
		bianZhu.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("bianZhu"));
		bianZhu.setMinWidth(30);
		final TableColumn<CoursePlan, String> press = new TableColumn<CoursePlan, String>("出版社");
		press.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("press"));
		press.setMinWidth(50);
		final TableColumn<CoursePlan, String> publications = new TableColumn<CoursePlan, String>("版次");
		publications.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("publications"));
		publications.setMinWidth(30);
		final TableColumn<CoursePlan, String> cengci = new TableColumn<CoursePlan, String>("层次");
		cengci.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("cengci"));
		cengci.setMinWidth(30);
		final TableColumn<CoursePlan, String> zjStatus = new TableColumn<CoursePlan, String>("征集状态");
		zjStatus.setCellValueFactory(new PropertyValueFactory<CoursePlan, String>("zjStatusDesc"));
		zjStatus.setMinWidth(30);
		//学校选择的课程IDs
		
		TABLE.setItems(DATALIST);
		TABLE.getColumns().addAll(checkBoxCol, coursePlanId, courseCode, courseName, outlineName, bookName, 
				bianZhu, press, publications, cengci, zjStatus);
		
		final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(TABLE);
        
        gp.add(vbox, 0, 1, 1, 1);
	}
	
	//已选择的课程列表
	@SuppressWarnings("unchecked")
	private void createSelectedTable(final GridPane gp, final Stage stage, final double width, final double height) {
		//表格宽度
		SELECTED_TABLE.setMinWidth(width);
		SELECTED_TABLE.setMinHeight(height);
		SELECTED_TABLE.setEditable(true);
		final TableColumn<SelectedCourse, Integer> coursePlanId = new TableColumn<SelectedCourse, Integer>("ID");
		coursePlanId.setCellValueFactory(new PropertyValueFactory<SelectedCourse, Integer>("coursePlanId"));
		coursePlanId.setMinWidth(10);
		final TableColumn<SelectedCourse, String> courseCode = new TableColumn<SelectedCourse, String>("课程代码");
		courseCode.setCellValueFactory(new PropertyValueFactory<SelectedCourse, String>("courseCode"));
		courseCode.setMinWidth(60);
		final TableColumn<SelectedCourse, String> courseName = new TableColumn<SelectedCourse, String>("课程名称");
		courseName.setCellValueFactory(new PropertyValueFactory<SelectedCourse, String>("courseName"));
		courseName.setMinWidth(150);
		final TableColumn<SelectedCourse, String> isSpecify = new TableColumn<SelectedCourse, String>("是否命题办指定");
		isSpecify.setCellValueFactory(new PropertyValueFactory<SelectedCourse, String>("isSpecifyDesc"));
		isSpecify.setMinWidth(120);
		final TableColumn<SelectedCourse, String> confirmDesc = new TableColumn<SelectedCourse, String>("是否已确认");
		confirmDesc.setCellValueFactory(new PropertyValueFactory<SelectedCourse, String>("confirmDesc"));
		confirmDesc.setMinWidth(120);
		final TableColumn<SelectedCourse, Button> cancelCol = new TableColumn<SelectedCourse, Button>("操作");
		cancelCol.setCellValueFactory(new PropertyValueFactory<SelectedCourse, Button>("btnCancel"));
		cancelCol.setMinWidth(100);

		cancelCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<SelectedCourse, Button>, ObservableValue<Button>>() {
			
			@Override
			public ObservableValue<Button> call(CellDataFeatures<SelectedCourse, Button> param) {
				return new ObservableValue<Button>(){

					@Override
					public void addListener(InvalidationListener listener) {
					}

					@Override
					public void removeListener(InvalidationListener listener) {
					}

					@Override
					public void addListener(ChangeListener<? super Button> listener) {
					}

					@Override
					public void removeListener(ChangeListener<? super Button> listener) {
					}

					@Override
					public Button getValue() {
						Button btn = new Button("取消选择");
						btn.setOnAction(new EventHandler<ActionEvent>() {
							
							@Override
							public void handle(ActionEvent event) {
								cancelSelect(param.getValue(), stage);
							}
						});
						if (param.getValue().getIsSpecifyDesc() != null 
								&& param.getValue().getIsSpecifyDesc().equals("命题办指定")) {
							btn.setDisable(true);//命题办指定的不能取消
						}
						return btn;
					}
					
				};
			}
		});
		
		SELECTED_TABLE.setItems(SELECTED_DATALIST);
		SELECTED_TABLE.getColumns().addAll(coursePlanId, courseCode, courseName, isSpecify, confirmDesc, cancelCol);
		
		final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(SELECTED_TABLE);
        
        gp.add(vbox, 1, 1, 1, 1);
	}
	
	//左边待选择列表删除
	private void deleteFromMainTable(final List<CoursePlan> selectList) {
		DATALIST.removeAll(selectList);
	}
	//右边已选择列表添加
	private void addToSelectedTable(final List<CoursePlan> selectList) {
		SELECTED_DATALIST.addAll(buildSelectedList(selectList));
	}
	
	//其他类调用
	public static void addToSelectedTable(final SelectedCourse selectedCourse) {
		SELECTED_DATALIST.addAll(selectedCourse);
	}
	
	private List<SelectedCourse> buildSelectedList(final List<CoursePlan> selectList) {
		List<SelectedCourse> list = new ArrayList<SelectedCourse>();
		for (CoursePlan course : selectList) {
			SelectedCourse selected = new SelectedCourse();
			try {
				BeanUtils.copyProperties(selected, course);
				selected.setIsSpecifyDesc("否");
				selected.setConfirmDesc(course.getConfirmStatus() == 1 ? "已确认" : "否");
				list.add(selected);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	
	//其他类调用
	public static SelectedCourse buildSelectedCourse(final CoursePlan coursePlan) {
		SelectedCourse selected = new SelectedCourse();
		try {
			BeanUtils.copyProperties(selected, coursePlan);
			selected.setConfirmDesc(coursePlan.getConfirmStatus() == 1 ? "已确认" : "否");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return selected;
	}
	
	//检查左边表勾选对象是否右边选择区已经存在
	private boolean checkIsAlreadySelected(final CoursePlan coursePlan) {
		for (SelectedCourse stc : SELECTED_DATALIST) {
			if (stc.getCoursePlanId().intValue() == coursePlan.getCoursePlanId().intValue()) {
				return true;
			}
		}
		return false;
	}
	
	private void deleteFromSelectedTable(final SelectedCourse selectedCourse) {
		SELECTED_DATALIST.remove(selectedCourse);
	}
	
	//取消后加到左边待选择列表
	private void addCancelToLeftTable(final SelectedCourse selectedCourse) {
		CoursePlan course = CURR_SELECTED_MAP.remove(selectedCourse.getCoursePlanId());
		course.getChkBox().setSelected(false);
		DATALIST.add(course);
	}
	
	//取消选择
	private void cancelSelect(final SelectedCourse selectedCourse, final Stage stage) {
		if (ZJ_STATUS == BatchConst.STATUS_PUBLISHED) {
			DialogUtil.showAlertDialog(stage, AlertType.WARNING, "提示", "已发布，不能取消!");
			return;
		}
		//主表取消选择
		if (DialogUtil.confirm("是否取消？", stage)) {
			//发送消息
			final BizRequest req = new BizRequest();
			req.setReqType(AppConst.SCH_CANCEL_COURSE);//取消
			req.setSelectIds(selectedCourse.getCoursePlanId().toString());
			req.setSchoolId(Main.LOGIN_SCHOOL_ID);
			req.setSchoolName(Main.LOGIN_SCHOOL_NAME);
			final String json = JSON.toJSONString(req);
			final Message msg = new Message(MsgTypeConst.TYPE_BIZ_REQ_TO_MGE, json);
			try {
				//IFuture future = 
				//Login.CLIENT.requestToMgr(msg).get();
				Object obj = Login.CLIENT.requestTwoWay(msg);
				if (obj != null) {
					for (CoursePlan cp : DATALIST) {
						if (cp.getCoursePlanId().intValue() == selectedCourse.getCoursePlanId().intValue()) {
							cp.getChkBox().setSelected(false);
						}
					}
					deleteFromSelectedTable(selectedCourse);//已选择列表中删除
					addCancelToLeftTable(selectedCourse);
					//输出
					DialogUtil.showAlertDialog(stage, AlertType.INFORMATION, "成功", "已成功取消!");
				}
			} catch (RemotingException e) {
				//TODO 重试
				e.printStackTrace();
			}
		}
	}
	
	//连接成功就去拉取最新的列表
	public static void fetchNewList() throws RemotingException {
		final BizRequest req = new BizRequest();
		req.setReqType(AppConst.SCH_FETCH_NEW_LIST);//拉取最新
		req.setSchoolId(Main.LOGIN_SCHOOL_ID);//拉取学校
		final String json = JSON.toJSONString(req);
		final Message msg = new Message(MsgTypeConst.TYPE_BIZ_REQ_TO_MGE, json);
		Object obj = Login.CLIENT.requestTwoWay(msg);
		if (obj != null) {
			Message retMsg = (Message)obj;
			BizRequest retReq = JSON.parseObject(retMsg.getMsgBody(), BizRequest.class);
			MtzjTab.DATALIST.clear();
			MtzjTab.CURR_SELECTED_MAP.clear();
			for (CoursePlan course : retReq.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();
		}
	}
}
