package shop.alien.store.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.*;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifeSysRole;
import shop.alien.entity.store.vo.MenuWithRoleVo;
import shop.alien.store.service.LifeSysRoleMenuService;
import shop.alien.store.service.LifeSysRoleService;

import java.util.List;

/**
 * 平台角色信息表 前端控制器
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Api(tags = {"平台角色管理"})
@ApiSort(1)
@CrossOrigin
@RestController
@RequestMapping("/sys/role")
@RequiredArgsConstructor
public class LifeSysRoleController {

    private final LifeSysRoleService lifeSysRoleService;
    private final LifeSysRoleMenuService lifeSysRoleMenuService;

    @ApiOperation("分页查询角色列表")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "size", value = "页容", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "roleName", value = "角色名称（支持模糊查询）", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "description", value = "角色描述（支持模糊查询）", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "角色状态（0正常 1停用）", dataType = "String", paramType = "query")
    })
    @GetMapping("/getRolePage")
    public R<IPage<LifeSysRole>> getRolePage(
            @RequestParam(name = "page", defaultValue = "1") int page,
            @RequestParam(name = "size", defaultValue = "10") int size,
            @RequestParam(value = "roleName", required = false) String roleName,
            @RequestParam(value = "description", required = false) String description,
            @RequestParam(value = "status", required = false) String status) {
        log.info("LifeSysRoleController.getRolePage?page={}, size={}, roleName={}, roleKey={}, status={}", 
                page, size, roleName, description, status);
        IPage<LifeSysRole> rolePage = lifeSysRoleService.getRolePage(page, size, roleName, description, status);
        return R.data(rolePage);
    }

    @ApiOperation("根据ID查询角色详情")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "path", required = true)
    })
    @GetMapping("/getRoleById")
    public R<LifeSysRole> getRoleById(@RequestParam("roleId") Long roleId) {
        log.info("LifeSysRoleController.getRoleById?roleId={}", roleId);
        LifeSysRole role = lifeSysRoleService.getRoleById(roleId);
        if (role == null) {
            return R.fail("未找到该角色信息");
        }
        return R.data(role);
    }

    @ApiOperation("新增角色")
    @ApiOperationSupport(order = 3)
    @PostMapping("/saveRole")
    public R<String> saveRole(@RequestBody LifeSysRole role) {
        log.info("LifeSysRoleController.saveRole?role={}", role);
        boolean result = lifeSysRoleService.saveRole(role);
        if (result) {
            return R.success("新增成功");
        }
        return R.fail("新增失败");
    }

    @ApiOperation("修改角色")
    @ApiOperationSupport(order = 4)
    @PostMapping("/updateRole")
    public R<String> updateRole(@RequestBody LifeSysRole role) {
        log.info("LifeSysRoleController.updateRole?role={}", role);
        boolean result = lifeSysRoleService.updateRole(role);
        if (result) {
            return R.success("修改成功");
        }
        return R.fail("修改失败");
    }

    @ApiOperation("删除角色")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "path", required = true)
    })
    @DeleteMapping("/deleteRole")
    public R<String> deleteRole(@RequestParam("roleId") Long roleId) {
        log.info("LifeSysRoleController.deleteRole?roleId={}", roleId);
        boolean result = lifeSysRoleService.deleteRole(roleId);
        if (result) {
            return R.success("删除成功");
        }
        return R.fail("删除失败");
    }

    @ApiOperation("修改角色状态")
    @ApiOperationSupport(order = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "path", required = true),
            @ApiImplicitParam(name = "status", value = "角色状态（0正常 1停用）", dataType = "String", paramType = "query", required = true)
    })
    @PutMapping("/updateStatus")
    public R<String> updateStatus(
            @RequestParam("roleId") Long roleId,
            @RequestParam("status") String status) {
        log.info("LifeSysRoleController.updateStatus?roleId={}, status={}", roleId, status);
        boolean result = lifeSysRoleService.updateStatus(roleId, status);
        if (result) {
            return R.success("操作成功");
        }
        return R.fail("操作失败");
    }

    @ApiOperation("查询所有正常状态的角色列表")
    @ApiOperationSupport(order = 7)
    @GetMapping("/getAllNormalRoles")
    public R<List<LifeSysRole>> getAllNormalRoles() {
        log.info("LifeSysRoleController.getAllNormalRoles");
        List<LifeSysRole> roles = lifeSysRoleService.getAllNormalRoles();
        return R.data(roles);
    }

    @ApiOperation("根据角色ID查询所有权限（区分已拥有和未拥有的权限）")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "query", required = true),
    })
    @GetMapping(value = "/getMenusWithRoleStatus")
    public R<List<MenuWithRoleVo>> getMenusWithRoleStatus(@RequestParam Long roleId) {
        log.info("LifeSysRoleMenuController.getMenusWithRoleStatus => roleId={}", roleId);
        return lifeSysRoleMenuService.getMenusWithRoleStatus(roleId);
    }

    @ApiOperation("批量为角色分配菜单")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "body", required = true),
            @ApiImplicitParam(name = "menuIds", value = "菜单ID列表", dataType = "List", paramType = "body", required = true),
    })
    @PostMapping(value = "/assignMenus")
    public R<Boolean> assignMenus(@RequestBody AssignMenusDto assignMenusDto) {
        log.info("LifeSysRoleMenuController.assignMenus => roleId={}, menuIds={}",
                assignMenusDto.getRoleId(), assignMenusDto.getMenuIds());
        return lifeSysRoleMenuService.assignMenus(assignMenusDto.getRoleId(), assignMenusDto.getMenuIds());
    }

    @ApiOperation("移除角色的所有菜单")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "query", required = true),
    })
    @DeleteMapping(value = "/removeAllMenus")
    public R<Boolean> removeAllMenus(@RequestParam Long roleId) {
        log.info("LifeSysRoleMenuController.removeAllMenus => roleId={}", roleId);
        return lifeSysRoleMenuService.removeAllMenus(roleId);
    }


    @ApiOperation("根据角色ID获取菜单ID列表")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "query", required = true),
    })
    @GetMapping(value = "/getMenuIdsByRoleId")
    public R<List<Long>> getMenuIdsByRoleId(@RequestParam Long roleId) {
        log.info("LifeSysRoleMenuController.getMenuIdsByRoleId => roleId={}", roleId);
        return lifeSysRoleMenuService.getMenuIdsByRoleId(roleId);
    }

    @ApiOperation("为角色添加单个菜单")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "body", required = true),
            @ApiImplicitParam(name = "menuId", value = "菜单ID", dataType = "Long", paramType = "body", required = true),
    })
    @PostMapping(value = "/addMenu")
    public R<Boolean> addMenu(@RequestBody AddMenuDto addMenuDto) {
        log.info("LifeSysRoleMenuController.addMenu => roleId={}, menuId={}",
                addMenuDto.getRoleId(), addMenuDto.getMenuId());
        return lifeSysRoleMenuService.addMenu(addMenuDto.getRoleId(), addMenuDto.getMenuId());
    }

    @ApiOperation("移除角色的单个菜单")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", dataType = "Long", paramType = "query", required = true),
            @ApiImplicitParam(name = "menuId", value = "菜单ID", dataType = "Long", paramType = "query", required = true),
    })
    @DeleteMapping(value = "/removeMenu")
    public R<Boolean> removeMenu(@RequestParam Long roleId, @RequestParam Long menuId) {
        log.info("LifeSysRoleMenuController.removeMenu => roleId={}, menuId={}", roleId, menuId);
        return lifeSysRoleMenuService.removeMenu(roleId, menuId);
    }

    @ApiOperation("根据菜单ID获取角色ID列表")
    @ApiOperationSupport(order = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "menuId", value = "菜单ID", dataType = "Long", paramType = "query", required = true),
    })
    @GetMapping(value = "/getRoleIdsByMenuId")
    public R<List<Long>> getRoleIdsByMenuId(@RequestParam Long menuId) {
        log.info("LifeSysRoleMenuController.getRoleIdsByMenuId => menuId={}", menuId);
        return lifeSysRoleMenuService.getRoleIdsByMenuId(menuId);
    }

    /**
     * 批量分配菜单请求DTO
     */
    @Data
    @ApiModel(value = "AssignMenusDto", description = "批量分配菜单请求参数")
    static class AssignMenusDto {
        @ApiModelProperty(value = "角色ID", required = true)
        private Long roleId;

        @ApiModelProperty(value = "菜单ID列表", required = true)
        private List<Long> menuIds;
    }

    /**
     * 添加菜单请求DTO
     */
    @Data
    @ApiModel(value = "AddMenuDto", description = "添加菜单请求参数")
    static class AddMenuDto {
        @ApiModelProperty(value = "角色ID", required = true)
        private Long roleId;

        @ApiModelProperty(value = "菜单ID", required = true)
        private Long menuId;
    }
}

