package com.brframework.commonwebadmin.web.admin;

import com.brframework.commoncms.annatotion.layout.EditAlertLayout;
import com.brframework.commoncms.annatotion.layout.EditLayout;
import com.brframework.commoncms.annatotion.layout.PageLayout;
import com.brframework.commoncms.annatotion.layout.ViewLayout;
import com.brframework.commoncms.annatotion.option.CmsOption;
import com.brframework.commoncms.core.Icons;
import com.brframework.commoncms.core.permission.Menu;
import com.brframework.commoncms.core.permission.Permission;
import com.brframework.commonweb.json.JSONResult;
import com.brframework.commonweb.json.Page;
import com.brframework.commonweb.json.PageParam;
import com.brframework.commoncms.annatotion.AdminMenu;
import com.brframework.commonwebadmin.aop.annotation.AOLog;
import com.brframework.commonwebadmin.domain.admin.FunctionNode;
import com.brframework.commonwebadmin.domain.admin.FunctionRole;
import com.brframework.commonwebadmin.entity.admin.AdminOptionLog;
import com.brframework.commonwebadmin.entity.admin.AdminRole;
import com.brframework.commonwebadmin.entity.admin.AdminUser;
import com.brframework.commonwebadmin.json.admin.adminuser.*;
import com.brframework.commonwebadmin.service.admin.AdminOptionLogService;
import com.brframework.commonwebadmin.service.admin.AdminRoleService;
import com.brframework.commonwebadmin.service.admin.AdminUserService;
import com.brframework.commonwebadmin.service.admin.FunctionService;
import com.google.common.primitives.Ints;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;

import static com.brframework.commondb.core.ControllerPageHandle.jpaPageToPage;

/**
 * @author xu
 * @date 2018/3/9 0009 下午 8:37
 * 后台用户管理(需要ADMIN权限)
 */
@RestController
@Api(tags = "系统用户")
@RequestMapping("/admin/access")
@AdminMenu(menuName = "系统用户", icon = Icons.USER, order = Integer.MIN_VALUE)
public class AdminUserRoleController {

    @Autowired
    AdminUserService adminUserService;
    @Autowired
    AdminRoleService adminRoleService;
    @Autowired
    FunctionService functionService;



    @ApiOperation(value = "用户列表", notes = "用户列表")
    @GetMapping("v1/sys-user/list")
    @PageLayout(
            options = {
                    @CmsOption(name = "增加", uriMappingMethod = "userCreateV1")
            },
            columnOptions = {
                    @CmsOption(name = "修改信息", uriMappingMethod = "userEditV1"),
                    @CmsOption(name = "重置密码", uriMappingMethod = "userEditPasswordV1"),
                    @CmsOption(name = "禁用", condition = "{state}==1", uriMappingMethod = "userDisableV1", alert = "您确定禁用该账号吗？"),
                    @CmsOption(name = "启用", condition = "{state}==0", uriMappingMethod = "userEnableV1", alert = "您确定启用该账号吗？"),
                    @CmsOption(name = "删除", condition = "{id}!=1", uriMappingMethod = "userDeleteV1", alert = "您确定要删除该用户吗？")
            }
    )
    @PreAuthorize("hasRole('ADMIN_USER_LIST')")
    @AdminMenu(menuName = "用户管理", order = Integer.MIN_VALUE)
    public JSONResult<Page<AdminUser>> userListV1(@Valid PageParam page) {

        return JSONResult.ok(jpaPageToPage(
                adminUserService.page(page, null),
                page
        ));
    }

    @ApiOperation(value = "用户信息", notes = "用户信息")
    @GetMapping("v1/sys-user/{id}")
    @PreAuthorize("hasRole('ADMIN_USER_LIST')")
    public JSONResult<AdminUser> userInfo(@PathVariable Integer id){

        return JSONResult.ok(
                adminUserService.accessObject(id)
        );
    }

    @ApiOperation(value = "用户信息", notes = "用户信息")
    @GetMapping("v1/sys-user/id/{userId}")
    @ViewLayout(paddingMappingMethod = "userInfoByUserId")
    @PreAuthorize("hasRole('ADMIN_USER_LIST')")
    public JSONResult<AdminUser> userInfoByUserId(@PathVariable Integer userId){
        return userInfo(userId);
    }

    @ApiOperation(value = "更新用户信息", notes = "更新用户信息")
    @PostMapping("v1/sys-user/{id}")
    @EditAlertLayout(
            paddingMappingMethod = "userInfo"
    )
    @PreAuthorize("hasRole('ADMIN_USER_EDIT')")
    @AOLog
    public JSONResult userEditV1(
            @PathVariable Integer id,
            @Valid @RequestBody AdminUserUpdateParam param) {

        adminUserService.updateUser(id, param.getNickname(), param.getRoles());

        return JSONResult.ok();
    }

    @ApiOperation(value = "禁用用户", notes = "设置禁用状态,当前token失效,登录验证状态;选用delete方法是为了前端颜色问题")
    @DeleteMapping("v1/sys-user/disable/{id}")
    @PreAuthorize("hasRole('ADMIN_USER_EDIT')")
    @AOLog
    public JSONResult userDisableV1(@PathVariable Integer id) {

        adminUserService.disableUser(id);

        return JSONResult.ok();
    }

    @ApiOperation(value = "启用用户", notes = "设置为启用状态")
    @PostMapping("v1/sys-user/enable/{id}")
    @PreAuthorize("hasRole('ADMIN_USER_EDIT')")
    @AOLog
    public JSONResult userEnableV1(@PathVariable Integer id) {

        adminUserService.enableUser(id);

        return JSONResult.ok();
    }

    @ApiOperation(value = "重置用户密码", notes = "重置用户密码")
    @PostMapping("v1/sys-user/{id}/password")
    @EditAlertLayout
    @PreAuthorize("hasRole('ADMIN_USER_PASSWORD')")
    @AOLog
    public JSONResult userEditPasswordV1(
            @PathVariable Integer id,
            @Valid @RequestBody AdminUserPasswordParam param) {

        adminUserService.updateUserPassword(id, param.getPassword());

        return JSONResult.ok();
    }

    @ApiOperation(value = "添加用户", notes = "添加用户")
    @PutMapping("v1/sys-user")
    @EditAlertLayout
    @PreAuthorize("hasRole('ADMIN_USER_CREATE')")
    @AOLog
    public JSONResult userCreateV1(@Valid @RequestBody AdminUserCreateParam param) {

        adminUserService.save(AdminUser.builder()
                .createDate(LocalDateTime.now())
                .nickname(param.getNickname())
                .password(new BCryptPasswordEncoder().encode(param.getPassword()))
                .roles(param.getRoles())
                .username(param.getUsername())
                .state(1)
                .build());

        return JSONResult.ok();
    }

    @ApiOperation(value = "删除用户", notes = "删除用户")
    @DeleteMapping("v1/sys-user/{id}")
    @PreAuthorize("hasRole('ADMIN_USER_DELETE')")
    @AOLog
    public JSONResult userDeleteV1(@PathVariable String id) {
        adminUserService.removeById(Ints.tryParse(id));
        return JSONResult.ok();
    }

    @ApiOperation(value = "角色列表", notes = "角色列表")
    @GetMapping("v1/sys-role/list")
    @PageLayout(
            options = {
                    @CmsOption(name = "增加", uriMappingMethod = "roleCreateV1")
            },
            columnOptions = {
                    @CmsOption(name = "修改权限", condition = "{id}!=1", uriMappingMethod = "roleEditV1"),
                    @CmsOption(name = "删除", condition = "{id}!=1", uriMappingMethod = "roleDeleteV1", alert = "您确定要删除该角色吗？该操作可能会造成系统不能正常运行，请谨慎操作！")
            }
    )
    @PreAuthorize("hasRole('ADMIN_ROLE_LIST')")
    @AdminMenu(menuName = "角色管理", order = 0)
    public JSONResult<Page<AdminRole>> roleListV1(@Valid PageParam page) {

        return JSONResult.ok(jpaPageToPage(
                adminRoleService.page(page, null),
                page
        ));
    }

    @ApiOperation(value = "创建角色", notes = "创建角色")
    @PutMapping("v1/sys-role")
    @PreAuthorize("hasRole('ADMIN_ROLE_CREATE')")
    @EditAlertLayout
    @AOLog
    public JSONResult roleCreateV1(@Valid @RequestBody AdminRoleEditParam param) {
        adminRoleService.create(param.getName(), param.getPermissions());
        return JSONResult.ok();
    }

    @ApiOperation(value = "角色详情", notes = "角色详情")
    @GetMapping("v1/sys-role/{id}")
    @PreAuthorize("hasRole('ADMIN_ROLE_LIST')")
    @AOLog
    public JSONResult<AdminRole> roleGetV1(@PathVariable String id) {
        return JSONResult.ok(adminRoleService.accessObject(Integer.parseInt(id)));
    }

    @ApiOperation(value = "编辑角色", notes = "编辑角色")
    @PostMapping("v1/sys-role/{id}")
    @EditAlertLayout(
            paddingMappingMethod = "roleGetV1"
    )
    @PreAuthorize("hasRole('ADMIN_ROLE_EDIT')")
    @AOLog
    public JSONResult roleEditV1(@PathVariable String id,@Valid @RequestBody  AdminRoleEditParam param) {
        adminRoleService.update(Integer.parseInt(id), param.getName(), param.getPermissions());
        return JSONResult.ok();
    }

    @ApiOperation(value = "删除角色", notes = "删除角色")
    @DeleteMapping("v1/sys-role/{id}")
    @PreAuthorize("hasRole('ADMIN_ROLE_DELETE')")
    @AOLog
    public JSONResult roleDeleteV1(@PathVariable String id) {
        adminRoleService.removeById(Ints.tryParse(id));
        return JSONResult.ok();
    }

    @Autowired
    AdminOptionLogService logService;

    @ApiOperation(value = "操作审计", notes = "操作审计")
    @GetMapping("v1/sys-user/option-log/list")
    @PageLayout
    @PreAuthorize("hasRole('ADMIN_USER_OPTION_LIST')")
    @AdminMenu(menuName = "操作审计", order = 1)
    public JSONResult<Page<AdminOptionLog>> userOptionLogListV1(@Valid PageParam page,
                                                                AdminOptionLogListParam param) {

        return JSONResult.ok(jpaPageToPage(
                logService.page(page, param),
                page
        ));
    }

}
