package com.reyun.controller.manage;

import com.reyun.dic.LogEnumType;
import com.reyun.dic.OperateObjectEnumType;
import com.reyun.dic.RoleEnumType;
import com.reyun.model.Account;
import com.reyun.model.RoleAuth;
import com.reyun.repository.AuthRepository;
import com.reyun.security.annotation.CurrentAccount;
import com.reyun.service.AuthService;
import com.reyun.service.UserLogService;
import com.reyun.util.DateUtil;
import com.reyun.util.IPAddrUtil;
import com.reyun.util.ResultModel;
import com.reyun.util.ResultStatus;
import com.reyun.util.StringUtil;
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.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
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.HttpServletRequest;

import java.util.Date;

@Controller
@RequestMapping("/mng/auth")
public class MngAuthController {

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

    private static final int CUSTOM_ROLE_NAME_LENGTH = 8;

    private static final int STATUS_INACTIVATE = -3;

    @Autowired
    private AuthService authService;

    @Autowired
    private UserLogService userLogService;

    @Autowired
    private AuthRepository authRepository;


    /**
     * 查询所有的非管理员和子应用管理员的子账号和渠道账号。
     */
    @RequestMapping(value = "find/{appId}", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllSubAccountAndChannel(@CurrentAccount Account loginAccount, @PathVariable Long appId) {
        return ResultModel.OK(authService.getAuthorizedSubAndChannelAccount(loginAccount, appId));
    }

    @RequestMapping(value = "findchannel/{appId}/{channel}", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllCampaignAccountByAppChannel(@PathVariable Long appId, @PathVariable Long channel) {
        return ResultModel.OK(authRepository.findAllcampaignAccountByChanelApp(appId, channel));
    }


    /**
     * 根据角色查询菜单权限
     * roleId 1:管理员,2:子应用管理员,N:自定义角色,5:渠道人员
     */
    @RequestMapping(value = "{roleId}/findMenu", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllMenuByRole(@CurrentAccount Account loginAccount, @PathVariable Long roleId) {
        return ResultModel.OK(authService.getMenuAthByRole(loginAccount, roleId));
    }

    /**
     * 查询所有的自定义角色
     */
    @RequestMapping(value = "role/find", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllCustomRoleList(@CurrentAccount Account loginAccount) {
        return ResultModel.OK(authService.getAllCustomRoleList(loginAccount));
    }

    /**
     * 查询单个子账号信息
     * created by sunhao 20170605
     */
    @RequestMapping(value = "{subAccountId}/find", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getSubAccountById(@CurrentAccount Account loginAccount, @PathVariable Long subAccountId) {
        return ResultModel.OK(authService.getSubAccountById(loginAccount, subAccountId));
    }

    /**
     * 查询所有启用子账户信息
     * created by sunhao 20170605
     */
    @RequestMapping(value = "list/enable", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllActiveSubAccount(@CurrentAccount Account loginAccount) {

        userLogService.insertLog(loginAccount, LogEnumType.FIND.getCode(), LogEnumType.FIND.getName() + "启用状态子用户列表", null,
                null, OperateObjectEnumType.ACCOUNT.getCode());

        return ResultModel.OK(authService.getAllActiveSubAccount(loginAccount));

    }

    /**
     * 查询所有停用子账户信息
     * created by sunhao 20170605
     */
    @RequestMapping(value = "list/disable", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel getAllDisableSubAccount(@CurrentAccount Account loginAccount) {

        userLogService.insertLog(loginAccount, LogEnumType.FIND.getCode(), LogEnumType.FIND.getName() + "停用状态子用户列表", null,
                null, OperateObjectEnumType.ACCOUNT.getCode());

        return ResultModel.OK(authService.getAllDisableSubAccount(loginAccount));
    }

    /**
     * 启用子账号
     * created by sunhao 20170605
     */
    @RequestMapping(value = "{subAccountId}/enable", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel enableSubAccount(HttpServletRequest request, @CurrentAccount Account loginAccount, @PathVariable Long subAccountId) {

        userLogService.insertLog(loginAccount, LogEnumType.UPDATE.getCode(), LogEnumType.UPDATE.getName() + "启用子账号", authService.getSubAccountInfo(subAccountId),
                null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.enableSubAccountById(loginAccount, subAccountId));
    }

    /**
     * 禁用子账号
     * created by sunhao 20170605
     */
    @RequestMapping(value = "{subAccountId}/disable", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel disableSubAccount(HttpServletRequest request, @CurrentAccount Account loginAccount, @PathVariable Long subAccountId) {

        userLogService.insertLog(loginAccount, LogEnumType.UPDATE.getCode(), LogEnumType.UPDATE.getName() + "禁用子账号", authService.getSubAccountInfo(subAccountId),
                null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.disableSubAccountById(loginAccount, subAccountId));
    }

    /**
     * 删除未激活的子账号
     * created by sunhao 20170609
     */
    @RequestMapping(value = "{subAccountId}/delete", method = RequestMethod.DELETE)
    @ResponseBody
    public ResultModel deleteSubAccount(HttpServletRequest request, @CurrentAccount Account loginAccount, @PathVariable Long subAccountId) {

        userLogService.insertLog(loginAccount, LogEnumType.UPDATE.getCode(), LogEnumType.DELETE.getName() + "子账号", authService.getSubAccountInfo(subAccountId),
                null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.deleteInactivateSubAccount(subAccountId));
    }

    /**
     * 创建子账号
     * created by sunhao 20170606
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel createSubAccount(HttpServletRequest request, @CurrentAccount Account loginAccount, @RequestBody Account subAccount) {

        //校验参数
        if (StringUtil.isEmpty(subAccount.getEmail()) || StringUtil.isEmpty(subAccount.getName()) || null == subAccount.getRoleCategory()) {
            return ResultModel.ERROR(ResultStatus.PARAM_INVALID);
        }

        //校验邮箱是否存在
        if (authService.checkEmailExists(subAccount.getEmail())) {
            return ResultModel.ERROR(ResultStatus.NAME_EXIST);
        }

        //校验子账号管理员数量是否超过
        if (subAccount.getRoleCategory().equals(RoleEnumType.MANAGER.getKey()) && authService.checkSubMangerNumber(loginAccount)) {
            return ResultModel.ERROR(ResultStatus.NUMBER_LIMIT);
        }

        //校验角色
        RoleAuth roleAuth = authService.getRoleAuthById(subAccount.getRoleCategory());

        if (null == roleAuth) {
            return ResultModel.ERROR(ResultStatus.PARAM_INVALID);
        }

        //记录日志
        userLogService.insertLog(loginAccount, LogEnumType.CREATE.getCode(), LogEnumType.CREATE.getName() + "子账号:" + subAccount.getEmail(),
                subAccount, null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.createSubAccount(loginAccount, subAccount, roleAuth));
    }

    /**
     * 修改子账号
     * created by sunhao 20170606
     */
    @RequestMapping(value = "{subAccountId}/update", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel modifySubAccount(HttpServletRequest request,@CurrentAccount Account loginAccount, @PathVariable Long subAccountId, @RequestBody Account subAccount) {

        RoleAuth roleAuth = authService.getRoleAuthById(subAccount.getRoleCategory());

        //参数校验name
        if (StringUtils.isEmpty(subAccount.getName()) || null == roleAuth) {
            return ResultModel.ERROR(ResultStatus.PARAM_INVALID);
        }

        //校验子账号管理员数量是否超过
        if (authService.checkUpdateSubMangerNumber(loginAccount, subAccount)) {
            return ResultModel.ERROR(ResultStatus.NUMBER_LIMIT);
        }

        subAccount.setId(subAccountId);
        //记录日志
        userLogService.insertLog(loginAccount, LogEnumType.UPDATE.getCode(), LogEnumType.UPDATE.getName() + "子账号:" + subAccount.getEmail(),
                subAccount, null, OperateObjectEnumType.ACCOUNT.getCode(), request);
        logger.info(IPAddrUtil.getIpAddr(request));
        return ResultModel.OK(authService.modifySubAccount(loginAccount, subAccount, roleAuth));
    }


    /**
     * 创建自定义角色
     * created by sunhao 20170606
     */
    @RequestMapping(value = "role/create", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel createCustomRole(HttpServletRequest request, @CurrentAccount Account loginAccount, @RequestBody RoleAuth roleAuth) {

        //校验参数
        if (StringUtils.isEmpty(roleAuth.getRoleName()) || roleAuth.getRoleName().length() > CUSTOM_ROLE_NAME_LENGTH
                || CollectionUtils.isEmpty(roleAuth.getRoleAuthDetails())) {
            return ResultModel.ERROR(ResultStatus.PARAM_INVALID);
        }

        //校验名字是否重复
        if (authService.checkCustomRoleName(loginAccount, roleAuth.getRoleName(), null)) {
            return ResultModel.ERROR(ResultStatus.NAME_EXIST);
        }

        //校验角色数量是否超过
        if (authService.checkCustomRoleNumber(loginAccount)) {
            return ResultModel.ERROR(ResultStatus.NUMBER_LIMIT);
        }

        //记录日志
        userLogService.insertLog(loginAccount, LogEnumType.CREATE.getCode(), LogEnumType.CREATE.getName() + "定义角色:" + roleAuth.getRoleName(),
                roleAuth, null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.createCustomRole(loginAccount, roleAuth));
    }

    /**
     * 修改自定义角色
     * created by sunhao 20170606
     */
    @RequestMapping(value = "role/{roleId}/update", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel modifyCustomRole(HttpServletRequest request, @CurrentAccount Account loginAccount, @PathVariable Long roleId, @RequestBody RoleAuth roleAuth) {

        roleAuth.setId(roleId);

        //校验是否修改名字,是否名字重复
        if (authService.checkCustomRoleName(loginAccount, roleAuth.getRoleName(), roleId)) {
            return ResultModel.ERROR(ResultStatus.NAME_EXIST);
        }

        //记录日志
        userLogService.insertLog(loginAccount, LogEnumType.UPDATE.getCode(), LogEnumType.UPDATE.getName() + "定义角色:" + roleAuth.getRoleName(),
                roleAuth, null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.modifyCustomRole(loginAccount, roleAuth));
    }

    /**
     * 删除自定义角色
     * created by sunhao 20170607
     */
    @RequestMapping(value = "role/{roleId}/delete", method = RequestMethod.DELETE)
    @ResponseBody
    public ResultModel deleteCustomRole(HttpServletRequest request, @CurrentAccount Account loginAccount, @PathVariable Long roleId) {

        //校验此角色是否有新建的子账号,有则无法删除
        if (authService.checkCustomRoleAccount(roleId)) {
            return ResultModel.ERROR(ResultStatus.PARAM_INVALID);
        }

        //记录日志
        userLogService.insertLog(loginAccount, LogEnumType.DELETE.getCode(), LogEnumType.DELETE.getName() + "定义角色:" + roleId,
                roleId, null, OperateObjectEnumType.ACCOUNT.getCode(), request);

        return ResultModel.OK(authService.deleteCustomRole(loginAccount, roleId));
    }

    @RequestMapping(value = "/test/deal", method = RequestMethod.PUT)
    @ResponseBody
    public ResultModel dealAuth() {
        return ResultModel.OK(authService.dealWithOldAuth());
    }

    /**
     * 重新发送激活邮件
     */
    @RequestMapping(value = "mail/{subAccountId}/resend", method = RequestMethod.POST)
    @ResponseBody
    public ResultModel resendSubAccountActiveEmail(@CurrentAccount Account loginAccount, @PathVariable Long subAccountId) {

        Account subAccount = authService.getSubAccountInfo(subAccountId);

        if (null != subAccount) {
            return ResultModel.OK(authService.sendSubAccountActivateEmail(loginAccount, subAccount));
        } else {
            return ResultModel.OK(false);
        }
    }
}
