package com.reyun.controller;

import com.google.common.collect.Maps;
import com.reyun.dic.LogEnumType;
import com.reyun.dic.RoleEnumType;
import com.reyun.model.*;
import com.reyun.repository.*;
import com.reyun.security.RedisLoginStatusManager;
import com.reyun.security.TokenManager;
import com.reyun.security.annotation.CurrentAccount;
import com.reyun.security.interceptor.AuthorizationInterceptor;
import com.reyun.service.*;
import com.reyun.util.*;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("login")
public class LoginController
{

    protected Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    LoginService loginService;

    @Autowired
    TokenManager tokenManager;

    @Autowired
    AccountRepository accountRepository;

    @Autowired
    UserLogService userLogService;

    @Autowired
    ConfigParamService configParamService;

    @Autowired
    RedisLoginStatusManager redisLoginStatusManager;

    @Autowired
    BussinessManRepository bussinessManRepository;

    @Autowired
    AuthService authService;

    @Autowired
    AccountFlowRestrictService accountFlowRestrictService;


    @Autowired
    PackageTypeRepository packageTypeRepository;

    @RequestMapping(value = "loginweb", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel login(HttpServletRequest request, HttpServletResponse response, @RequestParam String email,
            @RequestParam String password, @RequestParam Boolean isrember, @RequestParam Boolean autologin)
    {

        Map<String, Object> rtnMap = Maps.newHashMap();

        logger.info(email + "is login...");
        Account account = loginService.login(email, password);

        if (account != null) {
            logger.info("login account:" + account.toString());

            if(!account.getRoleCategory().equals(5L)) {
                Boolean trackAndIoBothExhaust = accountFlowRestrictService.isIoExhaust(account.getId());
                Long rootParent = accountRepository.findRootParentByAccountId(account.getId()).longValue();
                Account rootAccount = accountRepository.findOne(rootParent);
                if (trackAndIoBothExhaust) {
                    rtnMap.put("msg", "行为分析流量用尽！");
                    rtnMap.put("code", 211);
                    return ResultModel.OK(rtnMap);
                }
            }

            String nowDate = DateUtil.format(new Date(), DateUtil.C_DATE_PATTON_DEFAULT);

            if (account.getIsSuperUser()) {

                //母账号
                if (account.getStatus() == 0) {
                    //主账号禁用
                    rtnMap.put("msg", "主账号禁用");
                    rtnMap.put("code", 208);
                    return ResultModel.OK(rtnMap);

                } else if (account.getStatus() == -1) {
                    //主账号还没通过审核
                    rtnMap.put("msg", "还没通过审核");
                    rtnMap.put("code", 210);
                    return ResultModel.OK(rtnMap);
                } else if (account.getStatus() == -2) {
                    //主账号还没通过审核
                    rtnMap.put("msg", "还没通过审核");
                    rtnMap.put("code", 210);
                    return ResultModel.OK(rtnMap);
                }

                //主账号过期
                if (!StringUtil.isEmpty(account.getPastDate()) && DateUtil.compare_date(nowDate, account.getPastDate()) == 1) {
                    rtnMap.put("msg", "主账号过期");
                    rtnMap.put("code", 206);
                    return ResultModel.OK(rtnMap);
                }

            }else {

                //子账号
                if (account.getStatus() == 0) {
                    // 子账号禁用
                    rtnMap.put("msg", "子账号禁用");
                    rtnMap.put("code", 203);
                    return ResultModel.OK(rtnMap);

                } else if(!account.getRoleCategory().equals(5L)){

                    //获取根节点母账号
                    Account parent = authService.findRootParentAccount(account.getId());

                    if (parent.getStatus() == 0) {
                        //子账号所在主账号被禁用
                        rtnMap.put("msg", "子账号所在主账号被禁用");
                        rtnMap.put("code", 209);
                        return ResultModel.OK(rtnMap);

                    } else if (!StringUtil.isEmpty(parent.getPastDate()) && DateUtil.compare_date(nowDate, parent.getPastDate()) == 1) {
                        //子账号所在主账号过期
                        rtnMap.put("msg", "子账号所在主账号过期");
                        rtnMap.put("code", 207);
                        return ResultModel.OK(rtnMap);
                    }
                }

                //没有控制权限AuthStr没有授权
                if (!account.getRoleCategory().equals(RoleEnumType.MANAGER.getKey())) {

                    if (!ValidateUtil.isValid(account.getAuthStr()) || !ValidateUtil.isValid(JSONObject.fromObject(account.getAuthStr()))) {

                        rtnMap.put("msg", "没有产品权限");
                        rtnMap.put("code", 202);
                        return ResultModel.OK(rtnMap);
                    }
                }
            }

            //存储token
            String token = tokenManager.createToken(String.valueOf(account.getId()));
            //存储登陆密码
            redisLoginStatusManager.createLoginStatus(token, account.getIsMasterLogin() ? CipherUtil.generatePassword(configParamService.generateMasterPwd()) : account.getPassword());

            if (isrember) {
                Cookie cookie = new Cookie("ryioUpass", password);
                cookie.setPath("/");
                cookie.setMaxAge(60 * 60 * 24 * 7);
                response.addCookie(cookie);
            }
            else {
                Cookie cookie = new Cookie("ryioUpass", "");
                cookie.setPath("/");
                cookie.setMaxAge(0);
                response.addCookie(cookie);
            }

            //自动登录
            Cookie cookie = new Cookie("TOKEN", token);
            cookie.setPath("/");
            cookie.setMaxAge(autologin ? 60 * 60 * 24 * 7 : 60 * 30);
            response.addCookie(cookie);

            rtnMap.put("code", 200);
            rtnMap.put("token", token);
            rtnMap.put("account", account);

            try {
                userLogService.insertLog(account, LogEnumType.LOGIN.getCode(), LogEnumType.LOGIN.getName() + account.getEmail(), account, null, null, request);
            }
            catch (Exception e) {
                logger.error("fail to parse ip," + e.getMessage());
            }
            return ResultModel.OK(rtnMap);
        }
        else {
            // 没有此账号
            rtnMap.put("code", 205);
            rtnMap.put("msg", "用户名或密码不正确");
            return ResultModel.OK(rtnMap);
        }
    }

    /**
     * 获取用户付费等级的各个指标限制
     */
    @RequestMapping(value = "limit", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getLevelLimit(@CurrentAccount Account loginAccount)
    {

        Long level = loginAccount.getPricelevel();
        //EditionPricingLevel levelObject = levelRepository.findOne(level);

        PackageType levelObject = packageTypeRepository.findOne(level);
        EditionPricingLevel4Web webLevel = new EditionPricingLevel4Web(levelObject);

        return ResultModel.OK(webLevel);
    }


    @RequestMapping(value = "logout", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> logout(HttpServletRequest request, HttpServletResponse response, @CurrentAccount Account loginAccount)
    {

        if (loginAccount != null) {

            String token = request.getHeader(AuthorizationInterceptor.httpHeaderName);
            //删除session,token
            request.getSession().removeAttribute(Constant.CURRENT_ACCOUNT);
            tokenManager.delRelationshipByToken(token);
            redisLoginStatusManager.deleteLoginStatus(token);

            Cookie cookie = new Cookie("TOKEN", null);
            cookie.setDomain("trackingio.com");
            cookie.setPath("/");
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("status", 1);

        userLogService.insertLog(loginAccount, LogEnumType.LOGOUT.getCode(), LogEnumType.LOGOUT.getName() + loginAccount.getEmail(), loginAccount, null, null, request);

        return result;
    }

    @RequestMapping(value = "getvalidcode", method = RequestMethod.GET)
    @ResponseBody
    public void getValidateCode(HttpServletRequest request, HttpServletResponse response)
    {

        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        // 禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

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

        HttpSession session = request.getSession();
        session.setMaxInactiveInterval(60);

        ValidateCodeUtil vCode = new ValidateCodeUtil(100, 40, 4, 50, code);
        session.setAttribute("code", vCode.getCode());
        try {
            vCode.write(response.getOutputStream());
        }
        catch (IOException e) {
            logger.error(e.getMessage());
        }
    }

    @RequestMapping(value = "getopenid", method = RequestMethod.GET)
    @ResponseBody
    public String getOpenid(HttpServletRequest request, HttpServletResponse response) {
        String code = request.getParameter("js_code");
        String appId = "wxd7411c633c54c5ab";
        String appSecret = "69834fabd641256ec29b052743616308";
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appId+"&secret="+appSecret+"&grant_type=authorization_code&js_code="+code;
        String responseStr = HttpClientUtil.doHttpGetRequest(url, "");
        return responseStr;
    }
}
