package com.yizhi.application.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.yizhi.application.wechat.utils.WechatInfoService;
import com.yizhi.calendar.application.feign.CalendarClient;
import com.yizhi.calendar.application.vo.CalendarVO;
import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.core.application.token.TokenHelper;
import com.yizhi.site.application.enums.FunctionTypeCode;
import com.yizhi.site.application.feign.api.FunctionDisplayConfigApiClients;
import com.yizhi.site.application.feign.api.MyItemConfigApiClients;
import com.yizhi.site.application.feign.api.MyItemConfigDefaultApiClients;
import com.yizhi.site.application.vo.domain.FunctionDisplayConfigVo;
import com.yizhi.site.application.vo.site.MyItemConfigVO;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.system.remote.CompanyClient;
import com.yizhi.system.application.system.remote.LoginLogClient;
import com.yizhi.system.application.system.remote.SiteClient;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.system.application.vo.CompanyVO;
import com.yizhi.system.application.vo.LoginLogAddReqVO;
import com.yizhi.system.application.vo.domain.Account;
import com.yizhi.util.application.constant.GlobalConstant;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.Response;
import com.yizhi.wechat.application.feign.WeiXinClient;
import com.yizhi.wechat.application.vo.wechat.WeChatUserVO;
import com.yizhi.wechat.application.vo.wechat.domain.PublicPlatformConfigVo;
import com.yizhi.wechat.application.vo.wechat.domain.TrAccountUserinfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信登录对接
 * @since 2018-5-10 13:48:46
 * @author lilingye
 */
@RestController
@Api(tags = "获取用户信息和token接口")
//@CrossOrigin
@RequestMapping("/wechat")
public class WechatLoginController {
    private static final Logger LOGGER = LoggerFactory.getLogger(WechatLoginController.class);
    @Autowired
    private WeiXinClient weiXinClient;
    @Autowired
    private TokenHelper tokenHelper;

    @Autowired
    private AccountClient accountClient;

    @Autowired
    private CompanyClient companyClient;

    @Autowired
    private SiteClient siteClient;

    @Autowired
    LoginLogClient loginLogClient;

    @Autowired
    WechatInfoService wechatInfoService;

	@Autowired
    FunctionDisplayConfigApiClients functionClient;
    @Autowired
    private MyItemConfigApiClients myItemConfigApiClients;
    @Autowired
    private MyItemConfigDefaultApiClients myItemConfigDefaultApiClients;
    @Autowired
    private CalendarClient calendarClient;

    @Value("${wechat.account.initializtion.pwd}")
    private String password;

    @Autowired
    private RedisCache redisCache;

    @ApiOperation(value = "查询用户是否在系统中", notes = "查询用户是否在系统中")
    @GetMapping(value = "/get/user/test")
    public Response<String> queryUserInWechat(HttpServletResponse httpResponse,
                                              @ApiParam(name = "wechatUserId", value = "用户openid", required = true)
                                              @RequestParam(name = "wechatUserId", required = true) String wechatUserId,
                                              @ApiParam(name = "appid", value = "公众号的APPID或者是企业服务号的CorpID", required = true)
                                              @RequestParam(name = "appid",required = true) String appid,
                                              @ApiParam(name = "agentId", value = "机构Id", required = false) @RequestParam(name = "agentId",required = false) String agentId) {



        LOGGER.info("参数wechatUserId:"+wechatUserId+"参数appid："+appid);

        RequestContext context = ContextHolder.get();
        LOGGER.info("微信接口上下文的信息1：{}",context);
        LOGGER.info("微信接口上下文的信息2：{}", JSON.toJSON(context));
        //获取企业的信息
        CompanyVO companyVO = companyClient.findByCode(context.getCompanyCode());
        //获取用户绑定信息
        TrAccountUserinfoVo trAccountUserinfo = weiXinClient.queryUserInWechat(wechatUserId,companyVO.getId());

        // 封装统计登录的参数
        LoginLogAddReqVO loginLogAddReqVO = new LoginLogAddReqVO();
        loginLogAddReqVO.setCompanyId(companyVO.getId());
        loginLogAddReqVO.setSiteId(context.getSiteId());
        loginLogAddReqVO.setType(3);


        //判断条件
        if (trAccountUserinfo != null) {
            // modify @ 2018年12月28日16:00:16
            //判断企业用户 企业用户更新信息
            if (StringUtils.isNotBlank(agentId)){
                Map<String, String> map = new HashMap<String,String>();
                map.put("appid",appid);
                map.put("agentId",agentId);
                map.put("accountId",trAccountUserinfo.getAccountId().toString());
                map.put("wechatUserId",wechatUserId);

                wechatInfoService.execute(map,true);
            }

            loginLogAddReqVO.setAccountId(trAccountUserinfo.getAccountId());
            LOGGER.info("该微信用户已经绑定未木云账号：" + trAccountUserinfo.getAccountId());


            // 判断该用户是是否有 站点的访问权限
            if (getSiteAuthorize(trAccountUserinfo.getAccountId(),context.getSiteId(),companyVO.getId())) {
                // 有站点访问权限

                if(trAccountUserinfo.getSiteId()==null){
                    trAccountUserinfo.setSiteId(context.getSiteId());
                    weiXinClient.updateUserInWechat(trAccountUserinfo);
                }

                //如果用户存在微服务系统中
                //生成token
                //获取用户信息
                AccountVO accountVO = accountClient.findById(trAccountUserinfo.getAccountId());


                Map<String, Object> info = new HashMap<String, Object>();

                info.put(GlobalConstant.ACCOUNT_ID, trAccountUserinfo.getAccountId().toString());

                info.put(GlobalConstant.COMPANY_CODE, context.getCompanyCode());
                info.put(GlobalConstant.COMPANY_ID, companyVO.getId().toString());
                info.put(GlobalConstant.COMPANY_NAME, companyVO.getName());
                info.put(GlobalConstant.SITE_ID, context.getSiteId().toString());
                LOGGER.info("companyCode:" + context.getCompanyCode() + ",COMPANY_ID" + companyVO.getId().toString() + ",CompanyName:" + context.getCompanyName());


                context.setAccountId(trAccountUserinfo.getAccountId());
                //生成token
                String token = tokenHelper.createToken(accountVO.getName(), info);
                Map<String, Object> retMap = new HashMap<>();
                try {
					retMap.putAll(isEnableSign(context.getSiteId(), accountVO.getId()));
				} catch (Exception e1) {
					LOGGER.error("服务异常",e1);
					retMap.put("isEnableSign", 0);
				}
                // 统计登录调用接口
                    loginLogAddReqVO.setOrgId(accountVO.getOrgId());
                try {
                    loginLogClient.addLoginLog(loginLogAddReqVO);
                } catch (Exception e) {
                    e.printStackTrace();
                }


                httpResponse.addHeader(GlobalConstant.TOKEN_HEADER, token);
                retMap.put(GlobalConstant.TOKEN_HEADER, token);
                retMap.put("userInfo", accountVO);
                ContextHolder.set(context);
                //返回用户信息和token
                return Response.ok(retMap);
            } else {
                return Response.fail(ReturnCode.NOT_SITE_AUTH.getCode(),ReturnCode.NOT_SITE_AUTH.getMsg());
            }
        } else {
            // 不存在账号
            LOGGER.info("该微信的wechatUserId:"+wechatUserId+"未绑定未木云的系统账号");

            PublicPlatformConfigVo publicPlatformConfig = weiXinClient.getPlatformconfig(appid,agentId);
            // 企业用户微信和 类型为自动新增
            if ("0".equals(publicPlatformConfig.getType())&&publicPlatformConfig.getIsAddedUser() == 1) {
                // 查询未木云系统中是否存在此企业和用户名的用户
                AccountVO userInfo = accountClient.findUser(wechatUserId,companyVO.getId());

                //生成token
                Map<String, Object> retMap = new HashMap<>();
                if (userInfo!=null) {

                    loginLogAddReqVO.setAccountId(userInfo.getId());
                    LOGGER.info(wechatUserId+" exist in system!!!!!");
                    //系统中存在用户自动建立关联关系
                    LOGGER.info("参数"+wechatUserId+"；用户id："+userInfo.getId()+"站点id："+context.getSiteId()+";公司companyId："+context.getCompanyId());
                    weiXinClient.saveTrAccountUserinfo(wechatUserId,userInfo.getId(),context.getSiteId(),companyVO.getId(),1);

                    //生成token
                    Map<String, Object> info = new HashMap<String, Object>();
                    info.put(GlobalConstant.ACCOUNT_ID, userInfo.getId().toString());
                    info.put(GlobalConstant.COMPANY_CODE, context.getCompanyCode());
                    info.put(GlobalConstant.COMPANY_ID, companyVO.getId().toString());
                    info.put(GlobalConstant.COMPANY_NAME, companyVO.getName());
                    info.put(GlobalConstant.SITE_ID,context.getSiteId().toString());

                    context.setAccountId(userInfo.getId());
                    String token = tokenHelper.createToken(userInfo.getName(), info);
                    // 统计登录调用接口
                    try {
    					retMap.putAll(isEnableSign(context.getSiteId(), userInfo.getId()));
    				} catch (Exception e1) {
    					LOGGER.error("服务异常",e1);
    					retMap.put("isEnableSign", 0);
    				}
                    try {
                        loginLogAddReqVO.setOrgId(userInfo.getOrgId());
                        loginLogClient.addLoginLog(loginLogAddReqVO);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }


                    httpResponse.addHeader(GlobalConstant.TOKEN_HEADER, token);
                    retMap.put(GlobalConstant.TOKEN_HEADER, token);
                    retMap.put("userInfo", userInfo);
                    retMap.put("siteId",context.getSiteId().toString());
                    ContextHolder.set(context);
                } else {
                    // 系统中不存在用户
                    LOGGER.info("there are no username is"+wechatUserId+" in system!");
                    String accessToken = weiXinClient.getChatAccessToken(publicPlatformConfig);
                    LOGGER.info("获取当前的accessToken："+accessToken);
                    // 查询用户的信息
                    WeChatUserVO weChatUserVO = weiXinClient.getWechatUser(accessToken,wechatUserId);

                    Account account = null;
                    if (weChatUserVO!=null) {
                        // 新增用户和用户对应的组织
                        com.yizhi.system.application.vo.WeChatUserVO systemWeChatUserVo = new com.yizhi.system.application.vo.WeChatUserVO();
                        BeanUtils.copyProperties(weChatUserVO,systemWeChatUserVo);
                        account = accountClient.saveUser(systemWeChatUserVo);
                    }


                    AccountVO accountVO = new AccountVO();
                    BeanUtils.copyProperties(account,accountVO);
                        if (account != null) {
                            try {
                                // 生成站点访问权限
                                Boolean b = siteClient.relateAccountSite(context.getSiteId(),account.getId(),context.getCompanyCode());
                                LOGGER.info("访问权限生成::"+b );

                                // 新增用戶微信关联
                                weiXinClient.saveTrAccountUserinfo(wechatUserId,accountVO.getId(),context.getSiteId(),companyVO.getId(),1);
                                LOGGER.info("企业微信用户的关联已经生成。");

                            } catch (Exception e) {
                                LOGGER.info(e.toString());
                            }
                            LOGGER.info("访问权限生成.");


                            //生成token
                            Map<String, Object> info = new HashMap<String, Object>();
                            info.put(GlobalConstant.ACCOUNT_ID, accountVO.getId().toString());
                            info.put(GlobalConstant.COMPANY_CODE, context.getCompanyCode());
                            info.put(GlobalConstant.COMPANY_ID, companyVO.getId().toString());
                            info.put(GlobalConstant.COMPANY_NAME, companyVO.getName());
                            info.put(GlobalConstant.SITE_ID,context.getSiteId().toString());

                            context.setAccountId(account.getId());
                            String token = tokenHelper.createToken(account.getName(), info);
                            // 统计登录调用接口
                            try {
            					retMap.putAll(isEnableSign(context.getSiteId(), accountVO.getId()));
            				} catch (Exception e1) {
            					LOGGER.error("服务异常",e1);
            					retMap.put("isEnableSign", 0);
            				}
                            try {
                                loginLogAddReqVO.setOrgId(account.getOrgId());
                                loginLogAddReqVO.setAccountId(account.getId());
                                loginLogClient.addLoginLog(loginLogAddReqVO);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            httpResponse.addHeader(GlobalConstant.TOKEN_HEADER, token);
                            retMap.put(GlobalConstant.TOKEN_HEADER, token);
                            retMap.put("siteId",context.getSiteId().toString());
                            retMap.put("userInfo", accountVO);
                            ContextHolder.set(context);
                    }
                }
                return Response.ok(retMap);
            } else {
                LOGGER.info("当前的微信号未关联系统账号");
                return Response.fail(ReturnCode.NOT_RELATE_ACCOUNT.getCode(),ReturnCode.NOT_RELATE_ACCOUNT.getMsg());
            }
        }
    }

    /**
     * 判断站点是否有权
     * @param siteId
     * @return
     */
    public Boolean getSiteAuthorize(Long accountId, Long siteId,Long companyId){
            Boolean f =false;
        try {
            if (siteClient.isAccessToSite(accountId,siteId,companyId)) {
                f = true;
            } else {
                f = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info(e.toString());
        }
        return f;
    }

	/**
	 * 签到打卡显示查询
	 * @param siteId
	 * @param accountId
	 * @return
	 */
	public Map<String, Object> isEnableSign(Long siteId,Long accountId){
		Map<String,Object> map = new HashMap<String, Object>();
        List<Integer> terminalType = new ArrayList<>();
        terminalType.add(2);
        terminalType.add(3);
		List<FunctionDisplayConfigVo> list = functionClient.getBySiteId(siteId);
        List<MyItemConfigVO> voList = myItemConfigApiClients.queryByAuthoity(terminalType);
        CalendarVO calendar = calendarClient.getCalendar();
		map.put("isEnableSign", 0);
		map.put("isPCEnableSign", 0);
		map.put("isAPPEnableSign", 0);
        if (calendar!=null) {
			map.put("isEnableSign", calendar.getState());
			if (calendar.getState()==1) {
		        SimpleDateFormat format = new SimpleDateFormat("yyyMMdd");
				Date date = new Date();
				if (redisCache.exists(format.format(date)+accountId+siteId)) {
					map.put("isFirstLogin", 0);
				}else {
					redisCache.hset(format.format(date)+accountId+siteId, format.format(date)+accountId+siteId, "0", 86500l);
					map.put("isFirstLogin", 1);
				}
			}
		}else {
			map.put("isFirstLogin", 0);
		}
        //如果我的配置表没有数据，取默认表里的数据
        if (CollectionUtils.isEmpty(voList)){
            voList = myItemConfigDefaultApiClients.queryByAuthoity(terminalType);
        }
		if (!CollectionUtils.isEmpty(list)) {
			LOGGER.info("签到打卡PC端显示配置"+list.toString());
			for(FunctionDisplayConfigVo config:list) {
				if (config.getFunctionType().equals(FunctionTypeCode.SIGN.getCode())&&config.getShowDisplay()) {
					map.put("isPCEnableSign", 1);
				}
			}
		}
		if (!CollectionUtils.isEmpty(voList)) {
			LOGGER.info("签到打卡移动端显示配置"+voList.toString());
			for(MyItemConfigVO vo:voList) {
				if (vo.getItemType()==15&&vo.getShowable()==1) {
					map.put("isAPPEnableSign", 1);
				}
			}
		}
		return map;
	}
}
