package com.yizhi.application.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.vo.AccountVO;
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.WeChatUserClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.*;

/**
 * 微信登录对接
 *
 * @author lilingye
 * @since 2018-5-10 13:48:46
 */
@RestController
@Api(tags = "获取用户信息和token接口")
@RequestMapping("/wechat")
public class WeiXinController {
    private static final Logger LOGGER = LoggerFactory.getLogger(WeiXinController.class);
    private final static String ZERO = "0";
    private final static String ONE = "1";
    private final static String TWO = "2";
    @Autowired
    private WeChatUserClient weChatClient;
    @Autowired
    private FunctionDisplayConfigApiClients functionClient;
    @Autowired
    private MyItemConfigApiClients myItemConfigApiClients;
    @Autowired
    private MyItemConfigDefaultApiClients myItemConfigDefaultApiClients;
    @Autowired
    private CalendarClient calendarClient;
    @Autowired
    private TokenHelper tokenHelper;
    @Autowired
    private RedisCache redisCache;

    @ApiOperation(value = "查询用户是否在系统中", notes = "查询用户是否在系统中")
    @GetMapping(value = "/get/user")
    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") String appid,
                                              @ApiParam(name = "agentId", value = "机构Id", required = false) @RequestParam(name = "agentId", required = false) String agentId) {
        LOGGER.info("参数wechatUserId:" + wechatUserId + "参数appid：" + appid);
        LOGGER.info("agentId:" + agentId);
        RequestContext context = ContextHolder.get();

        LOGGER.info("wechat 请求站点的上下文：{}", JSON.toJSON(context));
        Map<String, Object> retMap = weChatClient.getWeChatUserInfoToken(wechatUserId, appid, agentId);
        LOGGER.info("返回的数据:{}", retMap);
        if (null != retMap) {
            String returnCode = retMap.get("returnCode").toString();

            if ((ZERO).equals(returnCode)) {
                return Response.fail(ReturnCode.NOT_SITE_ACCESS.getMsg());
            }
            if ((TWO).equals(returnCode)) {
                String msg = retMap.get("msg").toString();
                return Response.fail(msg);
            }

            //生成token
            Object userInfo = retMap.get("userInfo");
            LOGGER.info("map中的用户信息1：{}", userInfo);
            if (userInfo == null) {
                return Response.fail(ReturnCode.NOT_RELATE_ACCOUNT);
            }
            JSONObject jsonObject = (JSONObject) JSON.toJSON(userInfo);
            AccountVO accountVO = JSON.toJavaObject(jsonObject, AccountVO.class);
            LOGGER.info("accountVO中的用户信息1：{}", accountVO);
            LOGGER.info("accountVO中的用户信息2：{}", JSON.toJSON(accountVO));
            context.setAccountId(accountVO.getId());
            String token = generateToken(context.getCompanyCode(), context.getCompanyId(), context.getCompanyName(), accountVO, context.getSiteId());
            retMap.put(GlobalConstant.TOKEN_HEADER, token);
            // 签到打卡是否可见
            retMap.putAll(getEnableSign(context.getSiteId(), accountVO.getId()));
            httpResponse.addHeader(GlobalConstant.TOKEN_HEADER, token);
            ContextHolder.set(context);
            LOGGER.info("返回得到token结果：{}", retMap);

        } else {
            LOGGER.info("当前的微信号未关联系统账号");
            return Response.fail(ReturnCode.NOT_RELATE_ACCOUNT);
        }
        LOGGER.info("最后的结果，{}", retMap);
        return Response.ok(retMap);
    }

    /**
     * 生成token
     *
     * @param companyCode
     * @param companyId
     * @param companyName
     * @param accountVO
     * @param siteId
     * @return
     */
    public String generateToken(String companyCode, Long companyId, String companyName, AccountVO accountVO, Long siteId) {

        Map<String, Object> mapInfo = new HashMap<String, Object>(6);
        mapInfo.put(GlobalConstant.ACCOUNT_ID, accountVO.getId().toString());
        mapInfo.put(GlobalConstant.COMPANY_CODE, companyCode);
        mapInfo.put(GlobalConstant.COMPANY_ID, companyId.toString());
        mapInfo.put(GlobalConstant.COMPANY_NAME, companyName);
        mapInfo.put(GlobalConstant.SITE_ID, siteId.toString());
        LOGGER.info("生成token的参数：{}", JSON.toJSON(mapInfo));
        String token = null;
        try {
            token = tokenHelper.createToken(accountVO.getName(), mapInfo);
        } catch (Exception e) {
            LOGGER.info("生成token的异常：{}", e.getMessage());
        }
        return token;
    }

    /**
     * 打卡方法
     *
     * @param siteId
     * @param accountId
     * @return
     */
    private Map<String, Object> getEnableSign(Long siteId, Long accountId) {
        Map<String, Object> map = new HashMap<>(16);
        try {
            return isEnableSign(siteId, accountId);
        } catch (Exception e) {
            map.put("isEnableSign", 0);
            LOGGER.error("签到服务异常", e);
            return map;
        }
    }

    /**
     * 签到打卡显示查询
     *
     * @param siteId    站点id
     * @param accountId 用户id
     * @return
     */
    public Map<String, Object> isEnableSign(Long siteId, Long accountId) {
        Map<String, Object> map = new HashMap<String, Object>(16);
        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;
    }


}
