package com.mosquito.project.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mosquito.project.dto.ApiResponse;
import com.mosquito.project.permission.ApprovalFlowService;
import com.mosquito.project.permission.RequirePermission;
import com.mosquito.project.service.SystemService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * 系统配置控制器
 */
@RestController
@RequestMapping("/api/v1/system")
public class SystemController {

    private static final Logger log = LoggerFactory.getLogger(SystemController.class);
    private static final String ADMIN_TOKEN_HEADER = "X-Admin-Token";

    // 权限码常量 (使用PRD四段式格式)
    private static final String PERM_SYSTEM_VIEW = "system.index.view.ALL";
    private static final String PERM_SYSTEM_SENSITIVE = "system.sensitive.access.ALL"; // P0修复：敏感接口使用独立权限码
    private static final String PERM_SYSTEM_CONFIG = "system.config.manage.ALL";
    private static final String PERM_SYSTEM_CACHE = "system.cache.manage.ALL";

    // 业务类型常量
    private static final String BIZ_TYPE_SYSTEM_CONFIG = "SYSTEM_CONFIG";
    private static final String BIZ_TYPE_SYSTEM_CONFIG_BATCH = "SYSTEM_CONFIG_BATCH";
    private static final String BIZ_TYPE_SYSTEM_CONFIG_RESET = "SYSTEM_CONFIG_RESET";

    private final SystemService systemService;

    @Autowired(required = false)
    private com.mosquito.project.config.AppConfig appConfig;

    @Autowired(required = false)
    private ApprovalFlowService approvalFlowService;

    public SystemController(SystemService systemService) {
        this.systemService = systemService;
    }

    /**
     * 验证X-Admin-Token并记录审计日志
     */
    private boolean validateAdminToken(HttpServletRequest request, String action) {
        String adminToken = request.getHeader(ADMIN_TOKEN_HEADER);
        if (adminToken == null || adminToken.isBlank()) {
            log.warn("缓存操作失败: 缺少X-Admin-Token, action={}, ip={}", action, getClientIp(request));
            return false;
        }

        // 验证token是否与配置匹配
        String expectedToken = appConfig != null ? appConfig.getCache().getAdminToken() : null;
        if (expectedToken == null || expectedToken.isBlank()) {
            log.error("缓存操作失败: 未配置admin-token, action={}, ip={}", action, getClientIp(request));
            return false;
        }

        if (!expectedToken.equals(adminToken)) {
            log.warn("缓存操作失败: token验证失败, action={}, ip={}", action, getClientIp(request));
            return false;
        }

        // 记录token指纹(只记录前4位和后4位)
        String tokenFingerprint = adminToken.length() > 8
            ? adminToken.substring(0, 4) + "****" + adminToken.substring(adminToken.length() - 4)
            : "****";

        log.info("缓存操作审计: action={}, tokenFingerprint={}, ip={}, userAgent={}",
            action, tokenFingerprint, getClientIp(request), request.getHeader("User-Agent"));

        return true;
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多级代理时取第一个
        if (ip != null && ip.contains(",")) {
            ip = ip.trim().split(",")[0];
        }
        return ip;
    }

    /**
     * 获取系统配置列表
     */
    @GetMapping("/configs")
    @RequirePermission(PERM_SYSTEM_VIEW)
    public ResponseEntity<ApiResponse<Map<String, Object>>> getConfigs(
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String keyword) {

        Map<String, Object> data = systemService.getConfigs(category, keyword);
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 获取单个配置
     */
    @GetMapping("/configs/{key}")
    @RequirePermission(PERM_SYSTEM_VIEW)
    public ResponseEntity<ApiResponse<Map<String, Object>>> getConfigByKey(@PathVariable String key) {
        Map<String, Object> data = systemService.getConfigByKey(key);
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 更新配置（需要审批）
     */
    @PutMapping("/configs/{key}")
    @RequirePermission(PERM_SYSTEM_CONFIG)
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateConfig(
            @PathVariable String key,
            @RequestBody Map<String, String> request,
            HttpServletRequest httpRequest) {

        String value = request.get("value");
        Long currentUserId = getCurrentUserId(httpRequest);

        // 先保存待审批的配置值
        String pendingValue = systemService.savePendingConfig(key, value);

        // 尝试提交审批
        if (approvalFlowService != null && currentUserId != null) {
            try {
                // 将配置信息序列化为业务数据
                String bizData = String.format("{\"key\":\"%s\",\"oldValue\":\"%s\",\"newValue\":\"%s\"}",
                    key, systemService.getConfigByKey(key).get("value"), value);

                Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
                    "SYSTEM_CONFIG",  // 触发事件
                    BIZ_TYPE_SYSTEM_CONFIG, // 业务类型
                    (long) key.hashCode(),  // 业务ID（使用key的hash作为唯一标识）
                    "系统配置审批: " + key, // 审批标题
                    currentUserId,    // 申请人ID
                    "申请更新配置 " + key, // 申请原因
                    bizData
                );

                log.info("系统配置已提交审批: key={}, recordId={}", key, approvalResult.get("recordId"));

                Map<String, Object> result = new HashMap<>();
                result.put("key", key);
                result.put("pendingValue", pendingValue);
                result.put("recordId", approvalResult.get("recordId"));
                result.put("status", "PENDING_APPROVAL");
                result.put("message", "配置已提交审批，审批通过后生效");

                return ResponseEntity.ok(ApiResponse.success(result, "配置已提交审批"));
            } catch (Exception e) {
                log.error("提交审批失败，拒绝执行敏感操作: key={}, error={}", key, e.getMessage());
                // 审批失败，拒绝执行敏感操作（Fail-Closed）
                return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作，请稍后重试"));
            }
        }

        // 如果没有审批服务，返回409（Fail-Closed原则）
        return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作"));
    }

    /**
     * 批量更新配置（需要审批）
     */
    @PutMapping("/configs/batch")
    @RequirePermission(PERM_SYSTEM_CONFIG)
    public ResponseEntity<ApiResponse<Map<String, Object>>> batchUpdateConfigs(
            @RequestBody Map<String, Object> request,
            HttpServletRequest httpRequest) {
        @SuppressWarnings("unchecked")
        Map<String, Object> configs = (Map<String, Object>) request.get("configs");
        Long currentUserId = getCurrentUserId(httpRequest);

        // 提交审批申请，审批通过后生效
        if (approvalFlowService != null) {
            try {
                // 包装configs为{"configs": {...}}结构，与回调处理保持一致
                Map<String, Object> bizDataMap = new HashMap<>();
                bizDataMap.put("configs", configs);
                String bizData = new ObjectMapper().writeValueAsString(bizDataMap);
                Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
                    "SYSTEM_CONFIG",
                    BIZ_TYPE_SYSTEM_CONFIG_BATCH,
                    0L,
                    "批量系统配置更新审批",
                    currentUserId,
                    (String) request.getOrDefault("reason", "批量更新系统配置"),
                    bizData
                );

                Map<String, Object> result = new HashMap<>();
                result.put("approvalRecordId", approvalResult.get("recordId"));
                result.put("message", "配置更新已提交审批，审批通过后生效");
                return ResponseEntity.ok(ApiResponse.success(result, "提交审批成功"));
            } catch (Exception e) {
                log.error("提交批量配置更新审批失败: {}", e.getMessage());
                return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作"));
            }
        }
        // 没有审批服务时，Fail-Closed拒绝执行
        return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作"));
    }

    /**
     * 重置配置（需要审批）
     */
    @PostMapping("/configs/{key}/reset")
    @RequirePermission(PERM_SYSTEM_CONFIG)
    public ResponseEntity<ApiResponse<Map<String, Object>>> resetConfig(
            @PathVariable String key,
            HttpServletRequest httpRequest) {
        Long currentUserId = getCurrentUserId(httpRequest);

        // 提交审批申请，审批通过后生效
        if (approvalFlowService != null) {
            try {
                // 统一使用 key 字段名，与回调处理保持一致
                Map<String, Object> bizData = new HashMap<>();
                bizData.put("key", key);
                bizData.put("action", "reset");

                Map<String, Object> approvalResult = approvalFlowService.submitApprovalByEvent(
                    "SYSTEM_CONFIG",
                    BIZ_TYPE_SYSTEM_CONFIG_RESET,
                    0L,
                    "系统配置重置审批: " + key,
                    currentUserId,
                    "重置系统配置: " + key,
                    new ObjectMapper().writeValueAsString(bizData)
                );

                Map<String, Object> result = new HashMap<>();
                result.put("approvalRecordId", approvalResult.get("recordId"));
                result.put("message", "配置重置已提交审批，审批通过后生效");
                return ResponseEntity.ok(ApiResponse.success(result, "提交审批成功"));
            } catch (Exception e) {
                log.error("提交配置重置审批失败: {}", e.getMessage());
                return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作"));
            }
        }
        // 没有审批服务时，Fail-Closed拒绝执行
        return ResponseEntity.status(409).body(ApiResponse.error(409, "审批服务不可用，无法执行敏感操作"));
    }

    /**
     * 清除缓存 - 需要X-Admin-Token认证
     */
    @PostMapping("/cache/clear")
    @RequirePermission(PERM_SYSTEM_CACHE)
    public ResponseEntity<ApiResponse<Void>> clearCache(
            @RequestParam(required = false) String type,
            HttpServletRequest request) {

        if (!validateAdminToken(request, "cache_clear")) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "缓存清除失败: 缺少有效的X-Admin-Token"));
        }

        boolean success = systemService.clearCache(type);
        if (success) {
            log.info("缓存清除成功: type={}, operatorIp={}", type, getClientIp(request));
            return ResponseEntity.ok(ApiResponse.success(null, "缓存清除成功"));
        }
        return ResponseEntity.ok(ApiResponse.error(400, "缓存清除失败"));
    }

    /**
     * 获取缓存列表
     */
    @GetMapping("/cache/list")
    @RequirePermission(PERM_SYSTEM_CACHE)
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCacheList() {
        List<Map<String, Object>> data = systemService.getCacheList();
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 缓存键级失效 - 需要X-Admin-Token认证
     * PRD要求: 支持key级别的失效接口
     */
    @DeleteMapping("/cache/evict")
    @RequirePermission(PERM_SYSTEM_CACHE)
    public ResponseEntity<ApiResponse<Void>> evictCache(
            @RequestParam String cacheName,
            @RequestParam String key,
            HttpServletRequest request) {

        if (!validateAdminToken(request, "cache_evict")) {
            return ResponseEntity.status(401).body(ApiResponse.error(401, "缓存键失效失败: 缺少有效的X-Admin-Token"));
        }

        boolean success = systemService.evictCache(cacheName, key);
        if (success) {
            log.info("缓存键失效成功: cacheName={}, key={}, operatorIp={}", cacheName, key, getClientIp(request));
            return ResponseEntity.ok(ApiResponse.success(null, "缓存键失效成功"));
        }
        return ResponseEntity.ok(ApiResponse.error(400, "缓存键失效失败: 缓存不存在"));
    }

    /**
     * 获取系统信息
     * P0修复：敏感接口使用独立敏感权限码
     */
    @GetMapping("/info")
    @RequirePermission(PERM_SYSTEM_SENSITIVE)
    public ResponseEntity<ApiResponse<Map<String, Object>>> getSystemInfo() {
        Map<String, Object> data = systemService.getSystemInfo();
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 获取当前用户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();
        } else if (userIdObj instanceof String) {
            try {
                return Long.parseLong((String) userIdObj);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
}
