package com.qaup.collision.controller;

import com.qaup.collision.rule.model.entity.SpatialRule;
import com.qaup.collision.rule.model.enums.RuleCategory;
import com.qaup.collision.rule.model.enums.RuleStatus;
import com.qaup.collision.rule.service.RuleConfigurationService;
import com.qaup.collision.rule.service.SpatialRuleService;
import com.qaup.collision.rule.service.SpatialRuleService.RuleValidationResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 空间规则控制器
 * 提供规则管理的REST API接口
 * 
 * @author AI Assistant
 * @version 1.0
 * @since 2025-01-17
 */
@RestController
@RequestMapping("/api/spatial-rules")
@Validated
@CrossOrigin(origins = "*")
public class SpatialRuleController {

    private static final Logger logger = LoggerFactory.getLogger(SpatialRuleController.class);

    @Autowired
    private SpatialRuleService spatialRuleService;
    
    @Autowired
    private RuleConfigurationService ruleConfigurationService;

    // ==================== 规则基础CRUD操作 ====================

    /**
     * 创建新规则
     */
    @PostMapping
    public ResponseEntity<?> createRule(@Valid @RequestBody SpatialRule rule) {
        logger.info("创建新规则: ruleName={}, category={}", rule.getName(), rule.getCategory());
        
        try {
            SpatialRule createdRule = spatialRuleService.createRule(rule);
            return ResponseEntity.status(HttpStatus.CREATED).body(createdRule);
            
        } catch (Exception e) {
            logger.error("创建规则失败", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "创建规则失败", "message", e.getMessage()));
        }
    }

    /**
     * 根据ID获取规则
     */
    @GetMapping("/{ruleId}")
    public ResponseEntity<?> getRuleById(@PathVariable String ruleId) {
        logger.debug("获取规则详情: ruleId={}", ruleId);
        
        Optional<SpatialRule> rule = spatialRuleService.findRuleById(ruleId);
        if (rule.isPresent()) {
            return ResponseEntity.ok(rule.get());
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("error", "规则不存在", "ruleId", ruleId));
        }
    }

    /**
     * 更新规则
     */
    @PutMapping("/{ruleId}")
    public ResponseEntity<?> updateRule(@PathVariable String ruleId, 
                                       @Valid @RequestBody SpatialRule rule) {
        logger.info("更新规则: ruleId={}", ruleId);
        
        try {
            SpatialRule updatedRule = spatialRuleService.updateRule(ruleId, rule);
            return ResponseEntity.ok(updatedRule);
            
        } catch (Exception e) {
            logger.error("更新规则失败: ruleId={}", ruleId, e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "更新规则失败", "message", e.getMessage()));
        }
    }

    /**
     * 删除规则
     */
    @DeleteMapping("/{ruleId}")
    public ResponseEntity<?> deleteRule(@PathVariable String ruleId) {
        logger.info("删除规则: ruleId={}", ruleId);
        
        boolean deleted = spatialRuleService.deleteRule(ruleId);
        if (deleted) {
            return ResponseEntity.ok(Map.of("message", "规则删除成功", "ruleId", ruleId));
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("error", "规则不存在或删除失败", "ruleId", ruleId));
        }
    }

    /**
     * 获取所有规则
     */
    @GetMapping
    public ResponseEntity<List<SpatialRule>> getAllRules(
            @RequestParam(required = false) RuleCategory category,
            @RequestParam(required = false) RuleStatus status,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "priority") String sortBy,
            @RequestParam(defaultValue = "asc") String sortDirection) {
        
        logger.debug("获取规则列表: category={}, status={}, page={}, size={}", category, status, page, size);
        
        try {
            List<SpatialRule> rules;
            
            if (category != null) {
                rules = spatialRuleService.findRulesByCategory(category);
            } else if (status != null) {
                rules = spatialRuleService.findRulesByStatus(status);
            } else {
                rules = spatialRuleService.findAllRules();
            }
            
            // 简单的分页处理（生产环境应使用Spring Data分页）
            int start = page * size;
            int end = Math.min(start + size, rules.size());
            
            if (start < rules.size()) {
                List<SpatialRule> pagedRules = rules.subList(start, end);
                return ResponseEntity.ok(pagedRules);
            } else {
                return ResponseEntity.ok(List.of());
            }
            
        } catch (Exception e) {
            logger.error("获取规则列表失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    // ==================== 规则状态管理 ====================

    /**
     * 启用规则
     */
    @PostMapping("/{ruleId}/enable")
    public ResponseEntity<?> enableRule(@PathVariable String ruleId) {
        logger.info("启用规则: ruleId={}", ruleId);
        
        boolean enabled = spatialRuleService.enableRule(ruleId);
        if (enabled) {
            return ResponseEntity.ok(Map.of("message", "规则启用成功", "ruleId", ruleId));
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "规则启用失败", "ruleId", ruleId));
        }
    }

    /**
     * 禁用规则
     */
    @PostMapping("/{ruleId}/disable")
    public ResponseEntity<?> disableRule(@PathVariable String ruleId) {
        logger.info("禁用规则: ruleId={}", ruleId);
        
        boolean disabled = spatialRuleService.disableRule(ruleId);
        if (disabled) {
            return ResponseEntity.ok(Map.of("message", "规则禁用成功", "ruleId", ruleId));
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "规则禁用失败", "ruleId", ruleId));
        }
    }

    /**
     * 批量启用规则
     */
    @PostMapping("/batch-enable")
    public ResponseEntity<?> enableRules(@RequestBody List<String> ruleIds) {
        logger.info("批量启用规则: count={}", ruleIds.size());
        
        int enabledCount = spatialRuleService.enableRules(ruleIds);
        return ResponseEntity.ok(Map.of("message", "批量启用完成", 
                                       "requestedCount", ruleIds.size(),
                                       "enabledCount", enabledCount));
    }

    /**
     * 批量禁用规则
     */
    @PostMapping("/batch-disable")
    public ResponseEntity<?> disableRules(@RequestBody List<String> ruleIds) {
        logger.info("批量禁用规则: count={}", ruleIds.size());
        
        int disabledCount = spatialRuleService.disableRules(ruleIds);
        return ResponseEntity.ok(Map.of("message", "批量禁用完成", 
                                       "requestedCount", ruleIds.size(),
                                       "disabledCount", disabledCount));
    }

    // ==================== 规则配置管理 ====================

    /**
     * 创建规则模板
     */
    @PostMapping("/templates")
    public ResponseEntity<?> createRuleTemplate(@RequestParam RuleCategory category,
                                                @RequestParam String name,
                                                @RequestParam(required = false) String description) {
        logger.info("创建规则模板: category={}, name={}", category, name);
        
        try {
            SpatialRule template = ruleConfigurationService.createRuleTemplate(category, name, description);
            return ResponseEntity.status(HttpStatus.CREATED).body(template);
            
        } catch (Exception e) {
            logger.error("创建规则模板失败", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "创建规则模板失败", "message", e.getMessage()));
        }
    }

    /**
     * 克隆规则配置
     */
    @PostMapping("/{sourceRuleId}/clone")
    public ResponseEntity<?> cloneRule(@PathVariable String sourceRuleId,
                                      @RequestParam String newRuleId,
                                      @RequestParam String newName) {
        logger.info("克隆规则配置: sourceRuleId={}, newRuleId={}", sourceRuleId, newRuleId);
        
        try {
            SpatialRule clonedRule = ruleConfigurationService.cloneRuleConfiguration(sourceRuleId, newRuleId, newName);
            return ResponseEntity.status(HttpStatus.CREATED).body(clonedRule);
            
        } catch (Exception e) {
            logger.error("克隆规则配置失败", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "克隆规则配置失败", "message", e.getMessage()));
        }
    }

    /**
     * 更新规则基本信息
     */
    @PatchMapping("/{ruleId}/basic-info")
    public ResponseEntity<?> updateRuleBasicInfo(@PathVariable String ruleId,
                                                 @RequestParam(required = false) String name,
                                                 @RequestParam(required = false) String description,
                                                 @RequestParam(required = false) Integer priority) {
        logger.info("更新规则基本信息: ruleId={}", ruleId);
        
        boolean updated = ruleConfigurationService.updateRuleBasicInfo(ruleId, name, description, priority);
        if (updated) {
            return ResponseEntity.ok(Map.of("message", "规则基本信息更新成功", "ruleId", ruleId));
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "规则基本信息更新失败", "ruleId", ruleId));
        }
    }

    /**
     * 配置规则参数
     */
    @PutMapping("/{ruleId}/parameters")
    public ResponseEntity<?> configureRuleParameters(@PathVariable String ruleId,
                                                     @RequestBody Map<String, Object> parameters) {
        logger.info("配置规则参数: ruleId={}, parametersCount={}", ruleId, parameters.size());
        
        boolean configured = ruleConfigurationService.configureRuleParameters(ruleId, parameters);
        if (configured) {
            return ResponseEntity.ok(Map.of("message", "规则参数配置成功", "ruleId", ruleId));
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "规则参数配置失败", "ruleId", ruleId));
        }
    }

    // ==================== 规则验证 ====================

    /**
     * 验证规则配置
     */
    @PostMapping("/{ruleId}/validate")
    public ResponseEntity<RuleValidationResult> validateRule(@PathVariable String ruleId) {
        logger.debug("验证规则配置: ruleId={}", ruleId);
        
        RuleValidationResult validationResult = ruleConfigurationService.validateRuleConfiguration(ruleId);
        return ResponseEntity.ok(validationResult);
    }

    /**
     * 批量验证规则配置
     */
    @PostMapping("/batch-validate")
    public ResponseEntity<Map<String, RuleValidationResult>> batchValidateRules(@RequestBody List<String> ruleIds) {
        logger.info("批量验证规则配置: count={}", ruleIds.size());
        
        Map<String, RuleValidationResult> validationResults = 
                ruleConfigurationService.batchValidateRuleConfigurations(ruleIds);
        
        return ResponseEntity.ok(validationResults);
    }

    /**
     * 检查规则配置冲突
     */
    @GetMapping("/{ruleId}/conflicts")
    public ResponseEntity<List<SpatialRule>> checkRuleConflicts(@PathVariable String ruleId) {
        logger.debug("检查规则配置冲突: ruleId={}", ruleId);
        
        List<SpatialRule> conflicts = ruleConfigurationService.checkConfigurationConflicts(ruleId);
        return ResponseEntity.ok(conflicts);
    }

    // ==================== 统计和分析 ====================

    /**
     * 获取规则统计信息
     */
    @GetMapping("/statistics")
    public ResponseEntity<?> getRuleStatistics() {
        logger.debug("获取规则统计信息");
        
        try {
            Map<RuleCategory, Long> categoryStats = spatialRuleService.getRuleCountByCategory();
            Map<RuleStatus, Long> statusStats = spatialRuleService.getRuleCountByStatus();
            
            Map<String, Object> statistics = Map.of(
                    "categoryStatistics", categoryStats,
                    "statusStatistics", statusStats,
                    "totalRules", categoryStats.values().stream().mapToLong(Long::longValue).sum()
            );
            
            return ResponseEntity.ok(statistics);
            
        } catch (Exception e) {
            logger.error("获取规则统计信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("error", "获取统计信息失败", "message", e.getMessage()));
        }
    }

    /**
     * 获取配置统计信息
     */
    @GetMapping("/configuration-statistics")
    public ResponseEntity<?> getConfigurationStatistics() {
        logger.debug("获取配置统计信息");
        
        try {
            RuleConfigurationService.ConfigurationStatistics stats = 
                    ruleConfigurationService.getConfigurationStatistics();
            
            return ResponseEntity.ok(stats);
            
        } catch (Exception e) {
            logger.error("获取配置统计信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("error", "获取配置统计信息失败", "message", e.getMessage()));
        }
    }

    // ==================== 导入导出 ====================

    /**
     * 导出规则配置
     */
    @GetMapping("/{ruleId}/export")
    public ResponseEntity<?> exportRuleConfiguration(@PathVariable String ruleId) {
        logger.info("导出规则配置: ruleId={}", ruleId);
        
        String configJson = ruleConfigurationService.exportRuleConfiguration(ruleId);
        if (configJson != null) {
            return ResponseEntity.ok(Map.of("ruleId", ruleId, "configuration", configJson));
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("error", "规则不存在或导出失败", "ruleId", ruleId));
        }
    }

    /**
     * 批量导出规则配置
     */
    @PostMapping("/batch-export")
    public ResponseEntity<?> exportRuleConfigurations(@RequestBody List<String> ruleIds) {
        logger.info("批量导出规则配置: count={}", ruleIds.size());
        
        String configJson = ruleConfigurationService.exportRuleConfigurations(ruleIds);
        if (configJson != null) {
            return ResponseEntity.ok(Map.of("ruleCount", ruleIds.size(), "configurations", configJson));
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "批量导出失败"));
        }
    }

    /**
     * 导入规则配置
     */
    @PostMapping("/import")
    public ResponseEntity<?> importRuleConfiguration(@RequestBody String configurationJson) {
        logger.info("导入规则配置");
        
        try {
            List<SpatialRule> importedRules = ruleConfigurationService.importRuleConfiguration(configurationJson);
            return ResponseEntity.ok(Map.of("message", "规则配置导入成功", 
                                           "importedCount", importedRules.size(),
                                           "rules", importedRules));
            
        } catch (Exception e) {
            logger.error("导入规则配置失败", e);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("error", "导入规则配置失败", "message", e.getMessage()));
        }
    }

    // ==================== 异常处理 ====================

    /**
     * 全局异常处理
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<?> handleIllegalArgumentException(IllegalArgumentException e) {
        logger.warn("参数验证失败: {}", e.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(Map.of("error", "参数验证失败", "message", e.getMessage()));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> handleGeneralException(Exception e) {
        logger.error("处理请求时发生异常", e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Map.of("error", "服务器内部错误", "message", "请联系系统管理员"));
    }
} 