package com.writeoff.module.system.controller;

import com.writeoff.common.api.ApiResponse;
import com.writeoff.common.api.PageResult;
import com.writeoff.module.system.dto.BindPlatformMenuRolesRequest;
import com.writeoff.module.system.dto.CreateMenuRequest;
import com.writeoff.module.system.dto.ReorderMenusRequest;
import com.writeoff.module.system.dto.UpdateMenuRequest;
import com.writeoff.module.system.model.MenuInfo;
import com.writeoff.module.system.service.PlatformMenuService;
import com.writeoff.security.AuthContext;
import com.writeoff.security.AuthScope;
import com.writeoff.security.DataScopeType;
import com.writeoff.security.PermissionDomain;
import com.writeoff.security.RequirePermission;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import javax.validation.Valid;

@RestController
@RequestMapping("/api/platform/menus")
public class PlatformMenuController {
    private final PlatformMenuService platformMenuService;

    public PlatformMenuController(PlatformMenuService platformMenuService) {
        this.platformMenuService = platformMenuService;
    }

    @GetMapping
    @RequirePermission(value = "platform.menu.manage", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_LIST")
    public ApiResponse<PageResult<MenuInfo>> list() {
        return ApiResponse.success(platformMenuService.list());
    }

    @GetMapping("/current")
    public ApiResponse<List<MenuInfo>> current() {
        Long userId = AuthContext.userId();
        if (userId == null || AuthContext.scope() != AuthScope.PLATFORM) {
            return ApiResponse.success(Collections.<MenuInfo>emptyList());
        }
        return ApiResponse.success(platformMenuService.currentUserMenus(userId));
    }

    @PostMapping
    @RequirePermission(value = "platform.menu.manage", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_CREATE")
    public ApiResponse<MenuInfo> create(@RequestBody @Valid CreateMenuRequest request) {
        return ApiResponse.success(platformMenuService.create(request));
    }

    @PutMapping("/{id}")
    @RequirePermission(value = "platform.menu.manage", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_UPDATE")
    public ApiResponse<MenuInfo> update(@PathVariable("id") Long id, @RequestBody @Valid UpdateMenuRequest request) {
        return ApiResponse.success(platformMenuService.update(id, request));
    }

    @PostMapping("/reorder")
    @RequirePermission(value = "platform.menu.manage", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_REORDER")
    public ApiResponse<String> reorder(@RequestBody @Valid ReorderMenusRequest request) {
        platformMenuService.reorderMenus(request);
        return ApiResponse.success("ok");
    }

    @GetMapping("/{id}/roles")
    @RequirePermission(value = "platform.role.read", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_ROLES")
    public ApiResponse<List<Long>> menuRoles(@PathVariable("id") Long id) {
        return ApiResponse.success(platformMenuService.getMenuRoleIds(id));
    }

    @PostMapping("/{id}/roles")
    @RequirePermission(value = "platform.menu.manage", domain = PermissionDomain.PLATFORM, dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "PLATFORM_MENU_BIND_ROLES")
    public ApiResponse<String> bindRoles(@PathVariable("id") Long id, @RequestBody @Valid BindPlatformMenuRolesRequest request) {
        platformMenuService.bindMenuRoles(id, request);
        return ApiResponse.success("ok");
    }
}
