package com.mosquito.project.permission;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mosquito.project.dto.ApiResponse;
import com.mosquito.project.persistence.entity.UserTagEntity;
import com.mosquito.project.permission.entity.SysUserEntity;
import com.mosquito.project.permission.entity.UserComplaintEntity;
import com.mosquito.project.service.AuditService;
import com.mosquito.project.service.SensitiveMaskingService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 用户权限控制器 - 处理用户角色分配和用户管理（数据库化版本）
 */
@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private final UserRoleRepository userRoleRepository;
    private final RoleRepository roleRepository;
    private final SysUserService sysUserService;
    private final PermissionCheckService permissionCheckService;
    private final SensitiveMaskingService sensitiveMaskingService;
    private final ApprovalFlowService approvalFlowService;
    private final AuditService auditService;
    private final ObjectMapper objectMapper;
    private final PasswordEncoder passwordEncoder;
    private final com.mosquito.project.persistence.repository.UserTagRepository userTagRepository;
    private final UserComplaintRepository userComplaintRepository;

    // 业务类型常量
    private static final String BIZ_TYPE_ROLE_CHANGE = "ROLE_CHANGE";
    private static final String BIZ_TYPE_USER_FREEZE = "USER_FREEZE";
    private static final String BIZ_TYPE_USER_UNFREEZE = "USER_UNFREEZE";
    private static final String BIZ_TYPE_USER_DELETE = "USER_DELETE";
    private static final String BIZ_TYPE_SENSITIVE_EXPORT = "SENSITIVE_EXPORT";
    private static final String SUPER_ADMIN_ROLE = "super_admin";

    public UserController(UserRoleRepository userRoleRepository, RoleRepository roleRepository,
                         SysUserService sysUserService, PermissionCheckService permissionCheckService,
                         SensitiveMaskingService sensitiveMaskingService,
                         ApprovalFlowService approvalFlowService,
                         AuditService auditService,
                         ObjectMapper objectMapper,
                         PasswordEncoder passwordEncoder,
                         com.mosquito.project.persistence.repository.UserTagRepository userTagRepository,
                         UserComplaintRepository userComplaintRepository) {
        this.userRoleRepository = userRoleRepository;
        this.roleRepository = roleRepository;
        this.sysUserService = sysUserService;
        this.permissionCheckService = permissionCheckService;
        this.sensitiveMaskingService = sensitiveMaskingService;
        this.approvalFlowService = approvalFlowService;
        this.auditService = auditService;
        this.objectMapper = objectMapper;
        this.passwordEncoder = passwordEncoder;
        this.userTagRepository = userTagRepository;
        this.userComplaintRepository = userComplaintRepository;
    }

    /**
     * 判断当前用户是否为超级管理员
     */
    private boolean isSuperAdmin(HttpServletRequest httpRequest) {
        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return false;
        }
        // 查询用户角色
        List<String> userRoles = userRoleRepository.findRolesByUserId(userId);
        return userRoles.contains(SUPER_ADMIN_ROLE);
    }

    /**
     * 获取当前用户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;
    }

    private String getCurrentUserName(HttpServletRequest request) {
        Object userNameObj = request.getAttribute("userName");
        if (userNameObj != null) {
            return userNameObj.toString();
        }
        return "system";
    }

    /**
     * 获取用户列表（支持分页和筛选，带数据权限+敏感脱敏）
     */
    @GetMapping
    @RequirePermission("user.index.view.ALL")
    public ApiResponse<Map<String, Object>> listUsers(
            @RequestParam(required = false, defaultValue = "1") Integer page,
            @RequestParam(required = false, defaultValue = "10") Integer size,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String keyword,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        var pagedResult = sysUserService.listUsers(page, size, status, keyword, currentUserId);

        // 对列表中的敏感字段进行脱敏
        List<Map<String, Object>> items = pagedResult.getContent().stream()
                .map(user -> maskUserFields(toMap(user), currentUserId))
                .toList();

        Map<String, Object> result = new HashMap<>();
        result.put("items", items);
        result.put("total", pagedResult.getTotalElements());
        result.put("page", page);
        result.put("size", size);

        return ApiResponse.success(result);
    }

    /**
     * 创建用户
     */
    @PostMapping
    @RequirePermission("user.index.create.ALL")
    public ApiResponse<Map<String, Object>> createUser(@RequestBody Map<String, Object> userData, HttpServletRequest request) {
        Long currentUserId = getCurrentUserId(request);

        SysUserEntity user = new SysUserEntity();
        user.setUsername((String) userData.get("username"));
        // 密码必须哈希存储，使用BCrypt加密
        String password = (String) userData.get("password");
        if (password != null && !password.isEmpty()) {
            user.setPasswordHash(passwordEncoder.encode(password));
        }
        user.setEmail((String) userData.get("email"));
        user.setPhone((String) userData.get("phone"));
        user.setRealName((String) userData.get("realName"));
        if (userData.get("departmentId") != null) {
            user.setDepartmentId(((Number) userData.get("departmentId")).longValue());
        }
        user.setStatus((String) userData.getOrDefault("status", "ACTIVE"));

        SysUserEntity created = sysUserService.createUser(user);

        Map<String, Object> result = new HashMap<>();
        result.put("id", created.getId());
        result.put("username", created.getUsername());

        return ApiResponse.success(result, "用户创建成功");
    }

    /**
     * 更新用户
     */
    @PutMapping("/{userId}")
    @RequirePermission("user.index.update.ALL")
    public ApiResponse<Void> updateUser(@PathVariable Long userId, @RequestBody Map<String, Object> userData, HttpServletRequest request) {
        Long currentUserId = getCurrentUserId(request);

        Optional<SysUserEntity> existingOpt = sysUserService.getUserById(userId);
        if (existingOpt.isEmpty()) {
            return ApiResponse.error(404, "用户不存在");
        }

        SysUserEntity existing = existingOpt.get();
        if (userData.containsKey("email")) {
            existing.setEmail((String) userData.get("email"));
        }
        if (userData.containsKey("phone")) {
            existing.setPhone((String) userData.get("phone"));
        }
        if (userData.containsKey("realName")) {
            existing.setRealName((String) userData.get("realName"));
        }
        if (userData.containsKey("departmentId")) {
            existing.setDepartmentId(((Number) userData.get("departmentId")).longValue());
        }
        if (userData.containsKey("status")) {
            existing.setStatus((String) userData.get("status"));
        }

        sysUserService.updateUser(userId, existing);

        return ApiResponse.success(null, "用户更新成功");
    }

    /**
     * 删除用户（需要审批）
     */
    @DeleteMapping("/{userId}")
    @RequirePermission("user.index.delete.ALL")
    public ApiResponse<Map<String, Object>> deleteUser(@PathVariable Long userId, HttpServletRequest request) {
        Long currentUserId = getCurrentUserId(request);

        Optional<SysUserEntity> existing = sysUserService.getUserById(userId);
        if (existing.isEmpty()) {
            return ApiResponse.error(404, "用户不存在");
        }

        SysUserEntity user = existing.get();

        // 检查是否为紧急绕过（仅super_admin可绕过审批）
        String emergency = request.getHeader("X-Emergency-Bypass");
        boolean isSuperAdmin = isSuperAdmin(request);

        if (isSuperAdmin && "true".equals(emergency)) {
            // 紧急绕过审批，直接删除并记录审计日志
            sysUserService.deleteUser(userId);
            auditService.log(currentUserId.toString(), getCurrentUserName(request),
                "USER_DELETE_EMERGENCY", String.valueOf(userId), null);
            return ApiResponse.success(null, "用户删除成功（紧急绕过）");
        }

        // 正常流程：提交审批
        try {
            String bizData = String.format("{\"userId\":%d,\"username\":\"%s\",\"reason\":\"用户删除\"}",
                userId, user.getUsername());

            Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
                "USER_DELETE",
                BIZ_TYPE_USER_DELETE,
                userId,
                "用户删除审批: " + user.getUsername(),
                currentUserId,
                "申请删除用户: " + user.getUsername(),
                bizData
            );

            Map<String, Object> result = new HashMap<>();
            result.put("userId", userId);
            result.put("recordId", approvalResult.get("recordId"));
            result.put("status", "PENDING_APPROVAL");
            result.put("message", "删除申请已提交审批，审批通过后用户将被删除");

            return ApiResponse.success(result, "删除申请已提交审批");
        } catch (Exception e) {
            // 审批服务异常，拒绝执行（Fail-Closed）
            return ApiResponse.error(409, "审批服务不可用，无法执行敏感操作");
        }
    }

    /**
     * 导出用户（需要审批）
     */
    @GetMapping("/export")
    @RequirePermission("user.index.export.ALL")
    public ResponseEntity<byte[]> exportUsers(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);

        // 检查用户是否有查看敏感数据明文的权限
        boolean hasSensitiveAccess = permissionCheckService != null &&
            permissionCheckService.hasPermission(currentUserId, "system.sensitive.access.ALL");

        // 检查是否有已批准的敏感导出审批记录
        boolean hasApprovedExport = false;
        if (approvalFlowService != null && currentUserId != null) {
            try {
                hasApprovedExport = approvalFlowService.hasApprovedExport(currentUserId);
            } catch (Exception e) {
                // 审批服务异常，拒绝导出
                return ResponseEntity.status(org.springframework.http.HttpStatus.CONFLICT).build();
            }
        }

        if (!hasApprovedExport) {
            // 无审批记录或审批未通过，拒绝导出
            return ResponseEntity.status(org.springframework.http.HttpStatus.CONFLICT).build();
        }

        var pagedResult = sysUserService.listUsers(1, 10000, status, keyword, currentUserId);

        StringBuilder csv = new StringBuilder();
        csv.append("ID,用户名,邮箱,手机号,真实姓名,状态,认证状态,创建时间\n");

        for (SysUserEntity user : pagedResult.getContent()) {
            csv.append(user.getId()).append(",");
            csv.append(user.getUsername()).append(",");
            // 根据权限决定是否脱敏
            String emailValue;
            String phoneValue;
            if (hasSensitiveAccess) {
                // 有权限，导出明文
                emailValue = user.getEmail() != null ? user.getEmail() : "";
                phoneValue = user.getPhone() != null ? user.getPhone() : "";
            } else {
                // 无权限，使用脱敏服务（使用双参数版本确保脱敏）
                emailValue = user.getEmail() != null ?
                    sensitiveMaskingService.maskEmail(user.getEmail(), "default") : "";
                phoneValue = user.getPhone() != null ?
                    sensitiveMaskingService.maskPhone(user.getPhone(), "default") : "";
            }
            csv.append(emailValue).append(",");
            csv.append(phoneValue).append(",");
            csv.append(user.getRealName() != null ? user.getRealName() : "").append(",");
            csv.append(user.getStatus() != null ? user.getStatus() : "").append(",");
            csv.append(user.getIsCertified() != null && user.getIsCertified() ? "已认证" : "未认证").append(",");
            csv.append(user.getCreatedAt() != null ? user.getCreatedAt().toString() : "").append("\n");
        }

        byte[] body = csv.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
        headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"users_export.csv\"");

        return new ResponseEntity<>(body, headers, org.springframework.http.HttpStatus.OK);
    }

    /**
     * 实名认证（certify的别名）
     */
    @PostMapping("/{userId}/verify")
    @RequirePermission("user.index.certify.ALL")
    public ApiResponse<Void> verifyRealName(@PathVariable Long userId, @RequestBody Map<String, Object> verifyData, HttpServletRequest request) {
        Long currentUserId = getCurrentUserId(request);

        Optional<SysUserEntity> existing = sysUserService.getUserById(userId);
        if (existing.isEmpty()) {
            return ApiResponse.error(404, "用户不存在");
        }

        SysUserEntity user = existing.get();
        user.setRealName((String) verifyData.getOrDefault("realName", user.getRealName()));
        user.setIsCertified(true);
        sysUserService.updateUser(userId, user);

        return ApiResponse.success(null, "实名认证成功");
    }

    /**
     * 获取用户详情（带数据权限检查+敏感脱敏）
     */
    @GetMapping("/{userId}")
    @RequirePermission("user.index.view.ALL")
    public ApiResponse<Map<String, Object>> getUserDetail(@PathVariable Long userId, HttpServletRequest request) {
        Long currentUserId = getCurrentUserId(request);

        // 数据权限检查
        if (currentUserId != null) {
            Optional<SysUserEntity> targetUser = sysUserService.getUserById(userId);
            if (targetUser.isPresent()) {
                SysUserEntity user = targetUser.get();
                boolean hasAccess = permissionCheckService.canAccessData(
                    currentUserId,
                    user.getDepartmentId(),
                    user.getId(),
                    permissionCheckService.getUserDepartmentId(currentUserId)
                );
                if (!hasAccess) {
                    return ApiResponse.error(403, "无权限访问该用户数据");
                }
                // 对敏感字段进行脱敏后返回
                return ApiResponse.success(maskUserFields(toMap(user), currentUserId));
            }
            return ApiResponse.error(404, "用户不存在");
        }

        return sysUserService.getUserById(userId)
                .map(user -> ApiResponse.success(maskUserFields(toMap(user), currentUserId)))
                .orElse(ApiResponse.error(404, "用户不存在"));
    }

    /**
     * 将用户实体转换为Map
     */
    private Map<String, Object> toMap(SysUserEntity user) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        map.put("realName", user.getRealName());
        map.put("email", user.getEmail());
        map.put("phone", user.getPhone());
        map.put("departmentId", user.getDepartmentId());
        map.put("status", user.getStatus());
        map.put("isCertified", user.getIsCertified());
        map.put("isBlacklisted", user.getIsBlacklisted());
        map.put("lastLoginAt", user.getLastLoginAt());
        map.put("createdAt", user.getCreatedAt());
        return map;
    }

    /**
     * 对用户敏感字段进行脱敏
     */
    private Map<String, Object> maskUserFields(Map<String, Object> user, Long currentUserId) {
        Map<String, String> sensitiveFields = new HashMap<>();
        sensitiveFields.put("phone", "phone");
        sensitiveFields.put("email", "email");
        sensitiveMaskingService.maskFields(user, sensitiveFields, currentUserId);
        return user;
    }

    /**
     * 冻结用户 - 改为提交审批申请
     */
    @PostMapping("/{userId}/freeze")
    @RequirePermission("user.index.freeze.ALL")
    public ApiResponse<Map<String, Object>> freezeUser(
            @PathVariable Long userId,
            @RequestBody(required = false) Map<String, String> request,
            HttpServletRequest httpRequest) {
        try {
            Long currentUserId = getCurrentUserId(httpRequest);
            if (currentUserId == null) {
                return ApiResponse.error(401, "未获取到用户信息");
            }

            // 检查是否为紧急绕过（仅super_admin可使用）
            boolean isEmergency = request != null && "true".equalsIgnoreCase(request.get("emergency"));
            if (isEmergency && !isSuperAdmin(httpRequest)) {
                return ApiResponse.error(403, "仅超级管理员可使用紧急冻结");
            }

            // 构建审批申请
            String applyReason = request != null ? request.get("reason") : "用户冻结操作";

            // 构造业务数据
            Map<String, Object> bizData = new HashMap<>();
            bizData.put("userId", userId);
            bizData.put("reason", applyReason);
            bizData.put("emergency", isEmergency);

            // 获取默认的冻结审批流程（需要预先配置）
            Long flowId = getFreezeFlowId();

            // P0修复：如果没有配置审批流程且非紧急绕过，禁止直接执行
            if (flowId == null && !isEmergency) {
                return ApiResponse.error(409, "审批流程未配置，请联系管理员配置后再操作");
            }

            if (flowId != null) {
                // 提交审批
                Map<String, Object> result = approvalFlowService.submitApprovalWithData(
                    flowId,
                    BIZ_TYPE_USER_FREEZE,
                    userId,
                    "用户冻结审批",
                    currentUserId,
                    applyReason,
                    toJson(bizData)
                );
                return ApiResponse.success(result, "已提交冻结审批申请");
            } else {
                // 紧急绕过：直接执行并记录审计日志
                boolean success = sysUserService.freezeUser(userId);
                if (success) {
                    // 记录紧急操作审计日志
                    Map<String, Object> details = new HashMap<>();
                    details.put("reason", applyReason);
                    details.put("ip", httpRequest.getRemoteAddr());
                    auditService.log(currentUserId.toString(), getCurrentUserName(httpRequest),
                        "EMERGENCY_FREEZE", userId, details);
                    return ApiResponse.success(null, "用户已冻结（紧急绕过）");
                }
                return ApiResponse.error(404, "用户不存在");
            }
        } catch (IllegalArgumentException e) {
            return ApiResponse.error(400, e.getMessage());
        }
    }

    /**
     * 解冻用户 - 改为提交审批申请
     */
    @PostMapping("/{userId}/unfreeze")
    @RequirePermission("user.index.unfreeze.ALL")
    public ApiResponse<Map<String, Object>> unfreezeUser(
            @PathVariable Long userId,
            @RequestBody(required = false) Map<String, String> request,
            HttpServletRequest httpRequest) {
        try {
            Long currentUserId = getCurrentUserId(httpRequest);
            if (currentUserId == null) {
                return ApiResponse.error(401, "未获取到用户信息");
            }

            // 检查是否为紧急绕过（仅super_admin可使用）
            boolean isEmergency = request != null && "true".equalsIgnoreCase(request.get("emergency"));
            if (isEmergency && !isSuperAdmin(httpRequest)) {
                return ApiResponse.error(403, "仅超级管理员可使用紧急解冻");
            }

            // 构建审批申请
            String applyReason = request != null ? request.get("reason") : "用户解冻操作";

            // 构造业务数据
            Map<String, Object> bizData = new HashMap<>();
            bizData.put("userId", userId);
            bizData.put("reason", applyReason);
            bizData.put("emergency", isEmergency);

            // 获取默认的解冻审批流程（需要预先配置）
            Long flowId = getUnfreezeFlowId();

            // P0修复：如果没有配置审批流程且非紧急绕过，禁止直接执行
            if (flowId == null && !isEmergency) {
                return ApiResponse.error(409, "审批流程未配置，请联系管理员配置后再操作");
            }

            if (flowId != null) {
                // 提交审批
                Map<String, Object> result = approvalFlowService.submitApprovalWithData(
                    flowId,
                    BIZ_TYPE_USER_UNFREEZE,
                    userId,
                    "用户解冻审批",
                    currentUserId,
                    applyReason,
                    toJson(bizData)
                );
                return ApiResponse.success(result, "已提交解冻审批申请");
            } else {
                // 紧急绕过：直接执行并记录审计日志
                boolean success = sysUserService.unfreezeUser(userId);
                if (success) {
                    // 记录紧急操作审计日志
                    Map<String, Object> details = new HashMap<>();
                    details.put("reason", applyReason);
                    details.put("ip", httpRequest.getRemoteAddr());
                    auditService.log(currentUserId.toString(), getCurrentUserName(httpRequest),
                        "EMERGENCY_UNFREEZE", userId, details);
                    return ApiResponse.success(null, "用户已解冻（紧急绕过）");
                }
                return ApiResponse.error(404, "用户不存在");
            }
        } catch (IllegalArgumentException e) {
            return ApiResponse.error(400, e.getMessage());
        }
    }

    /**
     * 获取冻结审批流程ID
     * 从数据库查询配置的审批流程，如果未配置则返回null
     */
    private Long getFreezeFlowId() {
        // 使用触发事件查询已启用的审批流程
        var flow = approvalFlowService.getFlowByTriggerEvent("USER_FREEZE");
        return flow != null ? flow.getId() : null;
    }

    /**
     * 获取解冻审批流程ID
     * 从数据库查询配置的审批流程，如果未配置则返回null
     */
    private Long getUnfreezeFlowId() {
        // 使用触发事件查询已启用的审批流程
        var flow = approvalFlowService.getFlowByTriggerEvent("USER_UNFREEZE");
        return flow != null ? flow.getId() : null;
    }

    /**
     * 对象转JSON
     */
    private String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            return "{}";
        }
    }

    /**
     * 批量冻结用户 - 强制走审批流程
     */
    @PostMapping("/batch-freeze")
    @RequirePermission("user.index.freeze.ALL")
    public ApiResponse<Map<String, Object>> batchFreezeUsers(
            @RequestBody List<Long> userIds,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }

        // 获取冻结审批流程
        Long flowId = getFreezeFlowId();
        if (flowId == null) {
            return ApiResponse.error(400, "未配置冻结审批流程，请先在审批中心配置");
        }

        int successCount = 0;
        List<String> errors = new ArrayList<>();
        for (Long userId : userIds) {
            try {
                // 构造业务数据
                Map<String, Object> bizData = new HashMap<>();
                bizData.put("userId", userId);
                bizData.put("reason", "批量冻结");

                // 提交审批申请
                approvalFlowService.submitApprovalWithData(
                    flowId,
                    BIZ_TYPE_USER_FREEZE,
                    userId,
                    "批量用户冻结审批",
                    currentUserId,
                    "批量冻结用户",
                    toJson(bizData)
                );
                successCount++;
            } catch (Exception e) {
                errors.add("用户ID " + userId + ": " + e.getMessage());
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("successCount", successCount);
        result.put("totalCount", userIds.size());
        result.put("pendingApprovalCount", successCount);
        result.put("errors", errors);
        result.put("message", "已提交" + successCount + "个冻结审批申请");
        return ApiResponse.success(result);
    }

    /**
     * 批量解冻用户 - 强制走审批流程
     */
    @PostMapping("/batch-unfreeze")
    @RequirePermission("user.index.unfreeze.ALL")
    public ApiResponse<Map<String, Object>> batchUnfreezeUsers(
            @RequestBody List<Long> userIds,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);
        if (currentUserId == null) {
            return ApiResponse.error(401, "未获取到用户信息");
        }

        // 获取解冻审批流程
        Long flowId = getUnfreezeFlowId();
        if (flowId == null) {
            return ApiResponse.error(400, "未配置解冻审批流程，请先在审批中心配置");
        }

        int successCount = 0;
        List<String> errors = new ArrayList<>();
        for (Long userId : userIds) {
            try {
                // 构造业务数据
                Map<String, Object> bizData = new HashMap<>();
                bizData.put("userId", userId);
                bizData.put("reason", "批量解冻");

                // 提交审批申请
                approvalFlowService.submitApprovalWithData(
                    flowId,
                    BIZ_TYPE_USER_UNFREEZE,
                    userId,
                    "批量用户解冻审批",
                    currentUserId,
                    "批量解冻用户",
                    toJson(bizData)
                );
                successCount++;
            } catch (Exception e) {
                errors.add("用户ID " + userId + ": " + e.getMessage());
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("successCount", successCount);
        result.put("totalCount", userIds.size());
        result.put("pendingApprovalCount", successCount);
        result.put("errors", errors);
        result.put("message", "已提交" + successCount + "个解冻审批申请");
        return ApiResponse.success(result);
    }

    /**
     * 实名认证
     */
    @PostMapping("/{userId}/certify")
    @RequirePermission("user.index.certify.ALL")
    public ApiResponse<Void> certifyUser(@PathVariable Long userId) {
        boolean success = sysUserService.certifyUser(userId);
        if (success) {
            return ApiResponse.success(null, "用户已实名认证");
        }
        return ApiResponse.error(404, "用户不存在");
    }

    /**
     * 添加到黑名单
     */
    @PostMapping("/{userId}/blacklist")
    @RequirePermission("user.index.update.ALL")
    public ApiResponse<Void> addToBlacklist(@PathVariable Long userId) {
        boolean success = sysUserService.addToBlacklist(userId);
        if (success) {
            return ApiResponse.success(null, "用户已加入黑名单");
        }
        return ApiResponse.error(404, "用户不存在");
    }

    /**
     * 从黑名单移除
     */
    @PostMapping("/{userId}/unblacklist")
    @RequirePermission("user.index.update.ALL")
    public ApiResponse<Void> removeFromBlacklist(@PathVariable Long userId) {
        boolean success = sysUserService.removeFromBlacklist(userId);
        if (success) {
            return ApiResponse.success(null, "用户已从黑名单移除");
        }
        return ApiResponse.error(404, "用户不存在");
    }

    /**
     * 添加到白名单
     */
    @PostMapping("/{userId}/whitelist")
    @RequirePermission("user.whitelist.add.ALL")
    public ApiResponse<Void> addToWhitelist(@PathVariable Long userId) {
        boolean success = sysUserService.addToWhitelist(userId);
        if (success) {
            return ApiResponse.success(null, "用户已加入白名单");
        }
        return ApiResponse.error(404, "用户不存在");
    }

    /**
     * 从白名单移除
     */
    @PostMapping("/{userId}/unwhitelist")
    @RequirePermission("user.whitelist.remove.ALL")
    public ApiResponse<Void> removeFromWhitelist(@PathVariable Long userId) {
        boolean success = sysUserService.removeFromWhitelist(userId);
        if (success) {
            return ApiResponse.success(null, "用户已从白名单移除");
        }
        return ApiResponse.error(404, "用户不存在");
    }

    /**
     * 调整用户积分
     */
    @PostMapping("/{userId}/points/adjust")
    @RequirePermission("user.points.adjust.ALL")
    public ApiResponse<Map<String, Object>> adjustPoints(
            @PathVariable Long userId,
            @RequestBody AdjustPointsRequest request,
            HttpServletRequest httpRequest) {
        Long operatorId = getCurrentUserId(httpRequest);
        try {
            Long newPoints = sysUserService.adjustPoints(userId, request.getAmount(), request.getReason(), operatorId);
            Map<String, Object> result = new HashMap<>();
            result.put("userId", userId);
            result.put("newPoints", newPoints);
            result.put("adjustAmount", request.getAmount());
            return ApiResponse.success(result, "积分调整成功");
        } catch (IllegalArgumentException e) {
            return ApiResponse.error(400, e.getMessage());
        }
    }

    /**
     * 获取用户积分
     */
    @GetMapping("/{userId}/points")
    @RequirePermission("user.points.view.ALL")
    public ApiResponse<Map<String, Object>> getPoints(@PathVariable Long userId) {
        Long points = sysUserService.getPoints(userId);
        Map<String, Object> result = new HashMap<>();
        result.put("userId", userId);
        result.put("points", points);
        return ApiResponse.success(result);
    }

    /**
     * 获取用户角色
     */
    @GetMapping("/{userId}/roles")
    @RequirePermission("user.role.view.ALL")
    public ResponseEntity<List<String>> getUserRoles(@PathVariable Long userId) {
        List<Long> roleIds = userRoleRepository.findRoleIdsByUserId(userId);
        List<String> roleCodes = roleIds.stream()
                .map(id -> roleRepository.findById(id))
                .filter(java.util.Optional::isPresent)
                .map(java.util.Optional::get)
                .map(SysRole::getRoleCode)
                .toList();
        return ResponseEntity.ok(roleCodes);
    }

    /**
     * 分配角色给用户 - 强制走审批流程
     * PRD要求：角色变更必须走审批，审批通过后才生效
     */
    @PostMapping("/{userId}/roles")
    @RequirePermission("role.index.manage.ALL")
    public ApiResponse<Map<String, Object>> assignRoles(
            @PathVariable Long userId,
            @RequestBody AssignRolesRequest request,
            HttpServletRequest httpRequest) {

        Long operatorId = getCurrentUserId(httpRequest);

        // 检查是否为紧急绕过（仅super_admin可使用）
        boolean isEmergency = request != null && request.getEmergency() != null && request.getEmergency();
        if (isEmergency && !isSuperAdmin(httpRequest)) {
            return ApiResponse.error(403, "仅超级管理员可使用紧急角色变更");
        }

        // 构建待审批的角色变更信息
        List<String> roleNames = new ArrayList<>();
        for (Long roleId : request.getRoleIds()) {
            roleRepository.findById(roleId).ifPresent(role -> roleNames.add(role.getRoleName()));
        }

        try {
            // 将角色ID列表序列化为JSON保存到bizData
            Map<String, Object> roleData = new HashMap<>();
            roleData.put("roleIds", request.getRoleIds());
            roleData.put("roleNames", roleNames);
            roleData.put("emergency", isEmergency);
            String bizData = objectMapper.writeValueAsString(roleData);

            // 提交角色变更审批申请
            String title = String.format("用户角色变更申请 - 用户ID: %d", userId);
            String applyReason = request.getReason() != null ? request.getReason() : "管理员分配角色";

            // 使用触发事件提交审批（带业务数据）
            Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
                "ROLE_CHANGE",
                BIZ_TYPE_ROLE_CHANGE,
                userId,
                title,
                operatorId,
                applyReason,
                bizData
            );

            // 保存待审批的角色信息到审批记录扩展字段
            Long recordId = (Long) approvalResult.get("recordId");

            Map<String, Object> result = new HashMap<>();
            result.put("approvalRecordId", recordId);
            result.put("status", "PENDING");
            result.put("message", "角色变更申请已提交，等待审批");

            return ApiResponse.success(result, "角色变更申请已提交审批");

        } catch (JsonProcessingException e) {
            return ApiResponse.error(400, "角色数据序列化失败");
        } catch (Exception e) {
            // P0修复：审批流程不可用时，禁止直接执行，只允许super_admin紧急绕过
            if (isEmergency) {
                // 紧急绕过：直接执行并记录审计日志
                return executeRoleAssignmentWithAudit(userId, request, operatorId, httpRequest);
            }
            // 非紧急情况返回错误
            return ApiResponse.error(409, "审批流程不可用，请联系管理员配置后再操作");
        }
    }

    /**
     * 直接执行角色分配（审批通过后的回调或紧急绕过模式）
     */
    private ApiResponse<Map<String, Object>> executeRoleAssignment(Long userId, AssignRolesRequest request, Long operatorId) {
        // 删除现有角色关联
        userRoleRepository.deleteByUserId(userId);

        // 创建新的角色关联
        for (Long roleId : request.getRoleIds()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleRepository.save(userRole);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("status", "APPLIED");
        result.put("message", "角色已分配");

        return ApiResponse.success(result, "角色分配成功");
    }

    /**
     * 紧急绕过执行角色分配（带审计日志）
     */
    private ApiResponse<Map<String, Object>> executeRoleAssignmentWithAudit(Long userId, AssignRolesRequest request, Long operatorId, HttpServletRequest httpRequest) {
        // 删除现有角色关联
        userRoleRepository.deleteByUserId(userId);

        // 创建新的角色关联
        for (Long roleId : request.getRoleIds()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleRepository.save(userRole);
        }

        // 记录紧急操作审计日志
        Map<String, Object> details = new HashMap<>();
        details.put("reason", request.getReason());
        details.put("ip", httpRequest.getRemoteAddr());
        auditService.log(operatorId.toString(), getCurrentUserName(httpRequest),
            "EMERGENCY_ROLE_CHANGE", userId, details);

        Map<String, Object> result = new HashMap<>();
        result.put("status", "APPLIED");
        result.put("message", "角色已分配（紧急绕过）");

        return ApiResponse.success(result, "角色分配成功（紧急绕过）");
    }

    /**
     * 角色分配请求
     */
    public static class AssignRolesRequest {
        private List<Long> roleIds;
        private String reason;
        private Boolean emergency;

        public List<Long> getRoleIds() { return roleIds; }
        public void setRoleIds(List<Long> roleIds) { this.roleIds = roleIds; }
        public String getReason() { return reason; }
        public void setReason(String reason) { this.reason = reason; }
        public Boolean getEmergency() { return emergency; }
        public void setEmergency(Boolean emergency) { this.emergency = emergency; }
    }

    /**
     * 积分调整请求
     */
    public static class AdjustPointsRequest {
        private Long amount;
        private String reason;

        public Long getAmount() { return amount; }
        public void setAmount(Long amount) { this.amount = amount; }
        public String getReason() { return reason; }
        public void setReason(String reason) { this.reason = reason; }
    }

    // ========== 用户标签API ==========

    /**
     * 获取用户标签列表
     * 对应权限: user.tag.view
     */
    @GetMapping("/{userId}/tags")
    @RequirePermission("user.tag.view.ALL")
    public ApiResponse<List<Map<String, Object>>> getUserTags(@PathVariable Long userId) {
        List<UserTagEntity> tags = userTagRepository.findByUserId(userId);
        List<Map<String, Object>> result = new ArrayList<>();
        for (UserTagEntity tag : tags) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", tag.getId());
            item.put("tagName", tag.getTagName());
            item.put("tagColor", tag.getTagColor());
            item.put("createdAt", tag.getCreatedAt() != null ? tag.getCreatedAt().toString() : null);
            result.add(item);
        }
        return ApiResponse.success(result);
    }

    /**
     * 添加用户标签
     * 对应权限: user.tag.add
     */
    @PostMapping("/{userId}/tags")
    @RequirePermission("user.tag.add.ALL")
    public ApiResponse<Map<String, Object>> addUserTag(
            @PathVariable Long userId,
            @RequestBody Map<String, Object> request,
            HttpServletRequest httpRequest) {

        Long operatorId = getCurrentUserId(httpRequest);
        String tagName = request.get("tagName") != null ? request.get("tagName").toString() : null;
        String tagColor = request.get("tagColor") != null ? request.get("tagColor").toString() : "#1890ff";

        if (tagName == null || tagName.trim().isEmpty()) {
            return ApiResponse.error(400, "标签名称不能为空");
        }

        // 检查标签是否已存在
        if (userTagRepository.existsByUserIdAndTagName(userId, tagName)) {
            return ApiResponse.error(400, "该标签已存在");
        }

        UserTagEntity tag = new UserTagEntity();
        tag.setUserId(userId);
        tag.setTagName(tagName.trim());
        tag.setTagColor(tagColor);
        tag.setCreatedBy(operatorId);
        tag.setCreatedAt(java.time.LocalDateTime.now());
        tag.setUpdatedAt(java.time.LocalDateTime.now());

        tag = userTagRepository.save(tag);

        // 记录审计日志
        if (auditService != null) {
            Map<String, Object> details = new HashMap<>();
            details.put("action", "ADD_USER_TAG");
            details.put("userId", userId);
            details.put("tagName", tagName);
            details.put("operatorId", operatorId);
            details.put("userName", getCurrentUserName(httpRequest));
            auditService.recordAuditLog(details);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("id", tag.getId());
        result.put("tagName", tag.getTagName());
        result.put("tagColor", tag.getTagColor());

        return ApiResponse.success(result, "标签添加成功");
    }

    /**
     * 删除用户标签
     * 对应权限: user.tag.add
     */
    @DeleteMapping("/{userId}/tags/{tagId}")
    @RequirePermission("user.tag.add.ALL")
    public ApiResponse<Void> deleteUserTag(
            @PathVariable Long userId,
            @PathVariable Long tagId,
            HttpServletRequest httpRequest) {

        Long operatorId = getCurrentUserId(httpRequest);

        Optional<UserTagEntity> optTag = userTagRepository.findById(tagId);
        if (!optTag.isPresent()) {
            return ApiResponse.error(404, "标签不存在");
        }

        UserTagEntity tag = optTag.get();
        if (!tag.getUserId().equals(userId)) {
            return ApiResponse.error(400, "标签与用户不匹配");
        }

        userTagRepository.delete(tag);

        // 记录审计日志
        if (auditService != null) {
            Map<String, Object> details = new HashMap<>();
            details.put("action", "DELETE_USER_TAG");
            details.put("userId", userId);
            details.put("tagId", tagId);
            details.put("tagName", tag.getTagName());
            details.put("operatorId", operatorId);
            details.put("userName", getCurrentUserName(httpRequest));
            auditService.recordAuditLog(details);
        }

        return ApiResponse.success(null, "标签删除成功");
    }

    // ========== 用户投诉API ==========

    /**
     * 获取用户投诉记录列表
     * 对应权限: user.complaint.view
     */
    @GetMapping("/{userId}/complaints")
    @RequirePermission("user.index.view.ALL")
    public ApiResponse<List<Map<String, Object>>> getUserComplaints(@PathVariable Long userId) {
        List<UserComplaintEntity> complaints = userComplaintRepository.findByUserIdOrderByCreatedAtDesc(userId);
        List<Map<String, Object>> result = new ArrayList<>();
        for (UserComplaintEntity complaint : complaints) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", complaint.getId());
            item.put("title", complaint.getTitle());
            item.put("content", complaint.getContent());
            item.put("complainant", complaint.getComplainant());
            item.put("status", complaint.getStatus());
            item.put("createdAt", complaint.getCreatedAt() != null ? complaint.getCreatedAt().toString() : null);
            result.add(item);
        }
        return ApiResponse.success(result);
    }

    /**
     * 添加用户投诉记录
     * 对应权限: user.complaint.add
     */
    @PostMapping("/{userId}/complaints")
    @RequirePermission("user.index.update.ALL")
    public ApiResponse<Map<String, Object>> addUserComplaint(
            @PathVariable Long userId,
            @RequestBody Map<String, Object> request,
            HttpServletRequest httpRequest) {

        Long operatorId = getCurrentUserId(httpRequest);
        String title = request.get("title") != null ? request.get("title").toString() : null;
        String content = request.get("content") != null ? request.get("content").toString() : null;
        String complainant = request.get("complainant") != null ? request.get("complainant").toString() : null;

        if (title == null || title.trim().isEmpty()) {
            return ApiResponse.error(400, "投诉标题不能为空");
        }
        if (content == null || content.trim().isEmpty()) {
            return ApiResponse.error(400, "投诉内容不能为空");
        }

        UserComplaintEntity complaint = new UserComplaintEntity();
        complaint.setUserId(userId);
        complaint.setTitle(title.trim());
        complaint.setContent(content.trim());
        complaint.setComplainant(complainant != null ? complainant.trim() : null);
        complaint.setStatus("待处理");

        complaint = userComplaintRepository.save(complaint);

        // 记录审计日志
        if (auditService != null) {
            Map<String, Object> details = new HashMap<>();
            details.put("action", "ADD_USER_COMPLAINT");
            details.put("userId", userId);
            details.put("complaintId", complaint.getId());
            details.put("operatorId", operatorId);
            details.put("userName", getCurrentUserName(httpRequest));
            auditService.recordAuditLog(details);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("id", complaint.getId());
        result.put("title", complaint.getTitle());
        result.put("content", complaint.getContent());
        result.put("status", complaint.getStatus());
        result.put("createdAt", complaint.getCreatedAt() != null ? complaint.getCreatedAt().toString() : null);

        return ApiResponse.success(result, "投诉记录添加成功");
    }
}
