package com.mosquito.project.permission;

import com.mosquito.project.dto.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 权限管理控制器
 */
@RestController
@RequestMapping("/api/v1/permissions")
public class PermissionController {

    private final PermissionService permissionService;
    private final PermissionCheckService permissionCheckService;
    private final SysUserService sysUserService;
    private final ApprovalFlowService approvalFlowService;

    // 权限分配/撤销的触发事件
    private static final String TRIGGER_PERMISSION_ASSIGN = "PERMISSION_ASSIGN";
    private static final String TRIGGER_PERMISSION_REVOKE = "PERMISSION_REVOKE";
    private static final String BIZ_TYPE_PERMISSION_CHANGE = "PERMISSION_CHANGE";

    public PermissionController(PermissionService permissionService,
                              PermissionCheckService permissionCheckService,
                              SysUserService sysUserService,
                              ApprovalFlowService approvalFlowService) {
        this.permissionService = permissionService;
        this.permissionCheckService = permissionCheckService;
        this.sysUserService = sysUserService;
        this.approvalFlowService = approvalFlowService;
    }

    /**
     * 从请求属性中获取当前用户ID
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        Object userIdObj = request.getAttribute("userId");
        if (userIdObj instanceof Long) {
            return (Long) userIdObj;
        } else if (userIdObj instanceof Integer) {
            return ((Integer) userIdObj).longValue();
        }
        return null;
    }

    /**
     * 获取所有权限列表
     */
    @GetMapping
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<List<SysPermission>> getAllPermissions() {
        return ApiResponse.success(permissionService.findAll());
    }

    /**
     * 根据模块获取权限
     */
    @GetMapping("/module/{moduleCode}")
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<List<SysPermission>> getPermissionsByModule(@PathVariable String moduleCode) {
        return ApiResponse.success(permissionService.findByModuleCode(moduleCode));
    }

    /**
     * 获取当前用户权限信息
     * 已登录用户可查询自身权限，无需特定权限
     */
    @GetMapping("/current")
    public ApiResponse<CurrentUserPermissions> getCurrentUserPermissions(HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        if (userId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }
        var permissions = new java.util.ArrayList<>(permissionCheckService.getUserPermissions(userId));
        var dataScope = permissionCheckService.getUserDataScope(userId);

        CurrentUserPermissions result = new CurrentUserPermissions();
        result.setUserId(userId);
        result.setPermissions(permissions);
        result.setDataScope(dataScope);
        result.setRoles(permissionCheckService.getUserRoles(userId));

        return ApiResponse.success(result);
    }

    /**
     * 检查用户是否拥有指定权限
     */
    @GetMapping("/check")
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<Boolean> checkPermission(@RequestParam String permissionCode, HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        if (userId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }
        boolean hasPermission = permissionCheckService.hasPermission(userId, permissionCode);
        return ApiResponse.success(hasPermission);
    }

    /**
     * 检查用户是否拥有指定角色
     */
    @GetMapping("/role")
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<Boolean> checkRole(@RequestParam String roleCode, HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        if (userId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }
        boolean hasRole = permissionCheckService.hasRole(userId, roleCode);
        return ApiResponse.success(hasRole);
    }

    /**
     * 获取用户数据权限范围
     */
    @GetMapping("/datascope")
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<String> getDataScope(HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        if (userId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }
        String dataScope = permissionCheckService.getUserDataScope(userId);
        return ApiResponse.success(dataScope);
    }

    /**
     * 创建权限
     */
    @PostMapping
    @RequirePermission("permission.index.manage.ALL")
    public ApiResponse<Long> createPermission(@RequestBody SysPermission permission) {
        SysPermission saved = permissionService.save(permission);
        return ApiResponse.success(saved.getId(), "权限创建成功");
    }

    /**
     * 更新权限
     */
    @PutMapping("/{id}")
    @RequirePermission("permission.index.manage.ALL")
    public ApiResponse<Void> updatePermission(@PathVariable Long id, @RequestBody SysPermission permission) {
        permission.setId(id);
        permissionService.update(id, permission);
        return ApiResponse.success(null, "权限更新成功");
    }

    /**
     * 删除权限
     */
    @DeleteMapping("/{id}")
    @RequirePermission("permission.index.manage.ALL")
    public ApiResponse<Void> deletePermission(@PathVariable Long id) {
        permissionService.delete(id);
        return ApiResponse.success(null, "权限删除成功");
    }

    /**
     * 为用户分配权限（需要审批）
     */
    @PostMapping("/user/{userId}/assign")
    @RequirePermission("permission.user.assign.ALL")
    public ApiResponse<Map<String, Object>> assignUserPermissions(
            @PathVariable Long userId,
            @RequestBody AssignPermissionsRequest request,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }

        // 构建业务数据
        String bizData;
        try {
            Map<String, Object> bizDataMap = Map.of(
                "userId", userId,
                "permissionIds", request.getPermissionIds(),
                "reason", request.getReason() != null ? request.getReason() : "权限分配",
                "operator", currentUserId
            );
            bizData = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(bizDataMap);
        } catch (Exception e) {
            return ApiResponse.error(500, "构建业务数据失败");
        }

        // 提交审批
        Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
            TRIGGER_PERMISSION_ASSIGN,
            BIZ_TYPE_PERMISSION_CHANGE,
            userId,
            "用户权限分配审批",
            currentUserId,
            request.getReason() != null ? request.getReason() : "权限分配",
            bizData
        );

        return ApiResponse.success(approvalResult, "权限分配申请已提交，等待审批");
    }

    /**
     * 撤销用户权限（需要审批）
     */
    @PostMapping("/user/{userId}/revoke")
    @RequirePermission("permission.user.revoke.ALL")
    public ApiResponse<Map<String, Object>> revokeUserPermissions(
            @PathVariable Long userId,
            @RequestBody AssignPermissionsRequest request,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }

        // 构建业务数据
        String bizData;
        try {
            Map<String, Object> bizDataMap = Map.of(
                "userId", userId,
                "permissionIds", request.getPermissionIds(),
                "reason", request.getReason() != null ? request.getReason() : "权限撤销",
                "operator", currentUserId
            );
            bizData = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(bizDataMap);
        } catch (Exception e) {
            return ApiResponse.error(500, "构建业务数据失败");
        }

        // 提交审批
        Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
            TRIGGER_PERMISSION_REVOKE,
            BIZ_TYPE_PERMISSION_CHANGE,
            userId,
            "用户权限撤销审批",
            currentUserId,
            request.getReason() != null ? request.getReason() : "权限撤销",
            bizData
        );

        return ApiResponse.success(approvalResult, "权限撤销申请已提交，等待审批");
    }

    /**
     * 配置用户数据权限范围
     */
    @PostMapping("/user/{userId}/datascope")
    @RequirePermission("permission.data.config.ALL")
    public ApiResponse<Void> configUserDataScope(
            @PathVariable Long userId,
            @RequestBody DataScopeRequest request,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }

        sysUserService.updateDataScope(userId, request.getDataScope(), request.getDepartmentId());
        return ApiResponse.success(null, "数据权限配置成功");
    }

    /**
     * 获取用户权限列表
     */
    @GetMapping("/user/{userId}")
    @RequirePermission("permission.index.view.ALL")
    public ApiResponse<List<SysPermission>> getUserPermissions(@PathVariable Long userId) {
        List<SysPermission> permissions = sysUserService.getUserPermissions(userId);
        return ApiResponse.success(permissions);
    }

    /**
     * 当前用户权限
     */
    public static class CurrentUserPermissions {
        private Long userId;
        private List<String> roles;
        private List<String> permissions;
        private String dataScope;

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public List<String> getRoles() { return roles; }
        public void setRoles(List<String> roles) { this.roles = roles; }
        public List<String> getPermissions() { return permissions; }
        public void setPermissions(List<String> permissions) { this.permissions = permissions; }
        public String getDataScope() { return dataScope; }
        public void setDataScope(String dataScope) { this.dataScope = dataScope; }
    }

    /**
     * 权限分配请求体
     */
    public static class AssignPermissionsRequest {
        private List<Long> permissionIds;
        private String reason;

        public List<Long> getPermissionIds() { return permissionIds; }
        public void setPermissionIds(List<Long> permissionIds) { this.permissionIds = permissionIds; }
        public String getReason() { return reason; }
        public void setReason(String reason) { this.reason = reason; }
    }

    /**
     * 数据权限配置请求体
     */
    public static class DataScopeRequest {
        private String dataScope;
        private Long departmentId;

        public String getDataScope() { return dataScope; }
        public void setDataScope(String dataScope) { this.dataScope = dataScope; }
        public Long getDepartmentId() { return departmentId; }
        public void setDepartmentId(Long departmentId) { this.departmentId = departmentId; }
    }
}
