package com.iformall.controller.sys;

import com.github.pagehelper.PageInfo;
import com.iformall.annotation.SystemControllerLog;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.BaseEntity;
import com.iformall.enums.EnumMallUserStatus;
import com.iformall.enums.EnumUserAdmin;
import com.iformall.service.*;
import com.iformall.shiro.PasswordHelper;
import com.iformall.shiro.UserSession;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author chenkx
 * @date 2018-01-05.
 */
@Api(value = "API - UserInfoController", description = "用户接口")
@RestController
@RequestMapping("user")
public class MallUserInfoController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    MallUserInfoService userInfoService;

    @Autowired
    MallUserRoleService userRoleService;

    @Autowired
    MallRoleService mallRoleService;

    @Autowired
    MallUserRoleService mallUserRoleService;

    @Autowired
    MallPermissionService mallPermissionService;

    @Autowired
    MallRolePermissionService mallRolePermissionService;

    @Autowired
    WxMsgValidationcodeService wxMsgValidationcodeService;

    @ApiOperation(value = "用户分页接口", response = String.class)
    @GetMapping("lists")
    //@RequiresPermissions("sys:user:list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "用户管理-列表")
    public ResultData listAsPage(MallUserInfo userInfo, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::listAsPage");

        userInfo.setTenantId(getTenantId());
        userInfo.setSortColumns(BaseEntity.SortField.CreateTime_DESC,BaseEntity.SortField.Id_DESC);
        final PageInfo<MallUserInfo> page = userInfoService.listAsPage(userInfo, pageNum, pageSize);
        for (MallUserInfo u : page.getList()) {
            MallUserRole r = new MallUserRole();
            r.setUid(u.getId());
            PageInfo<MallUserRole> ur = userRoleService.listAsPage(r, 1, 1);
            if (ur.getSize() > 0) {
                MallRole role = mallRoleService.getById(ur.getList().get(0).getRoleId());
                if (role != null) {
                    u.setRoleName(role.getName());
                    u.setRoleId(role.getId());
                }
            }
            // 保密
            u.setPassword(null);
            u.setBopenId(null);
            if(StringUtils.isNotBlank(u.getWebOpenId())) {
                u.setWebOpenId("保密");
            }
        }
        return new ResultData(page);
    }

    @ApiOperation(value = "用户详情接口", response = String.class)
    @GetMapping("detail")
    //@RequiresPermissions("sys:user:info")
    @SystemControllerLog(description = "用户管理-用户详情")
    public ResultData detail(Long id) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::detail");
        final MallUserInfo user = userInfoService.getById(id);
        user.setPassword(null);
        user.setBopenId(null);
        if(StringUtils.isNotBlank(user.getWebOpenId())) {
            user.setWebOpenId("保密");
        }

        return new ResultData(user);
    }

    @ApiOperation(value = "创建用户接口", response = String.class)
    @PostMapping("add")
    //@RequiresPermissions("sys:user:add")
    @SystemControllerLog(description = "用户管理-创建用户")
    public ResultData createUser(@RequestBody MallUserInfo userInfo) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::createUser");
        MallUserInfo currentUser = getUser();
        if(currentUser.getIsAdmin().equals(EnumUserAdmin.Normal.getCode())) {
            return new ResultData(ErrorCode.USER_NOT_ADMIN.getCode(), "只有系统管理员才能添加用户");
        }

        if(checkUniqueName(userInfo.getUsername()) > 0){
            return new ResultData(ErrorCode.USER_NAME_IS_FOUND.getCode(),"用户名已存在");
        }
        if(checkUniquePhone(userInfo.getPhone()) > 0){
            return new ResultData(ErrorCode.USER_PHONE_IS_FOUND.getCode(),"手机号已存在");
        }
        Assert.notNull(userInfo.getPassword(), "密码不能为空");
        PasswordHelper passwordHelper = new PasswordHelper();
        passwordHelper.encryptPassword(userInfo);
        userInfo.setTenantId(getTenantId());
        // 无法创建超管
        userInfo.setIsAdmin(EnumUserAdmin.Normal.getCode());
        userInfoService.saveOrUpdate(userInfo);
        if (userInfo.getRoleId() != null) {
            MallUserRole r = new MallUserRole();
            r.setRoleId(userInfo.getRoleId());
            r.setUid(userInfo.getId());
            userRoleService.saveOrUpdate(r);
        }
        return new ResultData(userInfo);
    }

    @ApiOperation(value = "修改用户接口", response = String.class)
    @PostMapping("update")
    //@RequiresPermissions("sys:user:update")
    @SystemControllerLog(description = "用户管理-修改用户")
    public ResultData updateUser(@RequestBody MallUserInfo userInfo) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::updateUser");
        boolean bChangedPhone = false;
        MallUserInfo currentUser = getUser();
        // 只有超管和自己能更新信息
        if (!(currentUser.getId().equals(userInfo.getId()) ||
                currentUser.getIsAdmin().equals(EnumUserAdmin.ADMIN.getCode()))) {
            return new ResultData(ErrorCode.USER_NO_PERMISSION.getCode(), "系统管理员和自己才能修改信息");
        }
        MallUserInfo oldUser = userInfoService.getById(userInfo.getId());
        if (!oldUser.getUsername().equals(userInfo.getUsername())) {
            if(checkUniqueName(userInfo.getUsername()) > 0){
                return new ResultData(ErrorCode.USER_NAME_IS_FOUND.getCode(),"用户名已存在");
            }
        }
        if (!oldUser.getPhone().equals(userInfo.getPhone())) {
            if(checkUniquePhone(userInfo.getPhone()) > 0){
                return new ResultData(ErrorCode.USER_PHONE_IS_FOUND.getCode(),"手机号已存在");
            }
            bChangedPhone = true;
        }

        userInfo.setTenantId(getTenantId());
        if (StringUtils.isNotBlank(userInfo.getPassword()) && userInfo.getPassword().length() > 0) {
            PasswordHelper passwordHelper = new PasswordHelper();
            passwordHelper.encryptPassword(userInfo);
        }
        // 系统内人员不能设置系统管理员
        userInfo.setIsAdmin(null);
        /*
        if (!currentUser.getIsAdmin().equals(EnumUserAdmin.ADMIN.getCode())) {
            // 只有系统管理员才能设置系统管理员
            userInfo.setIsAdmin(null);
        }
        */

        if (currentUser.getIsAdmin().equals(EnumUserAdmin.ADMIN.getCode()) &&
                currentUser.getId().equals(userInfo.getId())) {
            // 超管
            MallUserInfo adminUser = new MallUserInfo();
            adminUser.setEmail(userInfo.getEmail());
            adminUser.setId(userInfo.getId());
            if (StringUtils.isNotBlank(userInfo.getPassword()) && userInfo.getPassword().length() > 0) {
                adminUser.setPassword(userInfo.getPassword());
            }
            if (StringUtils.isNotBlank(userInfo.getNickName())) {
                adminUser.setNickName(userInfo.getNickName());
            }
            if (StringUtils.isNotBlank(userInfo.getPhone())) {
                adminUser.setPhone(userInfo.getPhone());
            }
            userInfoService.saveOrUpdate(adminUser);
        } else {
            userInfoService.saveOrUpdate(userInfo);
            if (userInfo.getRoleId() != null) {
                userRoleService.deleteByUserId(userInfo.getId());
                MallUserRole r = new MallUserRole();
                r.setRoleId(userInfo.getRoleId());
                r.setUid(userInfo.getId());
                userRoleService.saveOrUpdate(r);
            }
        }
        if(bChangedPhone) {
            // 手机号修改，清除bopen_id, 清除web_open_id
            userInfoService.cleanAllOpenId(userInfo);
        }

        return new ResultData();
    }

    @ApiOperation(value = "删除用户接口", response = String.class)
    @PostMapping("/del")
    //@RequiresPermissions("sys:user:del")
    @SystemControllerLog(description = "用户管理-删除用户")
    public ResultData deleteUser(@RequestBody MallUserInfo userInfo) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::deleteUser");
        MallUserInfo currentUser = getUser();
        if (currentUser.getIsAdmin().equals(EnumUserAdmin.Normal.getCode())) {
            return new ResultData(ErrorCode.USER_NOT_ADMIN.getCode(), "只有系统管理员才能删除用户");
        }
        if (currentUser.getId().equals(userInfo.getId())) {
            return new ResultData(ErrorCode.USER_NO_PERMISSION.getCode(), "用户不能删除自己");
        }
        userInfoService.deleteById(userInfo.getId());
        userRoleService.deleteByUserId(userInfo.getId());
        return new ResultData();
    }

    @ApiOperation(value = "起停用户接口")
    @PostMapping("updateStatus")
    //@RequiresPermissions("sys:user:update")
    @SystemControllerLog(description = "用户管理-起停用户")
    public ResultData modifyStatus(@RequestBody MallUserInfo userInfo) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::modifyStatus");
        MallUserInfo currentUser = getUser();
        if (currentUser.getIsAdmin().equals(EnumUserAdmin.ADMIN.getCode())) {
            MallUserInfo userInfo1 = userInfoService.getById(userInfo.getId());
            if(userInfo1 == null) {
                logger.error(ErrorCode.USER_IS_EMPTY.getMessage());
                return new ResultData(ErrorCode.USER_IS_EMPTY);
            }
            MallUserInfo updateUserInfo = new MallUserInfo();
            updateUserInfo.setId(userInfo.getId());
            updateUserInfo.setTenantId(getTenantId());
            updateUserInfo.setStatus(userInfo.getStatus());
            userInfoService.saveOrUpdate(userInfo);
            return new ResultData();
        } else {
            return new ResultData(ErrorCode.USER_NO_PERMISSION);
        }
    }

    private int checkUniqueName(String userName) {
        return userInfoService.cntByUserName(userName);
    }

    private int checkUniquePhone(String phone) {
        return userInfoService.cntByUserPhone(phone);
    }


    @ApiOperation(value = "用户权限检查")
    @GetMapping("hasButtonPermission")
    @SystemControllerLog(description = "用户管理-用户权限检查")
    public ResultData hasButtonPermission(String permissions) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::hasButtonPermission");
        MallUserInfo info = getUser();
        info.setPassword("保密");
        Map<String, Boolean> map = new HashMap<>();
        for (String name : permissions.split(",")) {
            Long userId = (Long)SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId);
            boolean has = userInfoService.hasButtonPermission(userId, name);
            map.put(name, has);
        }
        return new ResultData(map);
    }

    @ApiOperation(value = "用户权限检查")
    @GetMapping("getUser")
    //@RequiresPermissions("sys:user:info")
    @SystemControllerLog(description = "用户管理-获取用户信息")
    public ResultData getUserInfo() {
        ///logger.debug("[" + getIpAddr() + "] MallUserInfoController::getUserInfo");
        MallUserInfo info = getUser();
        info.protectInfos();
        return new ResultData(info);
    }

    @ApiOperation(value = "获取菜单")
    @GetMapping("/getMenu")
    @SystemControllerLog(description = "用户管理-获取菜单")
    public ResultData getMenu() {
        MallUserInfo info = getUser();
        String menu = userRoleService.getPermissionsByUser(info);
        return new ResultData(menu);
    }

    @ApiOperation(value = "用户密码发送验证码")
    @GetMapping("sendvalidationcode")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "场景(1:登录)", dataType = "Integer", paramType = "query", required = true)})
    public ResultData sendvalidationcode(String userName, Integer type) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::sendvalidationcode");
        MallUserInfo userQ = new MallUserInfo();
        userQ.setUsername(userName);

        MallUserInfo user = userInfoService.getByUsername(userName);
        if (user==null) {
            logger.error("用户不存在, userName: " + userName);
            return new ResultData(ErrorCode.USER_IS_EMPTY);
        }

        if(user.getStatus() == EnumMallUserStatus.NOT_VALID.getCode()){
            logger.error("用户已停用, userName: " + userName);
            return new ResultData(ErrorCode.USER_IS_LOCKED);
        }

        if (StringUtils.isBlank(user.getPhone())) {
            logger.error("用户手机号为空, userName: " + userName);
            return new ResultData(ErrorCode.USER_PHONE_IS_NOT_FOUND);
        }

        WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
        wxMsgValidationcode.setTenantId(user.getTenantId());
        wxMsgValidationcode.setPhone(user.getPhone());
        wxMsgValidationcode.setType(type);
        return wxMsgValidationcodeService.sendvalidationcode(wxMsgValidationcode);
    }

    @ApiOperation(value = "修改密码", notes = "{\"userName\",\"string\",\"code\",\"string\",\"pwd\",\"string\"}")
    @PostMapping("/updatepwd")
    @SystemControllerLog(description = "用户管理-修改密码")
    public ResultData updatepwd(@RequestBody Map<String, String> params) {
        logger.debug("[" + getIpAddr() + "] MallUserInfoController::updatepwd");
        // String phone,String code,String pwd
        String userName = params.get("userName");
        String code = params.get("code");
        String pwd = params.get("pwd");

        if (StringUtils.isBlank(userName)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "userName不能为空");
        }
        if (StringUtils.isBlank(code)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "验证码不能为空");
        }
        if (StringUtils.isBlank(pwd)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "密码不能为空");
        }

        MallUserInfo userQ = new MallUserInfo();
        userQ.setUsername(userName);
        MallUserInfo user = userInfoService.getByUsername(userName);
        if (user==null) {
            logger.error("用户不存在, userName: " + userName);
            return new ResultData(ErrorCode.USER_IS_EMPTY);
        }

        user.setPassword(pwd);

        PasswordHelper passwordHelper = new PasswordHelper();
        passwordHelper.encryptPassword(user);


        try {
            return userInfoService.updatepwd(user, code);
        } catch (Exception e) {
            return new ResultData(Result.ERROR, e.getMessage());
        }
    }


}
