package com.mortals.xhx.base.login.web;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.user.LoginPdu;
import com.mortals.xhx.common.pdu.user.UserPdu;
import com.mortals.xhx.common.utils.MenuEncodeUtil;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.feign.user.IUserFeign;
import com.mortals.xhx.module.access.model.AccessEntity;
import com.mortals.xhx.module.access.model.AccessQuery;
import com.mortals.xhx.module.access.model.AccessSystemEntity;
import com.mortals.xhx.module.access.service.AccessService;
import com.mortals.xhx.module.ph.model.PhQueueStatEntity;
import com.mortals.xhx.module.ph.model.PhQueueStatQuery;
import com.mortals.xhx.module.ph.service.PhQueueStatService;
import com.mortals.xhx.module.pj.model.PjEvaluateStatEntity;
import com.mortals.xhx.module.pj.model.PjEvaluateStatQuery;
import com.mortals.xhx.module.pj.service.PjEvaluateStatService;
import com.mortals.xhx.module.stat.model.StatEntity;
import com.mortals.xhx.module.stat.model.StatQuery;
import com.mortals.xhx.module.stat.service.StatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED;
import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED_CONTENT;

@RestController
@Slf4j
@RequestMapping("login")
public class LoginController extends BaseCRUDJsonBodyMappingController<UserService, UserEntity, Long> implements InitializingBean {

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private IAuthTokenService authTokenService;
    @Autowired
    private IUserFeign userFeign;
    @Autowired
    private StatService statService;
    @Autowired
    private PhQueueStatService phQueueStatService;
    @Autowired
    private PjEvaluateStatService pjEvaluateStatService;
    @Autowired
    private ISiteFeign siteFeign;
    @Autowired
    private AccessService accessService;


    @RequestMapping("login")
    public String login(@RequestBody LoginForm loginForm) throws Exception {

        String loginName = loginForm.getLoginName();
        String password = loginForm.getPassword();
        LoginPdu loginPdu = new LoginPdu();
        loginPdu.setLoginName(loginName);
        loginPdu.setPassword(password);
        loginPdu.setSecurityCode("admin");
        String resp = userFeign.portalLogin(loginPdu);
        return resp;
    }

    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
        recordSysLog(request, "退出登录");
        super.removeCurrUser(request);
    }

    @RequestMapping("index")
    public String index() throws Exception {
        JSONObject ret = new JSONObject();
        IUser user = this.getCurUser();
        if (user == null) {
            return JSONObject.toJSONString(Rest.fail(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT));
        }
        Set<String> urls = resourceService.findUrlSetByUserId(user.getId());
        log.info("userId:{},urls:{}", user.getId(), JSON.toJSONString(urls));
        // List<MenuEntity> outlookBarList = menuService.findTreeMenu(user, urls);

        List<MenuEntity> treeMenuList = menuService.findTreeMenu(user);
        String currUserName = user.getRealName();
        if (currUserName == null || currUserName.trim().length() == 0) {
            currUserName = "管理员";
        }
        JSONObject data = new JSONObject();

        String token = authTokenService.getToken(request);
        data.put("token", token);
        data.put("currUserName", currUserName);
        data.put("menuList", treeMenuList);
        data.put("id", user.getId());
        data.put("userType", user.getUserType());
        ret.put(KEY_RESULT_DATA, data);
        cacheService.hset(RedisKey.KEY_USER_MENU_CACHE, user.getId().toString(), MenuEncodeUtil.generateMenuUrlCode(urls));

        ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
        ret.put(KEY_RESULT_MSG, "用户登录系统成功!");
        ret.put("resources", urls);

        //todo  首页统计报表
        //    int totalAccessSite = 0;
        List<AccessEntity> accessEntities = new ArrayList<>();


        String siteTreeStr = siteFeign.siteTree(token);
        // RedisTemplate<String, String> baseRedisTemplate = cacheService.selectDbRedisTemplate(1);
        //com:mortals:xhx:module:site:model:SiteEntity  redis调用
        //String siteTreeStr = (String) baseRedisTemplate.opsForHash().get("user:site:tree", String.valueOf(user.getId()));
        if (!ObjectUtils.isEmpty(siteTreeStr)) {
            log.info("siteTreeStr:{}", siteTreeStr);
            //获取当前用户所拥有的站点列表
            AccessQuery accessQuery = new AccessQuery();
            // accessQuery.setTagNotList(Arrays.asList(""));
            accessEntities = accessService.find(accessQuery).stream().filter(item -> {
                List<AccessSystemEntity> accessSystemList = item.getAccessSystemList();
                //判断排队机或者评价系统是否开通
                if (ObjectUtils.isEmpty(accessSystemList)) return false;
                List<AccessSystemEntity> collect = accessSystemList.stream().filter(f -> f.getEnabled() == YesNoEnum.YES.getValue()).collect(Collectors.toList());
                if (ObjectUtils.isEmpty(collect)) {
                    return false;
                }
                return true;
            }).collect(Collectors.toList());

            //  totalAccessSite = accessEntities.size();
            if (!ObjectUtils.isEmpty(accessEntities)) {
                //当前用户存在的区域或者站点列表
                //遍历 如果不存在 正则
                Iterator<AccessEntity> iterator = accessEntities.iterator();
                while (iterator.hasNext()) {
                    AccessEntity next = iterator.next();
                    String type = next.getType();
                    if ("area".equals(type)) {
                        boolean contains = StrUtil.contains(siteTreeStr, next.getAreaCode());
                        if (!contains) {
                            iterator.remove();
                        }
                    } else if ("site".equals(type)) {
                        boolean contains = StrUtil.contains(siteTreeStr, next.getSiteCode());
                        if (!contains) {
                            iterator.remove();
                        }
                    } else {
                        log.info("未知类型节点，不做过滤！");
                    }
                }
            }
        }
        data.put("accessList", accessEntities);
        String totalAccessSite = cacheService.get(RedisKey.KEY_SITE_STAT_COUNT_CHCHE);
        String lastStatUpdateTime = cacheService.get(RedisKey.KEY_SITE_STAT_TIME_CHCHE);
        data.put("totalAccessSite", totalAccessSite == null ? 10 : Integer.parseInt(totalAccessSite));
        data.put("lastStatUpdateTime", lastStatUpdateTime == null ? DateUtil.formatDateTime(new Date()) : lastStatUpdateTime);
        int totalCount = 0;
        StatQuery statQuery = new StatQuery();
        statQuery.setGroupList(Arrays.asList("year"));
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPrePageResult(-1);
        List<StatEntity> list = statService.find(statQuery, pageInfo, getContext()).getList();
        if (!ObjectUtils.isEmpty(list)) {
            totalCount = list.stream().mapToInt(i -> i.getCount()).sum();

        }
        data.put("totalCount", totalCount);
        //近三十天数据总量趋势
        getThirtyStats(data);
        getThirtyPhStats(data);
        getThirtyPjStats(data);

        return ret.toJSONString();
    }

    private void getThirtyStats(JSONObject data) {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPrePageResult(-1);
        StatQuery statThirtyQuery = new StatQuery();
        statThirtyQuery.setTimeStart(DateUtil.offsetDay(new Date(), -30).toDateStr());
        statThirtyQuery.setTimeEnd(DateUtil.today());
        statThirtyQuery.setGroupList(Arrays.asList("year", "month", "day"));
        List<StatEntity> thirtyStatList = statService.find(statThirtyQuery, pageInfo, getContext()).getList();
        if (!ObjectUtils.isEmpty(thirtyStatList)) {
            //todo 日期排序趋势降序图
            data.put("thirtyStatList", thirtyStatList);
        } else {
            data.put("thirtyStatList", new ArrayList<>());
        }
    }

    private void getThirtyPhStats(JSONObject data) {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPrePageResult(-1);
        PhQueueStatQuery statThirtyQuery = new PhQueueStatQuery();
        statThirtyQuery.setTimeStart(DateUtil.offsetDay(new Date(), -30).toDateStr());
        statThirtyQuery.setTimeEnd(DateUtil.today());
        statThirtyQuery.setHallNameList(Arrays.asList(""));
        statThirtyQuery.setWindowFromnumList(Arrays.asList(""));
        statThirtyQuery.setSectionNameList(Arrays.asList(""));
        statThirtyQuery.setBusinessList(Arrays.asList(""));
        statThirtyQuery.setGroupList(Arrays.asList("year", "month", "day"));
        List<PhQueueStatEntity> thirtyStatList = phQueueStatService.find(statThirtyQuery, pageInfo, getContext()).getList();
        if (!ObjectUtils.isEmpty(thirtyStatList)) {
            //todo 日期排序趋势降序图
            data.put("thirtyPhStatList", thirtyStatList);
        } else {
            data.put("thirtyPhStatList", new ArrayList<>());
        }
    }

    private void getThirtyPjStats(JSONObject data) {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPrePageResult(-1);
        PjEvaluateStatQuery statThirtyQuery = new PjEvaluateStatQuery();
        statThirtyQuery.setTimeStart(DateUtil.offsetDay(new Date(), -30).toDateStr());
        statThirtyQuery.setTimeEnd(DateUtil.today());
        log.info(statThirtyQuery.getTimeStart() + "---" + statThirtyQuery.getTimeEnd());

        statThirtyQuery.setHallNameList(Arrays.asList(""));
        statThirtyQuery.setWindowFromnumList(Arrays.asList(""));
        statThirtyQuery.setSectionNameList(Arrays.asList(""));
        statThirtyQuery.setPjOptionList(Arrays.asList(""));

        statThirtyQuery.setGroupList(Arrays.asList("year", "month", "day"));
        List<PjEvaluateStatEntity> thirtyStatList = pjEvaluateStatService.find(statThirtyQuery, pageInfo, getContext()).getList();
        if (!ObjectUtils.isEmpty(thirtyStatList)) {
            //todo 日期排序趋势降序图
            data.put("thirtyPjStatList", thirtyStatList);
        } else {
            data.put("thirtyPjStatList", new ArrayList<>());
        }
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("初始化加载登录。。。");
    }
}
