package com.palmnest.webapp.controller;

import com.palmnest.application.Constants;
import com.palmnest.application.ElementConstant;
import com.palmnest.application.core.util.LingLingUtil;
import com.palmnest.application.core.util.StringUtil;
import com.palmnest.application.dto.OrgDto;
import com.palmnest.model.AppUserCompanyRelation;
import com.palmnest.model.Role;
import com.palmnest.model.TbCompany;
import com.palmnest.model.User;
import com.palmnest.model.estateserve.VirtualAccount;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.model.property.TbOrganization;
import com.palmnest.model.property.VirtualArchitecture;
import com.palmnest.service.*;
import com.palmnest.service.estateserve.ScWxuserManager;
import com.palmnest.service.property.PropertyManager;
import com.palmnest.service.redis.BaseRedisService;
import com.palmnest.service.virtProject.manager.VirtualAccountManager;
import com.palmnest.service.washcar.service.ElementGroupService;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.context.MessageSource;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Implementation of <strong>SimpleFormController</strong> that contains
 * convenience methods for subclasses. For example, getting the current user and
 * saving messages/errors. This class is intended to be a base class for all
 * Form controllers.
 *
 * <p>
 * <a href="BaseFormController.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author <a href="mailto:chasel.java@gmail.com">Chasel Li</a>
 */
@Slf4j
public class BaseFormController implements ServletContextAware {


	public static final String                MESSAGES_KEY = "successMessages";
	private             UserManager           userManager  = null;
	protected           MailEngine            mailEngine   = null;
	protected           SimpleMailMessage     message      = null;
	protected           String                templateName = "accountCreated.vm";
	protected           String                cancelView;
	protected           String                successView;
	private             MessageSourceAccessor messages;
	private             ServletContext        servletContext;

	@Autowired
	private ElementGroupManager   elementGroupManager;
	@Autowired
	private PropertyManager       propertyManager;
	@Autowired
	private OrganizationManager   organizationManager;
	@Autowired
	private AppUserService        appUserService;
	@Autowired
	private BaseRedisService      baseRedisService;
	@Autowired
	private ScWxuserManager       scWxuserManager;
	@Autowired
	private ElementGroupService   elementGroupService;
	@Autowired
	private VirtualAccountManager virtualAccountManager;

	@Autowired(required = false)
	Validator validator;

	@Autowired
	public void setMessages(MessageSource messageSource) {
		messages = new MessageSourceAccessor(messageSource);
	}

	@Autowired
	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}

	public UserManager getUserManager() {
		return this.userManager;
	}

	@Autowired
	public void setElementGroupManager(ElementGroupManager elementGroupManager) {
		this.elementGroupManager = elementGroupManager;
	}

	public ElementGroupManager getElementGroupManager() {
		return elementGroupManager;
	}

	@SuppressWarnings({"unchecked", "rawtypes"})
	public void saveError(HttpServletRequest request, String error) {
		List errors = (List) request.getSession().getAttribute("errors");
		if (errors == null) {
			errors = new ArrayList();
		}
		errors.add(error);
		request.getSession().setAttribute("errors", errors);
	}

	@SuppressWarnings({"unchecked", "rawtypes"})
	public void saveMessage(HttpServletRequest request, String msg) {
		List messages = (List) request.getSession().getAttribute(MESSAGES_KEY);

		if (messages == null) {
			messages = new ArrayList();
		}

		messages.add(msg);
		request.getSession().setAttribute(MESSAGES_KEY, messages);
	}

	/**
	 * Convenience method for getting a i18n key's value. Calling
	 * getMessageSourceAccessor() is used because the RequestContext variable is
	 * not set in unit tests b/c there's no DispatchServlet Request.
	 *
	 * @param msgKey
	 * @param locale the current locale
	 * @return
	 */
	public String getText(String msgKey, Locale locale) {
		return messages.getMessage(msgKey, locale);
	}

	/**
	 * Convenient method for getting a i18n key's value with a single string
	 * argument.
	 *
	 * @param msgKey
	 * @param arg
	 * @param locale the current locale
	 * @return
	 */
	public String getText(String msgKey, String arg, Locale locale) {
		return getText(msgKey, new Object[]{arg}, locale);
	}

	/**
	 * Convenience method for getting a i18n key's value with arguments.
	 *
	 * @param msgKey
	 * @param args
	 * @param locale the current locale
	 * @return
	 */
	public String getText(String msgKey, Object[] args, Locale locale) {
		return messages.getMessage(msgKey, args, locale);
	}

	/**
	 * Convenience method to get the Configuration HashMap from the servlet
	 * context.
	 *
	 * @return the user's populated form from the session
	 */
	@SuppressWarnings("rawtypes")
	public Map getConfiguration() {
		Map config = (HashMap) servletContext.getAttribute(Constants.CONFIG);

		// so unit tests don't puke when nothing's been set
		if (config == null) {
			return new HashMap();
		}

		return config;
	}

	/**
	 * Set up a custom property editor for converting form inputs to real
	 * objects
	 *
	 * @param request the current request
	 * @param binder  the data binder
	 */
	@InitBinder
	protected void initBinder(HttpServletRequest request,
							  ServletRequestDataBinder binder) {
		binder.registerCustomEditor(Integer.class, null,
				new CustomNumberEditor(Integer.class, null, true));
		binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(
				Long.class, null, true));
		binder.registerCustomEditor(byte[].class,
				new ByteArrayMultipartFileEditor());
		SimpleDateFormat dateFormat = new SimpleDateFormat(getText(
				"date.format", request.getLocale()));
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, null, new CustomDateEditor(
				dateFormat, true));
	}

	/**
	 * Convenience message to send messages to users, includes app URL as
	 * footer.
	 *
	 * @param user the user to send a message to.
	 * @param msg  the message to send.
	 * @param url  the URL of the application.
	 */
	protected void sendUserMessage(User user, String msg, String url) {
		// annotate by yb
		/*
		 * if (log.isDebugEnabled()) { log.debug("sending e-mail to user [" +
		 * user.getEmail() + "]..."); }
		 *
		 * message.setTo(user.getFullName() + "<" + user.getEmail() + ">");
		 *
		 * Map<String, Serializable> model = new HashMap<String,
		 * Serializable>(); model.put("user", user);
		 *
		 * // TODO: once you figure out how to get the global resource bundle in
		 * // WebWork, then figure it out here too. In the meantime, the
		 * Username // and Password labels are hard-coded into the template. //
		 * model.put("bundle", getTexts()); model.put("message", msg);
		 * model.put("applicationURL", url); mailEngine.sendMessage(message,
		 * templateName, model);
		 */
	}

	@Autowired
	public void setMailEngine(MailEngine mailEngine) {
		this.mailEngine = mailEngine;
	}

	@Autowired
	public void setMessage(SimpleMailMessage message) {
		this.message = message;
	}

	public void setTemplateName(String templateName) {
		this.templateName = templateName;
	}

	public final BaseFormController setCancelView(String cancelView) {
		this.cancelView = cancelView;
		return this;
	}

	public final String getCancelView() {
		// Default to successView if cancelView is invalid
		if (this.cancelView == null || this.cancelView.length() == 0) {
			return getSuccessView();
		}
		return this.cancelView;
	}

	public final String getSuccessView() {
		return this.successView;
	}

	public final BaseFormController setSuccessView(String successView) {
		this.successView = successView;
		return this;
	}

	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	protected ServletContext getServletContext() {
		return servletContext;
	}

	/**
	 * 初始化功能的操作权限
	 *
	 * @param request
	 */
	public void initFunctionOperate(HttpServletRequest request) {
		String funcid = request.getParameter("funcid");     //当期功能id
		if (StringUtils.isNotEmpty(funcid)) {
			Map<Integer, String> funcOperateCache = (Map<Integer, String>) request.getSession().getAttribute("FunctionOperateCache");
			String               operateStr       = funcOperateCache.get(Integer.parseInt(funcid));
			if (StringUtils.isNotEmpty(operateStr)) {
				if (operateStr.contains(ElementConstant.OPRATETYPE_ADD)) {
					request.setAttribute("addAct", "1");    //新增权限
				}
				if (operateStr.contains(ElementConstant.OPRATETYPE_UPD)) {
					request.setAttribute("updateAct", "1"); //修改权限
				}
				if (operateStr.contains(ElementConstant.OPRATETYPE_DEL)) {
					request.setAttribute("deleteAct", "1"); //修改权限
				}
			}
			request.setAttribute("funcid", funcid);
		}
	}

	/**
	 * 获取系统用户的物业项目权限集合
	 *
	 * @param request
	 * @return List<TbCompany>
	 */
	public List<TbCompany> getUserRelationCompanyList(HttpServletRequest request) {
		//获取当前用户 
		//TODO后续可以通过缓存控制
		User user = (User) request.getSession().getAttribute("UserCache");
		return organizationManager.getAppUserRelationCompany(user.getId().intValue());
	}

	/**
	 * 获取系统用户的物业项目权限id的字符串
	 *
	 * @param request
	 * @return 1, 2, 3, 4
	 */
	public String getUserRelationCompanyIdsStr(HttpServletRequest request) {
		User          user           = (User) request.getSession().getAttribute("UserCache");
		List<Integer> tempCompanyIds = new ArrayList<Integer>();

		List<AppUserCompanyRelation> relations         = userManager.getAppUserCompanyByUserId(user.getId().intValue());
		String                       organizationIdStr = "";
		if (!CollectionUtils.isEmpty(relations)) {
			for (AppUserCompanyRelation companyRelation : relations) {
				organizationIdStr += companyRelation.getCompanyId().toString() + ",";
				tempCompanyIds.add(companyRelation.getCompanyId());
			}
		}

		if (StringUtils.isNotEmpty(organizationIdStr)) {
			organizationIdStr = organizationIdStr.substring(0, organizationIdStr.lastIndexOf(","));
		} else {
			organizationIdStr = "-1";
		}
		return organizationIdStr;
	}


	/**
	 * 获取系统用户的高校组织权限集合
	 *
	 * @param
	 * @return String 1,2,3,4
	 */
	public String getUserRelationOrganizationStr(List<TbOrganization> organizationList) {
		String organizationIdStr = "";
		if (!CollectionUtils.isEmpty(organizationList)) {
			for (TbOrganization obj : organizationList) {
				organizationIdStr += obj.getId().toString() + ",";
			}
		}
		if (StringUtils.isNotEmpty(organizationIdStr)) {
			organizationIdStr = organizationIdStr.substring(0, organizationIdStr.lastIndexOf(","));
		} else {
			organizationIdStr = "-1";
		}
		return organizationIdStr;
	}

	/**
	 * 获取系统用户的项目权限集合
	 *
	 * @param request
	 * @return List<TbCompany>
	 */
	public List<TbOrganization> getUserRelationOrgList(HttpServletRequest request) {
		//获取当前用户
		//TODO后续可以通过缓存控制
		User user = (User) request.getSession().getAttribute("UserCache");
		return organizationManager.getUserRelationOrganizationList(user.getId());
	}

	/**
	 * web端获取当前登录用户所管辖的项目id串
	 *
	 * @return
	 */
	public String getUserManageOrgIds(User user) {
		String       orgStr = "";
		List<OrgDto> dtos   = appUserService.getUserOrgs(user.getId());
		//拼接项目id
		if (dtos != null && dtos.size() > 0) {
			for (OrgDto org : dtos) {
				orgStr += "," + org.getId();
			}
			orgStr = orgStr.substring(1);
		}
		return orgStr;
	}

	/**
	 * 微信端获取项目
	 *
	 * @param openId
	 * @return
	 */
	public String getWxUserOrgId(String openId) {
		String orgId = "";
		WxUser user  = scWxuserManager.getScWxuserByOpenId(openId);
		if (user != null && user.getOrganizationId() != null) {
			orgId = user.getOrganizationId().toString();
		}
		return orgId;
	}

	/**
	 * App端获取当前登录用户所管辖的项目id串
	 *
	 * @param request
	 * @return
	 */
	public String getAppUserManageOrgIds(HttpServletRequest request) {
		String userName = baseRedisService.get(request.getHeader("token"));
		if (userName == null) {
			return null;
		}

		User         user   = userManager.getUserByUsername2(userName);
		String       orgStr = "";
		List<OrgDto> dtos   = appUserService.getUserOrgs(user.getId());
		//拼接项目id
		if (dtos != null && dtos.size() > 0) {
			for (OrgDto org : dtos) {
				orgStr += "," + org.getId();
			}
			orgStr = orgStr.substring(1);
		}
		return orgStr;
	}
//	/**
//	 * 判断当前时间是否超出11点
//	 * @return
//	 */
//	public String isOverTime(){
//		List<Element> elList=elementGroupService.getElementsByGroupName("orderTime");
//		String eleventTime="105000";
//		int sysoTime=0;
//		if(elList!=null&&elList.size()>0){
//			Element element=elList.get(0);
//			eleventTime=element.getItemname();
//			if(StringUtils.isNotEmpty(eleventTime)){
//				sysoTime=Integer.parseInt(eleventTime);
//			}
//		}
//			SimpleDateFormat df=new SimpleDateFormat("HHmmss");
//			Date date=new Date();
//			String time=df.format(date);
//			System.out.println(time);
//	       int systime= Integer.parseInt(time);
//	       int elevent=Integer.parseInt(eleventTime);
//	       if(systime>elevent){
//	    	   String str=sysoTime+"";
//	    	   if("100000".equals(str)){
//	    		   str="10";
//	    	   }else if("200000".equals(str)){
//	    		   str="20";
//	    	   }else{
//	    		   str=str.replace("0", "");
//	    	   }
//	    	   return str;
//	       }
//	       return "";
//	}
//	
//	/**
//	 * 判断按钮是否能够操作
//	 * pc订餐今日汇总
//	 * 微信今日订餐确认送达
//	 * @return
//	 */
//	public String isCanOperate(){
//		List<Element> elList=elementGroupService.getElementsByGroupName("importTime");
//		String eleventTime="110000";
//		int sysoTime=0;
//		if(elList!=null&&elList.size()>0){
//			Element element=elList.get(0);
//			eleventTime=element.getItemname();
//			if(StringUtils.isNotEmpty(eleventTime)){
//				sysoTime=Integer.parseInt(eleventTime);
//			}
//		}
//		SimpleDateFormat df=new SimpleDateFormat("HHmmss");
//		Date date=new Date();
//		String time=df.format(date);
//		System.out.println(time);
//       int systime= Integer.parseInt(time);
//       int elevent=Integer.parseInt(eleventTime);
//       if(systime>elevent){
//    	   return "";
//       }
//       String str=sysoTime+"";
//	   if("100000".equals(str)){
//		   str="10";
//	   }else if("200000".equals(str)){
//		   str="20";
//	   }else{
//		   str=str.replace("0", "");
//	   }
//	   return str;
//	}

	public String decideParameter(Map<String, String> parament) {
		String str = "";
		if (parament.containsKey("orgId")) {
			String orgId = parament.get("orgId") == null ? "" : parament.get("orgId");
			if (!StringUtil.isNotEmpty(orgId)) {
				str = "抱歉，项目不允许为空，请联系管理员!";
			}
		}
		if (parament.containsKey("userId")) {
			String userId = parament.get("userId") == null ? "" : parament.get("userId");
			if (!StringUtil.isNotEmpty(userId)) {
				str = "抱歉，您还没有登录，请先登录!";
			}
		}
		return str;
	}

	/**
	 * 跳转页面信息初始化
	 * <p>
	 * admin或系统管理员所管辖项目太多,跳转列表页时加载数据太多,所以默认使其选择第一个,
	 * 可通过模糊搜索来查询不同项目信息;
	 *
	 * @param request
	 * @param model
	 */
	public void initPageOrgInfo(HttpServletRequest request, Model model) {
		User         user = (User) request.getSession().getAttribute("UserCache");
		List<OrgDto> dtos = appUserService.getUserOrgs(user.getId());
		model.addAttribute("org", dtos.get(0));
		model.addAttribute("isAdmin", user.isAdmin());
		model.addAttribute("isAdminAndProjectAdmin", user.isAdminAndProjectAdmin());

		// 企业账号相关初始化信息
		if (user.getUserType() == 5) {
			// 设置企业id,名称,项目id
			// 查询企业账号信息
			VirtualAccount      virAccount   = virtualAccountManager.getVirtualAccountByName(user.getUsername());
			VirtualArchitecture architecture = propertyManager.getVirtualArchitectureById(virAccount.getVirId());
			if (virAccount != null) {
				Map virAccountInfo = new HashMap();
				virAccountInfo.put("orgId", dtos.get(0).getId());
				virAccountInfo.put("virId", virAccount.getVirId());
				virAccountInfo.put("virName", architecture.getName());
				virAccountInfo.put("userType", user.getUserType());
				virAccountInfo.put("level", architecture.getLevel());
				if (architecture.getLevel().equals(2)) {
					Map<String, Object> map = propertyManager.getVirtualArchitectureMap(String.valueOf(virAccount.getVirId()));
					if (map != null) {
						virAccountInfo.put("range_id", map.get("range_id"));
						virAccountInfo.put("range_name", map.get("range_name"));
						virAccountInfo.put("relation_id", map.get("relation_id"));
						virAccountInfo.put("relation_name", map.get("relation_name"));
					} else {
						virAccountInfo.put("range_id", null);
						virAccountInfo.put("range_name", null);
						virAccountInfo.put("relation_id", null);
						virAccountInfo.put("relation_name", null);
					}
				}
				model.addAttribute("virAccountInfo", virAccountInfo);
			}
		}
	}

	public Map<String, String> getQuarter(String date) {
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtil.isNotEmpty(date)) {
			String[] dateArr = date.split("-");
			if (dateArr != null && dateArr.length == 2) {
				map.put("year", dateArr[0]);
				map.put("quarter", dateArr[1]);
			}
		}
		return map;
	}

	public String setPath(String fileName) {
		// TODO 自动生成的方法存根
		return null;
	}
	
	public String getRoleIds(User user){
		String roleIds="";
		Set<Role> roles=user.getRoles();
		if(null != roles && roles.size()>0){
			StringBuilder sb=new StringBuilder("");
			for(Role role:roles){
				if(null == role || null == role.getId()){
					continue;
				}
				sb.append(role.getId()+",");
			}
			if(StringUtils.isNotBlank(sb.toString())){
				roleIds=sb.substring(0,sb.length()-1);
			}
		}
		log.info("getRoleIds-roleIds:{}",roleIds);
		return roleIds;
	}
}
