package com.gx.obe.management.dialog;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.eclipse.swt.SWT;
import org.eclipse.swt.core.CallBack;
import org.eclipse.swt.core.utils.FileDialogUtils;
import org.eclipse.swt.core.widgets.EDialog;
import org.eclipse.swt.core.widgets.ELabel;
import org.eclipse.swt.core.widgets.ESepator;
import org.eclipse.swt.core.widgets.RectangleRadioButton;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

import com.gx.obe.ColorConstants;
import com.gx.obe.business.enumeration.ExpertEnum;
import com.gx.obe.business.enumeration.UserEnum;
import com.gx.obe.common.dialog.ImportFromExcelDialog;
import com.gx.obe.common.dialog.ImportFromExcelDialog.ImportListener;
import com.gx.obe.common.icons.IconsActivator;
import com.gx.obe.common.widget.dialog.MessageViewDialog;
import com.gx.obe.components.core.Constants;
import com.gx.obe.components.core.enumeration.CommonEnum;
import com.gx.obe.config.ConfigConstants;
import com.gx.obe.config.utils.PropertiesUtils;
import com.gx.obe.management.composite.ImportEvaluationExpertComposite;
import com.gx.obe.management.composite.SelectExpertComposite;
import com.gx.obe.message.Messages;
import com.gx.obe.report.poi.Excel;
import com.gx.obe.report.poi.ExcelRow;
import com.gx.obe.util.utils.LogUtils;
import com.gx.obe.util.utils.MD5Utils;
import com.gx.obe.util.utils.Map2BeanUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.util.utils.SpellHelper;
import com.gx.obe.util.utils.StringUtils;
import com.gx.obe.util.utils.UuidUtils;
import com.gx.obe.util.utils.XmlUtils;
import com.gx.obe.web.entity.auth.AuthRole;
import com.gx.obe.web.entity.auth.AuthUser;
import com.gx.obe.web.entity.auth.AuthUserRole;
import com.gx.obe.web.entity.expert.Expert;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.service.RoleService;
import com.gx.obe.web.service.UserRoleService;
import com.gx.obe.web.service.UserService;
import com.gx.obe.web.service.expert.ExpertService;
import com.gx.utils.NowTimeUtils;
import com.gx.utils.XmlBeanUtils;
import com.swtdesigner.ResourceManager;
import com.swtdesigner.SWTResourceManager;

/**
 * @Description: 导入评标专家成员
 * @author guoyr
 */
public class ImportExpertFromTenderProjectDialog extends EDialog {
	
	private UserService userService ;
	private RoleService roleService ;
	private UserRoleService userRoleService ;
	private ExpertService expertService ;
	private TenderProjectEntity tenderProjectEntity;
//	private CTabFolder tabFolder;
	private ELabel selectExcelFileLabel;
	private ELabel selectXmlFileLabel;
	private Composite load_composite;
	private RectangleRadioButton importSystemExpert;
	private RectangleRadioButton importLocalExpert;
	private RectangleRadioButton importProjectExpert;
	private RectangleRadioButton importButton;
	
	{
		LogUtils.logClass(ImportExpertFromTenderProjectDialog.class);
	}
	
	/**
	 * Create the dialog.
	 * @param parentShell
	 */
	public ImportExpertFromTenderProjectDialog(Shell parentShell, TenderProjectEntity tenderProjectEntity) {
		super(parentShell);
		this.tenderProjectEntity = tenderProjectEntity;
		setShellStyle(SWT.DIALOG_TRIM | SWT.SYSTEM_MODAL);
		setTitle(MessageFormat.format(Messages.Button_importFormat, Messages.Expert));
		expertService = new ExpertService();
	}
	
	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		GridLayout gl_container = new GridLayout(1, false);
		container.setLayout(gl_container);
		
		Composite composite = new Composite(container, SWT.NONE);
		GridLayout gl_composite = new GridLayout(3, false);
		gl_composite.marginHeight = 0;
		gl_composite.marginWidth = 0;
		gl_composite.verticalSpacing = 0;
		composite.setLayout(gl_composite);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		importSystemExpert = new RectangleRadioButton(composite, SWT.NONE);
		importSystemExpert.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				importExpertBySystem();
			}
		});
		importSystemExpert.setText(Messages.System + Messages.Expert);
		
		importLocalExpert = new RectangleRadioButton(composite, SWT.NONE);
		importLocalExpert.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				importLocalExpert();
			}
		});
		importLocalExpert.setText(Messages.Local_import);
		
		importProjectExpert = new RectangleRadioButton(composite, SWT.NONE);
		importProjectExpert.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				importProjectExpert();
			}
		});
		importProjectExpert.setText(Messages.Project_library_import);
		
		ESepator expert_tab = new ESepator(composite, SWT.NONE);
		expert_tab.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
		expert_tab.setBackground(ColorConstants.SKIN_BG);
		expert_tab.setLineWidth(2);
		
		Composite composite_1 = new Composite(container, SWT.NONE);
		GridLayout gl_composite_1 = new GridLayout(1, false);
		gl_composite_1.marginHeight = 0;
		gl_composite_1.verticalSpacing = 0;
		gl_composite_1.horizontalSpacing = 0;
		gl_composite_1.marginWidth = 0;
		composite_1.setLayout(gl_composite_1);
		composite_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1));
		
		load_composite = new Composite(composite_1, SWT.NONE);
		FillLayout fl_load_composite = new FillLayout(SWT.HORIZONTAL);
		load_composite.setLayout(fl_load_composite);
		load_composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		init();
		return container;
	}
	
	/**
	 * @Description: 初始化
	 * @author guoyr
	 */
	private void init(){
		userRoleService = new UserRoleService();
		roleService = new RoleService();
		importSystemExpert.setSelection(true);
		importExpertBySystem();
	}
	
	/**
	 * @Description: 注销所有子界面
	 * @author guoyr 
	 */
	private void disponseChildrenComposite(){
		Control[] controls = load_composite.getChildren();
		for(Control control : controls){
			control.dispose();
		}
	}
	private void changeButtonColor(RectangleRadioButton label){
		if(null != importButton && !importButton.isDisposed()){
			importButton.setSelection(false);
		}
		importButton = label;
		importButton.setSelection(true);
	}
	/**
	 * @Description: 选择系统专家
	 * @author guoyr 
	 */
	private void importExpertBySystem(){
		disponseChildrenComposite();
		changeButtonColor(importSystemExpert);
		new SelectExpertComposite(load_composite, SWT.NONE, tenderProjectEntity);
		load_composite.layout();
	}
	
	/**
	 * @Description: 导入本地专家
	 * @author guoyr 
	 */
	private void importLocalExpert(){
		disponseChildrenComposite();
		changeButtonColor(importLocalExpert);
		Composite composite = new Composite(load_composite, SWT.NONE);
		GridLayout gl_composite = new GridLayout(2, false);
		gl_composite.horizontalSpacing = 80;
		composite.setLayout(gl_composite);
		
		selectExcelFileLabel = new ELabel(composite, SWT.SELECTED | SWT.BOTTOM);
		selectExcelFileLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true, 1, 1));
		selectExcelFileLabel.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/excel_64.png"));
		selectExcelFileLabel.setFont(SWTResourceManager.getFont("宋体", 14, SWT.BOLD));
		selectExcelFileLabel.setText("Excel导入");
		selectExcelFileLabel.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				importLocalExcelFileAction();
			}
		});
		
		selectXmlFileLabel = new ELabel(composite, SWT.SELECTED | SWT.BOTTOM);
		selectXmlFileLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true, 1, 1));
		selectXmlFileLabel.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/xml_64.png"));
		selectXmlFileLabel.setFont(SWTResourceManager.getFont("宋体", 14, SWT.BOLD));
		selectXmlFileLabel.setText("Xml导入");
		selectXmlFileLabel.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				importLocalXmlFileAction();
			}
		});
		load_composite.layout();
	}
	/**
	 * @Description: 导入项目专家
	 * @author guoyr 
	 */
	private void importProjectExpert(){
		disponseChildrenComposite();
		changeButtonColor(importProjectExpert);
		new ImportEvaluationExpertComposite(load_composite, SWT.NONE, tenderProjectEntity);
		load_composite.layout();
	}
	
	
	
	/**
	 * @Description: 导入本地Excel文件
	 * @author guoyr
	 */
	private void importLocalExcelFileAction(){
		Excel excel = new Excel();
		excel.addRow().setHeight(30).addCell().setValue(Messages.Expert).setHead(true);
		ExcelRow row = excel.addRow();
		row.setHeight(25);
		row.addCell().setValue("姓名(必填)").setProperty("userName").setWidth(100).setHead(true);
//		row.addCell().setValue(Messages.Account).setProperty("account").setWidth(100).setHead(true);
		row.addCell().setValue(Messages.Gender).setProperty("gender").setWidth(50).setHead(true);
		row.addCell().setValue(Messages.IDCard).setProperty("userIdcard").setWidth(200).setHead(true);
		row.addCell().setValue(Messages.LinkerTel).setProperty("phone").setWidth(150).setHead(true);
		row.addCell().setValue(Messages.WorkCompany).setProperty("company").setWidth(200).setHead(true);
		row.addCell().setValue(Messages.ProfessionalTitle).setProperty("professionalTitle").setWidth(150).setHead(true);
		row.addCell().setValue(Messages.Specialty).setProperty("specialty").setWidth(150).setHead(true);
		setExcelRowContent(excel);
		ImportFromExcelDialog dialog = new ImportFromExcelDialog(getShell(), excel, new ImportListener(){
			public void onImport(List<Map<String, Object>> excelDataList) {
				getShell().close();
				MessageViewDialog messageDialog = new MessageViewDialog(getShell(), -1);
				new ImportLocalExcelThread(excelDataList, messageDialog.getCallBack()).start();
				messageDialog.setTitle("导入专家");
				messageDialog.open();
			}
		});
		dialog.setTitle("导入专家");
		dialog.open();
	}
	
	/**
	 * @Description: 设置Excel行内容
	 * @author guoyr
	 * @param excel
	 */
	private void setExcelRowContent(Excel excel){
		for(int i = 0; i < 5; i++){
			ExcelRow contentRow = excel.addRow();
			contentRow.setHeight(20);
			contentRow.addCell().setHead(false);
//			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
			contentRow.addCell().setHead(false);
		}
	}
	
	/**
	 * @Description: 导入本地Xml文件
	 * @author guoyr
	 */
	private void importLocalXmlFileAction(){
		String filePath = FileDialogUtils.getFileNames(SWT.SINGLE, "请选择专家文件", new String[]{"*.xml"}, new String[]{"所有专家文件(*.xml)"});
		if(StringUtils.isNotEmpty(filePath)){
			getShell().close();
			MessageViewDialog messageDialog = new MessageViewDialog(getShell(), -1);
			new ImportLocalXmlThread(filePath, messageDialog.getCallBack()).start();
			messageDialog.setTitle("导入专家");
			messageDialog.open();
		}
	}
	
	/**
	 * @Description: 导入本地Excel文件线程
	 * @author guoyr
	 */
	class ImportLocalExcelThread implements Runnable{
		
		private Thread thread;
		private List<Map<String, Object>> excelDataList;
		private CallBack callBack;
		
		public ImportLocalExcelThread(List<Map<String, Object>> excelDataList, CallBack callBack){
			this.excelDataList = excelDataList;
			this.callBack = callBack;
		}
		
		public void start(){
			thread = new Thread(this);
			thread.setName("导入本地Excel文件线程");
			thread.start();
		}
		
		public void stop(){
			thread = null;
		}
		
		public void run() {
			if(null != excelDataList && excelDataList.size() > 0){
				callBackMsg(callBack, "获得"+excelDataList.size()+"位专家！");
				int expertCount = 0;
				for(Map<String, Object> map : excelDataList){
					// 用户名称
					String userName = ObjectUtils.getObjString(map.get("userName"));
					if(null != userName && !"".equals(userName)){
						
						// 封装用户对象
						AuthUser user = Map2BeanUtils.createBean(map, AuthUser.class);
						if(null != user){
							boolean createSuccess = createExpert(callBack, user);
							if(createSuccess){
								expertCount ++;
							}
						}else {
							callBackMsg(callBack, "×【"+userName+"】Excel数据转换实体对象失败！");
						}
					}
				}
				if(expertCount > 0){
					callBackMsg(callBack, "\r\n√此次成功导入"+expertCount+"位专家！");
				}
			}else {
				callBackMsg(callBack, "×未检测到有效的专家！");
			}
			callBackMsg(callBack, "导入专家结束！");
			
			if(null != callBack){
				callBack.after();
			}
		}
		
	}
	private void callBackMsg(CallBack callBack, String msg){
		if(null != callBack){
			callBack.callBackString(msg);
		}
	}

	/**
	 * @Description: 生成专家
	 * @author guoyr
	 * @param callBack
	 * @param user
	 * @return
	 */
	private boolean createExpert(CallBack callBack, AuthUser user){

		if(createOrUpdateUserAndAuthRole(user, callBack)){
			// 根据用户创建专家
			Expert expert = createExpertInfo(user);
			
			// 先验证专家是否已经存在
			if(expertService.getIdListByTenderIdAndUserId( expert.getTenderId(),expert.getUserId())){
				callBackMsg(callBack, "×【"+user.getUserName()+"】专家已经存在！");
				return false;
			}
			
			if(expertService.insert(expert)!= null){
				callBackMsg(callBack, "√【"+user.getUserName()+"】专家导入成功！");
				return true;
			}else {
				callBackMsg(callBack, "×【"+user.getUserName()+"】专家导入失败！");
				return false;
			}
		}else {
			return false;
		}
		
		
	}

	/**
	 * @Description: 导入本地Xml文件线程
	 * @author guoyr
	 */
	class ImportLocalXmlThread implements Runnable{
		
		private Thread thread;
		private String filePath;
		private CallBack callBack;
		
		public ImportLocalXmlThread(String filePath, CallBack callBack){
			this.filePath = filePath;
			this.callBack = callBack;
		}
		
		public void start(){
			thread = new Thread(this);
			thread.setName("导入本地Xml文件线程");
			thread.start();
		}
		
		public void stop(){
			thread = null;
		}
		
		@SuppressWarnings("unchecked")
		public void run() {
			callBackMsg("正在读取专家的Xml文件...");
			Document doc = XmlUtils.getXmlDocument(filePath);
			if(null != doc){
				callBackMsg("√读取专家的Xml文件成功！");
				Element rootElement = doc.getRootElement();
				List<Element> userElementList = rootElement.elements("memberInfo");
				if(null != userElementList && userElementList.size() > 0){
					callBackMsg("获得"+userElementList.size()+"位专家！");
					int expertCount = 0;
					for(Element userElement : userElementList){
						// 用户名称
						String userName = userElement.elementTextTrim("workgmName");
						callBackMsg("正在读取【"+userName+"】用户信息...");
						// 封装用户对象
						AuthUser user = XmlBeanUtils.elementToBean(userElement, AuthUser.class);
						if(null != user){
							boolean createSuccess = createExpert(callBack, user);
							if(createSuccess){
								expertCount ++;
							}
						}else {
							callBackMsg("×【"+userName+"】Xml数据转换实体对象失败！");
						}
					}
					if(expertCount > 0){
						callBackMsg("√导入"+expertCount+"位专家成功！");
					}
				}else {
					callBackMsg("×未检测到有效的专家！");
				}
			}else {
				callBackMsg("×读取专家的Xml文件失败！");
			}
			callBackMsg("导入专家结束！");
			if(null != callBack){
				callBack.after();
			}
		}
		
		private void callBackMsg(String msg){
			if(null != callBack){
				callBack.callBackString(msg);
			}
		}
	}
	
	/**
	 * @Description: 设置用户信息
	 * @author guoyr
	 * @param user
	 */
	private boolean createOrUpdateUserAndAuthRole(AuthUser user, CallBack callBack){
		if(null == userService){
			userService = new UserService();
		}
		AuthUser existUser = null;
		if(null != user.getUserIdcard() && user.getUserIdcard().length() > 0){
			// 根据帐号查询用户信息。
			existUser = userService.getUserByIdCard(user.getUserIdcard());
		}
		String account = "";// 专家账号
		if(null == existUser){
			account = SpellHelper.getEname(user.getUserName());
			account = StringUtils.isNotEmpty(account) ? account : user.getUserName();
			List<AuthUser> sameAccountUserList =  userService.getUserAllByUserAccount(account);;
			// 如果存在同名
			if(null != sameAccountUserList && sameAccountUserList.size() > 0){
				for(AuthUser tempUser : sameAccountUserList){
					if(tempUser.getUserName().equals(user.getUserName())){
						existUser = tempUser;
						break;
					}
				}
				if(null == existUser){
					account = account + (sameAccountUserList.size() + 1);
				}
			}
		}
		if(null == existUser){
			user.setId(UuidUtils.getUUID());
			user.setUserAccount(account);// 账号
			user.setUserPassword(MD5Utils.getMD5String(PropertiesUtils.getProperty(ConfigConstants.EXPERT_DEFAULT_PASSWORD, "1")));// 密码(MD5加密)
			user.setGender(UserEnum.MALE);
			user.setUserType(UserEnum.EXPERT);
			user.setCreateTime(NowTimeUtils.getNowDate());
			user.setUseStatus(CommonEnum.REAL_STATUS);
//			user.setAvatar(ImageResolver.getImageBytes(defaultAvatorImage));// 默认头像
			if(userService.createUserInfo(user) != null){
//				callBackMsg(callBack, "×【"+user.getUserName()+"】专家导入成功！");
				callBackMsg(callBack, "正在为【"+user.getUserName()+"】分配角色...");
				if(setUserRole(user)){
					callBackMsg(callBack, "√为【"+user.getUserName()+"】分配角色成功！");
				}else {
					callBackMsg(callBack, "×为【"+user.getUserName()+"】分配角色失败！");
				}
				return true;
			}else {
				callBackMsg(callBack, "×【"+user.getUserName()+"】专家导入失败！");
			}
		}else{// 修改用户信息
			user.setId(existUser.getId());
			if(userService.updateAssignProperty(user, new String[]{"professionalTitle", "userIdcard", "phone", "specialty", "company"})){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * @Description: 分配用户角色
	 * @author guoyr
	 * @param user
	 * @return
	 */
	private boolean setUserRole(AuthUser user){
		boolean isSuccess = false;
		//则默认为专家分配专家角色
		List<AuthRole> roleList = roleService.getRoleListByRoleType(Constants.TERMINAL_EVALUATION);
		if(null != roleList && roleList.size() > 0){
			List<AuthUserRole> userRoleList = new ArrayList<AuthUserRole>();
			for(AuthRole authRole : roleList){
				AuthUserRole authUserRole = new AuthUserRole();
				authUserRole.setRoleId(authRole.getId());
				authUserRole.setId(user.getId());
				authUserRole.setCreateTime(NowTimeUtils.getNowDate());
				authUserRole.setCreateUserId(Constants.USER.getId());
				userRoleList.add(authUserRole);
			}
			if(userRoleService.batchSave(userRoleList) > 0){
				isSuccess = true;
			}
		}
		return isSuccess;
	}
	
	/**
	 * @Description: 创建专家
	 * @author guoyr
	 * @param user
	 * @param isLeader
	 * @return
	 */
	private Expert createExpertInfo(AuthUser user){
		Expert expert = new Expert();
		expert.setUser(user);
		expert.setTenderId(tenderProjectEntity.getId());
		expert.setUserId(user.getId());
		expert.setCreateTime(NowTimeUtils.getNowDate());
		expert.setCreateUserId(Constants.USER.getId());
		expert.setIsLeader(ExpertEnum.LEADER_NO);
		expert.setExpertType(ExpertEnum.EXPERT);
		if(null != tenderProjectEntity.getParentId() && !"".equals(tenderProjectEntity.getParentId())){
			expert.setProjectId(tenderProjectEntity.getParentId());
		}else{
			expert.setProjectId(tenderProjectEntity.getId());
		}
		return expert;
	}
	
	@Override
	protected Point getInitialSize() {
		return new Point(814, 481);
	}
}
