package com.writeoff.module.system.controller;

import com.writeoff.common.api.ApiResponse;
import com.writeoff.common.api.PageResult;
import com.writeoff.module.system.dto.AssignRoleDataPermissionRequest;
import com.writeoff.module.system.dto.CreateDataPermissionPolicyRequest;
import com.writeoff.module.system.dto.UpdateDataPermissionPolicyRequest;
import com.writeoff.module.system.model.DataPermissionPolicy;
import com.writeoff.module.system.service.DataPermissionService;
import com.writeoff.security.DataScopeType;
import com.writeoff.security.RequirePermission;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Map;

@RestController
@RequestMapping({"/api/data-permissions", "/api/data-scope-policies"})
public class DataPermissionController {
    private final DataPermissionService dataPermissionService;

    public DataPermissionController(DataPermissionService dataPermissionService) {
        this.dataPermissionService = dataPermissionService;
    }

    @GetMapping
    @RequirePermission(value = "data.permission.read", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_LIST")
    public ApiResponse<PageResult<DataPermissionPolicy>> list() {
        return ApiResponse.success(dataPermissionService.listPolicies());
    }

    @PostMapping
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_CREATE")
    public ApiResponse<DataPermissionPolicy> create(@RequestBody @Valid CreateDataPermissionPolicyRequest request) {
        return ApiResponse.success(dataPermissionService.createPolicy(request));
    }

    @PutMapping("/{id}")
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_UPDATE")
    public ApiResponse<DataPermissionPolicy> update(@PathVariable("id") Long id, @RequestBody @Valid UpdateDataPermissionPolicyRequest request) {
        return ApiResponse.success(dataPermissionService.updatePolicy(id, request));
    }

    @PostMapping("/{id}/assign-roles")
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_ASSIGN_ROLES")
    public ApiResponse<String> assignRoles(@PathVariable("id") Long id, @RequestBody @Valid AssignRoleDataPermissionRequest request) {
        dataPermissionService.assignRoles(id, request);
        return ApiResponse.success("OK");
    }

    @GetMapping("/{id}/roles")
    @RequirePermission(value = "data.permission.read", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_ROLES")
    public ApiResponse<java.util.List<Long>> policyRoles(@PathVariable("id") Long id) {
        return ApiResponse.success(dataPermissionService.listPolicyRoleIds(id));
    }

    @PostMapping("/{id}/copy")
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_COPY")
    public ApiResponse<DataPermissionPolicy> copy(@PathVariable("id") Long id) {
        return ApiResponse.success(dataPermissionService.copyPolicy(id));
    }

    @PostMapping("/{id}/enable")
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_ENABLE")
    public ApiResponse<String> enable(@PathVariable("id") Long id) {
        dataPermissionService.enablePolicy(id);
        return ApiResponse.success("OK");
    }

    @PostMapping("/{id}/disable")
    @RequirePermission(value = "data.permission.manage", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_DISABLE")
    public ApiResponse<String> disable(@PathVariable("id") Long id) {
        dataPermissionService.disablePolicy(id);
        return ApiResponse.success("OK");
    }

    @GetMapping("/current-scope")
    @RequirePermission(value = "data.permission.read", dataScope = DataScopeType.TENANT, auditAction = "DATA_PERMISSION_CURRENT_SCOPE")
    public ApiResponse<Map<String, Object>> currentScope() {
        return ApiResponse.success(dataPermissionService.currentScopeSummary());
    }
}
