package com.palmnest.webapp.controller.wechat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.AppConstants;
import com.palmnest.application.CodeConstants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.core.util.AppResultUtil;
import com.palmnest.application.core.util.NumberUtils;
import com.palmnest.application.core.util.PropertiesKit;
import com.palmnest.model.InPuchaseUser;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.model.estateserve.SmsAuthCode;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.service.estateserve.AppUserManager;
import com.palmnest.service.estateserve.NeigouManager;
import com.palmnest.service.estateserve.ScWxuserManager;
import com.palmnest.service.estateserve.SmsAuthCodeManager;
import com.palmnest.service.wechat.WeChatApiManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Author hxt
 * @Description 服务之窗-企业内购;此控制器针对在公众号菜单处配置的企业内购入口;
 * @Date 2019/3/5 11:39
 **/
@Slf4j
@Controller
@RequestMapping(value = "/wechat/newneigou*")
public class NeigouNweController {


	@Autowired
	private WeChatApiManager   weChatApiManager;
	@Autowired
	private NeigouManager      neigouManager;
	@Autowired
	private AppUserManager     appUserManager;
	@Autowired
	private SmsAuthCodeManager smsAuthCodeManager;
	@Autowired
	private ScWxuserManager    scWxuserManager;

	/**
	 * 内购模块,cookie的key值
	 */
	public static final String NEIGOU_OPENID = "neigouOpenid";

	/**
	 * 新 跳转企业内购页面
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/indexPage")
	public ModelAndView indexPage(HttpServletRequest request) throws Exception {
		Model model = new ExtendedModelMap();

		String userId     = request.getParameter("userId");
		String userMobile = request.getParameter("userMobile");// 用户手机号
		String virId      = request.getParameter("virId");// 企业id
		String orgId      = request.getParameter("orgId");// 项目id
		String openId     = request.getParameter("openId");// openId

        /*if (StringUtils.isAnyBlank(userId,userMobile,virId,orgId)){
            // 去错误提示页面
            model.addAttribute("errorMsg","/indexPage,跳转企业内购首页出错");
            return new ModelAndView("wechat/enterprisePurchase/neigouErrorPage",model.asMap());
        }*/

		if (StringUtils.isAnyBlank(userId, userMobile, virId, orgId)) {
			// 去错误提示页面
			model.addAttribute("errorMsg", "/indexPage,跳转企业内购首页失败！请请联系客服人员");
			log.error("跳转企业内购失败： userId=" + userId + " userMobile=" + userMobile + " virId=" + virId + " orgId=" + orgId);
			return new ModelAndView("wechat/enterprisePurchase/neigouErrorPage", model.asMap());
		}

		log.info("NeigouNweController indexPage ====> userId:{},userMobile:{},virId:{},orgId:{}", userId, userMobile, virId, orgId);

		String redirectUrl = PropertiesKit.readPropertiesValue("innerShoppingMall", "wechat.properties");

		//设置用户的wxUser-openId
		WxUser wxUser = scWxuserManager.getScWxuserByOpenId(openId);
		if (wxUser != null) {
			AppUser appUser = appUserManager.get(Integer.parseInt(userId));
			appUser.setWxUserId(wxUser.getId());
			appUser.setModifyTime(new Date());
			appUserManager.updateModel(appUser);
		}
		// 参数拼接
		if (redirectUrl.indexOf("?") != -1) {
			redirectUrl += "&userMobile=" + userMobile + "&core_enterprise=" + virId + "&core_organization=" + orgId + "&core_user=" + userId;
		} else {
			redirectUrl += "?userMobile=" + userMobile + "&core_enterprise=" + virId + "&core_organization=" + orgId + "&core_user=" + userId;
		}

		log.info("redirectUrl:" + redirectUrl);

		model.addAttribute("redirectFullUrl", redirectUrl);
		return new ModelAndView("wechat/toWechatAuth", model.asMap());
	}


	/**
	 * 公众号菜单点击企业内购
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/index")
	public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception {

		String openId    = "";
		String developId = "";

		// 判断当前会话中是否存在openid和state的cookie
		Cookie cookie = getCookieByName(request, NEIGOU_OPENID);
		if (Objects.isNull(cookie)) {
			// 如果不存在该cookie,则走微信授权获取用户openid与state,并将cookie写入网页端
			// 公众号网页授权返回code,用于换取access_token
			String code = request.getParameter("code");
			// 自定义参数,这里传公众号id,用于获取该公众号配置信息 appid和secret
			String state = request.getParameter("state");
			// 通过code换取网页授权access_token; 获取到用户信息如下
			Map<String, String> retMap = weChatApiManager.oauth2(code, state);
			Map<String, Object> map    = JSON.parseObject(retMap.get("jsonStr"), Map.class);

			openId = map == null ? "" : map.get("openid") == null ? "" : map.get("openid").toString();
			developId = retMap.get("developid");

			// 将cookie写回客户端
			String cookieStr = openId.concat(";").concat(developId).concat(";");
			log.info("NeigouNweController index ===========>openId:{},developId:{},cookieStr:{}", openId, developId, cookieStr);
			Cookie newCookie = new Cookie(NEIGOU_OPENID, cookieStr);
			newCookie.setMaxAge(60 * 60 * 24);
			response.addCookie(newCookie);
		} else {
			// 如果存在该cookie,则直接获取
			String   cookieValue = cookie.getValue();
			String[] strings     = cookieValue.split(";");
			openId = strings[0];
			developId = strings[1];
		}

		Model model = new ExtendedModelMap();
		try {
			if (StringUtils.isAnyBlank(openId)) {
				// 获取不到当前用户信息;去登录页面;
				return new ModelAndView("wechat/enterprisePurchase/loginPage", model.asMap());
			}

			log.info("NeigouNweController index ===> openId:{},developId:{}", openId, developId);

			// 首先验证当前用户是否登录,如果未登录,则跳转登录页;
			InPuchaseUser puchaseUser = neigouManager.getPuchaseUser(openId, developId, null);

			model.addAttribute("openId", openId);
			model.addAttribute("developId", developId);
			if (Objects.isNull(puchaseUser)) {
				// 去登录页面
				return new ModelAndView("wechat/enterprisePurchase/loginPage", model.asMap());
			}
			model.addAttribute("userMobile", puchaseUser.getMobile());

			// 如果已经登录企业购,则直接进企业列表页
			return new ModelAndView("wechat/enterprisePurchase/selectCompanyPage", model.asMap());
		} catch (Exception e) {
			e.printStackTrace();
			log.error("NeigouNweController index 微信端通过code换取网页授权access_token异常===>", e.getMessage());
			// 去错误提示页面
			model.addAttribute("errorMsg", "/index");
			return new ModelAndView("wechat/enterprisePurchase/neigouErrorPage", model.asMap());
		}
	}

	/**
	 * 根据名字获取cookie
	 *
	 * @param request
	 * @param name    cookie名字
	 * @return
	 */
	public Cookie getCookieByName(HttpServletRequest request, String name) {
		Map<String, Cookie> cookieMap = readCookieMap(request);
		if (cookieMap.containsKey(name)) {
			Cookie cookie = (Cookie) cookieMap.get(name);
			return cookie;
		} else {
			return null;
		}
	}

	/**
	 * 将cookie封装到Map里面
	 *
	 * @param request
	 * @return
	 */
	private Map<String, Cookie> readCookieMap(HttpServletRequest request) {
		Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
		Cookie[]            cookies   = request.getCookies();
		if (null != cookies) {
			for (Cookie cookie : cookies) {
				cookieMap.put(cookie.getName(), cookie);
			}
		}
		return cookieMap;
	}

	/**
	 * 根据用户手机号去查询用户关联的所有企业列表,带排序
	 *
	 * @return
	 */
	@RequestMapping(value = "/companyList")
	@ResponseBody
	public AppResultDto companyList(@RequestParam(required = false) String userMobile,
									@RequestParam(required = false) String virName) {

		if (StringUtils.isBlank(userMobile)) {
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "手机号码有误");
		}

		try {
			// 查询当前登录用户手机号所绑定的所有企业列表;支持企业名称模糊查询;
			List<Map<String, Object>> companySortList = neigouManager.getCompanyListByMobile(userMobile, virName);
			return AppResultUtil.createSuccesDto(companySortList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("NeigouNweController companyList =====>", e.getMessage());
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "获取企业列表失败");
		}

	}


	/**
	 * 企业内购获取短信验证码
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getNeiGouSmsCode")
	@ResponseBody
	public AppResultDto getNeiGouSmsCode(HttpServletRequest request) {

		String mobile = request.getParameter("userMobile");
		log.info("企业内购获取短信验证码 :NeigouNweController getNeiGouSmsCode userMobile:{}", mobile);

		if (StringUtils.isAnyBlank(mobile)) {
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "手机号有误");
		}

		try {
			// 校验是否白名单用户
			List<AppUser> users = appUserManager.getWhiteUserByMobile(mobile);
			if (CollectionUtils.isEmpty(users)) {
				log.warn("==== 当前手机号不是白名单用户 === 或者该白名单用户所属项目未在当前公众号下绑定 ===");
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "该手机号权限不足，请联系管理员");
			}
			//生成验证码
			String code    = NumberUtils.getValidateCode();
			String content = "您的验证码为" + code + "，15分钟内有效，如非本人操作，请忽略。";

			// 发送短信;由于从公众号菜单处登录,取不到项目信息,所以使用公用短信账号; 公用短信账号项目id设置为 0,需手动去数据库添加
			String result = smsAuthCodeManager.smsSendByOrgId("0", content, mobile, code, CodeConstants.SMS_CODE_TYPE);
			if ("Success".equals(result)) {
				return AppResultUtil.createSuccesDto();
			} else if ("3".equalsIgnoreCase(result)) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "该项目下未配置短信账号");
			} else {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "验证码发送失败");
			}
		} catch (Exception e) {
			log.info("NeigouNweController getNeiGouSmsCode获取验证码异常=======>" + e.getMessage());
		}

		return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "验证码发送失败");
	}


	/**
	 * 企业内购用户登录
	 *
	 * @return
	 */
	@RequestMapping("/neigouLogin")
	@ResponseBody
	public AppResultDto neigouLogin(HttpServletRequest request) {
		JSONObject object = new JSONObject();

		String openId    = "";
		String developId = "";
		Cookie cookie    = getCookieByName(request, NEIGOU_OPENID);
		if (Objects.isNull(cookie)) {
			openId = request.getParameter("openId");
			developId = request.getParameter("developId");
		} else {
			String cookieValue = cookie.getValue();
			log.info("NeigouNweController neigouLogin ===========>cookieValue:{}", cookieValue);
			String[] strings = cookieValue.split(";");
			openId = strings[0];
			developId = strings[1];
		}


		String mobile     = request.getParameter("userMobile");
		String mobileCode = request.getParameter("mobileCode");

		log.info("企业内购 :NeigouNweController puchaseLogin ===> openId--:{},mobile--:{},mobileCode--:{},developId--:{}", openId, mobile, mobileCode, developId);

		if (StringUtils.isAnyBlank(openId, mobile, developId, mobileCode)) {
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "参数为空");
		}

		SmsAuthCode smsAuthCode = smsAuthCodeManager.getSmsAuthCode(mobile, mobileCode, "1", 15);
		if (smsAuthCode == null) {
			return AppResultUtil.createErrorDto(AppConstants.AUTH_CODE_ERROR, "验证码不正确");
		}

		try {
			neigouManager.newNeigouLogin(openId, developId, mobile);
			object.put("openId", openId);
			object.put("userMobile", mobile);
			object.put("developId", developId);
			return AppResultUtil.createSuccesDto(object);
		} catch (Exception e) {
			log.error("NeigouNweController neigouLogin异常===========>" + e.getMessage());
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "登陆失败");
		}
	}

	/**
	 * 企业内购退出登录
	 *
	 * @return
	 */
	@RequestMapping("/quitLogin")
	@ResponseBody
	public AppResultDto quitLogin(HttpServletRequest request) {

		String openId = "";
		Cookie cookie = getCookieByName(request, NEIGOU_OPENID);
		if (Objects.isNull(cookie)) {
			openId = request.getParameter("openId");
		} else {
			String cookieValue = cookie.getValue();
			log.info("NeigouNweController quitLogin ===========>cookieValue:{}", cookieValue);
			String[] strings = cookieValue.split(";");
			openId = strings[0];
		}


		String mobile = request.getParameter("userMobile");

		log.info("企业内购 :NeigouNweController quitLogin ===> openId--:{},mobile--:{}", openId, mobile);

		if (StringUtils.isAnyBlank(openId, mobile)) {
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "参数为空");
		}

		try {
			neigouManager.quitNeigouLogin(openId, mobile);
			return AppResultUtil.createSuccesDto();
		} catch (Exception e) {
			log.error("NeigouNweController quitLogin异常===========>" + e.getMessage());
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "退出失败");
		}
	}

	/**
	 * 企业列表页
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/selectPage")
	public ModelAndView selectPage(HttpServletRequest request, HttpServletResponse response) {

		Model model = new ExtendedModelMap();

		String userMobile = request.getParameter("userMobile");

		// 企业内购跳转过来有可能丢失cookie参数,丢失openid,需要重新授权;此时需要去数据库查询记录;
		Cookie cookie = getCookieByName(request, NEIGOU_OPENID);
		if (Objects.isNull(cookie)) {

			InPuchaseUser user = neigouManager.getPuchaseUser(userMobile);

			// 将cookie写回客户端
			String cookieStr = user.getOpenId().concat(";").concat(user.getDevelopId()).concat(";");
			Cookie newCookie = new Cookie(NEIGOU_OPENID, cookieStr);
			newCookie.setMaxAge(60 * 60 * 24);
			response.addCookie(newCookie);
		}

		model.addAttribute("userMobile", userMobile);

		return new ModelAndView("wechat/enterprisePurchase/selectCompanyPage", model.asMap());
	}

	@RequestMapping(value = "/loginPage")
	public ModelAndView loginPage(HttpServletRequest request) {
		Model model = new ExtendedModelMap();
		return new ModelAndView("wechat/enterprisePurchase/loginPage", model.asMap());
	}

	/**
	 * 退出登录页
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/quitPage")
	public ModelAndView quitPage(HttpServletRequest request) {
		Model  model      = new ExtendedModelMap();
		String userMobile = request.getParameter("userMobile");

		model.addAttribute("userMobile", userMobile);
		return new ModelAndView("wechat/enterprisePurchase/quitPage", model.asMap());
	}

	@RequestMapping(value = "/aboutPage")
	public ModelAndView aboutPage() {
		return new ModelAndView("wechat/enterprisePurchase/about");
	}
}
