package com.erp.inventory.controller;

import com.erp.inventory.dto.*;
import com.erp.inventory.entity.StockWarningRecord;
import com.erp.inventory.entity.StockWarningRule;
import com.erp.inventory.service.StockWarningRuleService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import com.erp.common.core.model.ApiResponse;
import com.erp.common.core.model.PageResponse;

/**
 * 库存预警控制器
 * 提供预警规则管理、预警记录查询、预警统计等接口
 * 
 * API Endpoints:
 * - GET    /stocks/warning/rules           - 预警规则列表
 * - POST   /stocks/warning/rules            - 创建预警规则
 * - GET    /stocks/warning/rules/{id}       - 获取规则详情
 * - PUT    /stocks/warning/rules/{id}       - 更新预警规则
 * - DELETE /stocks/warning/rules/{id}       - 删除预警规则
 * - PUT    /stocks/warning/rules/{id}/toggle - 启用/禁用规则
 * 
 * - GET    /stocks/warning/records          - 预警记录列表
 * - PUT    /stocks/warning/records/{id}/acknowledge - 确认预警
 * - PUT    /stocks/warning/records/{id}/resolve    - 解决预警
 * - PUT    /stocks/warning/records/{id}/ignore     - 忽略预警
 * 
 * - GET    /stocks/warning/stats           - 预警统计
 * - GET    /stocks/warning/pending-count   - 待处理预警数量
 * 
 * - PUT    /stocks/warning/config          - 更新通知配置
 * - POST   /stocks/warning/test            - 测试通知
 * 
 * @author ERP Development
 */
@Slf4j
@RestController
@RequestMapping("/api/stocks/warning")
@RequiredArgsConstructor
public class StockWarningController {

    private final StockWarningRuleService warningRuleService;

    // ==================== 预警规则管理 ====================

    /**
     * 预警规则列表（分页）
     * 
     * GET /stocks/warning/rules?ruleType=low_stock&ruleName=xxx&enabled=1&warehouseId=1&page=1&limit=15
     */
    @GetMapping("/rules")
    public ApiResponse<PageResponse<StockWarningRuleDTO>> listRules(
            @RequestParam(required = false) String ruleType,
            @RequestParam(required = false) String ruleName,
            @RequestParam(required = false) Integer enabled,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "15") Integer limit) {
        try {
            PageResponse<StockWarningRuleDTO> result = warningRuleService.listRules(
                    ruleType, ruleName, enabled, warehouseId, page, limit);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("获取预警规则列表失败", e);
            return ApiResponse.<PageResponse<StockWarningRuleDTO>>error(e.getMessage());
        }
    }

    /**
     * 创建预警规则
     * 
     * POST /stocks/warning/rules
     */
    @PostMapping("/rules")
    public ApiResponse<StockWarningRuleDTO> createRule(@Valid @RequestBody StockWarningRuleRequest request) {
        try {
            StockWarningRule rule = warningRuleService.createRule(request);
            return ApiResponse.success("创建预警规则成功", toRuleDTO(rule));
        } catch (Exception e) {
            log.error("创建预警规则失败", e);
            return ApiResponse.<StockWarningRuleDTO>error(e.getMessage());
        }
    }

    /**
     * 获取预警规则详情
     * 
     * GET /stocks/warning/rules/{id}
     */
    @GetMapping("/rules/{id}")
    public ApiResponse<StockWarningRuleDTO> getRuleById(@PathVariable Long id) {
        try {
            StockWarningRuleDTO rule = warningRuleService.getRuleById(id);
            return ApiResponse.success(rule);
        } catch (Exception e) {
            log.error("获取预警规则详情失败: id={}", id, e);
            return ApiResponse.<StockWarningRuleDTO>error(e.getMessage());
        }
    }

    /**
     * 更新预警规则
     * 
     * PUT /stocks/warning/rules/{id}
     */
    @PutMapping("/rules/{id}")
    public ApiResponse<StockWarningRuleDTO> updateRule(
            @PathVariable Long id,
            @Valid @RequestBody StockWarningRuleRequest request) {
        try {
            StockWarningRule rule = warningRuleService.updateRule(id, request);
            return ApiResponse.success("更新预警规则成功", toRuleDTO(rule));
        } catch (Exception e) {
            log.error("更新预警规则失败: id={}", id, e);
            return ApiResponse.<StockWarningRuleDTO>error(e.getMessage());
        }
    }

    /**
     * 删除预警规则
     * 
     * DELETE /stocks/warning/rules/{id}
     */
    @DeleteMapping("/rules/{id}")
    public ApiResponse<Void> deleteRule(@PathVariable Long id) {
        try {
            warningRuleService.deleteRule(id);
            return ApiResponse.<Void>success("删除预警规则成功", null);
        } catch (Exception e) {
            log.error("删除预警规则失败: id={}", id, e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    /**
     * 启用/禁用预警规则
     * 
     * PUT /stocks/warning/rules/{id}/toggle?enabled=true
     */
    @PutMapping("/rules/{id}/toggle")
    public ApiResponse<Void> toggleRule(@PathVariable Long id, @RequestParam Boolean enabled) {
        try {
            warningRuleService.toggleRule(id, enabled);
            return ApiResponse.<Void>success(enabled ? "启用成功" : "禁用成功", null);
        } catch (Exception e) {
            log.error("切换规则状态失败: id={}, enabled={}", id, enabled, e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    // ==================== 预警记录管理 ====================

    /**
     * 预警记录列表（分页）
     * 
     * GET /stocks/warning/records?skuCode=xxx&warehouseId=1&ruleType=low_stock&status=pending&level=warning&startDate=2024-01-01&endDate=2024-01-31&page=1&limit=15
     */
    @GetMapping("/records")
    public ApiResponse<PageResponse<StockWarningRecordDTO>> listWarningRecords(
            @RequestParam(required = false) String skuCode,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(required = false) String ruleType,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String level,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "15") Integer limit) {
        try {
            StockWarningRecordQueryDTO query = StockWarningRecordQueryDTO.builder()
                    .skuCode(skuCode)
                    .warehouseId(warehouseId)
                    .ruleType(ruleType)
                    .status(status)
                    .level(level)
                    .startDate(startDate)
                    .endDate(endDate)
                    .page(page)
                    .limit(limit)
                    .build();
            PageResponse<StockWarningRecordDTO> result = warningRuleService.listWarningRecords(query);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("获取预警记录列表失败", e);
            return ApiResponse.<PageResponse<StockWarningRecordDTO>>error(e.getMessage());
        }
    }

    /**
     * 确认预警
     * 
     * PUT /stocks/warning/records/{id}/acknowledge
     */
    @PutMapping("/records/{id}/acknowledge")
    public ApiResponse<Void> acknowledgeWarning(@PathVariable Long id) {
        try {
            warningRuleService.acknowledgeWarning(id);
            return ApiResponse.<Void>success("确认预警成功", null);
        } catch (Exception e) {
            log.error("确认预警失败: id={}", id, e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    /**
     * 解决预警
     * 
     * PUT /stocks/warning/records/{id}/resolve
     * Body: { "remark": "已补货" }
     */
    @PutMapping("/records/{id}/resolve")
    public ApiResponse<Void> resolveWarning(@PathVariable Long id, @RequestBody Map<String, String> body) {
        try {
            String remark = body != null ? body.get("remark") : null;
            warningRuleService.resolveWarning(id, remark);
            return ApiResponse.<Void>success("解决预警成功", null);
        } catch (Exception e) {
            log.error("解决预警失败: id={}", id, e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    /**
     * 忽略预警
     * 
     * PUT /stocks/warning/records/{id}/ignore
     */
    @PutMapping("/records/{id}/ignore")
    public ApiResponse<Void> ignoreWarning(@PathVariable Long id) {
        try {
            warningRuleService.ignoreWarning(id);
            return ApiResponse.<Void>success("忽略预警成功", null);
        } catch (Exception e) {
            log.error("忽略预警失败: id={}", id, e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    // ==================== 预警统计 ====================

    /**
     * 预警统计
     * 
     * GET /stocks/warning/stats?startDate=2024-01-01&endDate=2024-01-31
     */
    @GetMapping("/stats")
    public ApiResponse<StockWarningStatsDTO> getWarningStats(
            @RequestParam String startDate,
            @RequestParam String endDate) {
        try {
            StockWarningStatsDTO stats = warningRuleService.getWarningStats(startDate, endDate);
            return ApiResponse.success(stats);
        } catch (Exception e) {
            log.error("获取预警统计失败", e);
            return ApiResponse.<StockWarningStatsDTO>error(e.getMessage());
        }
    }

    /**
     * 待处理预警数量
     * 
     * GET /stocks/warning/pending-count
     */
    @GetMapping("/pending-count")
    public ApiResponse<Map<String, Integer>> getPendingWarningCount() {
        try {
            Integer count = warningRuleService.getPendingWarningCount();
            return ApiResponse.success(Map.of("pendingCount", count));
        } catch (Exception e) {
            log.error("获取待处理预警数量失败", e);
            return ApiResponse.<Map<String, Integer>>error(e.getMessage());
        }
    }

    // ==================== 预警通知配置 ====================

    /**
     * 更新通知配置
     * 
     * PUT /stocks/warning/config
     */
    @PutMapping("/config")
    public ApiResponse<StockWarningRuleDTO> updateNotificationConfig(
            @Valid @RequestBody WarningNotificationConfigRequest request) {
        try {
            StockWarningRule rule = warningRuleService.updateNotificationConfig(request);
            return ApiResponse.success("更新通知配置成功", toRuleDTO(rule));
        } catch (Exception e) {
            log.error("更新通知配置失败", e);
            return ApiResponse.<StockWarningRuleDTO>error(e.getMessage());
        }
    }

    /**
     * 测试通知
     * 
     * POST /stocks/warning/test
     * Body: { "ruleId": 1, "method": "dingtalk" }
     */
    @PostMapping("/test")
    public ApiResponse<Void> testNotification(@RequestBody Map<String, Object> body) {
        try {
            Long ruleId = ((Number) body.get("ruleId")).longValue();
            String method = (String) body.get("method");
            warningRuleService.testNotification(ruleId, method);
            return ApiResponse.<Void>success("测试" + getMethodLabel(method) + "发送成功", null);
        } catch (Exception e) {
            log.error("测试通知失败", e);
            return ApiResponse.<Void>error(e.getMessage());
        }
    }

    // ==================== 辅助方法 ====================

    private StockWarningRuleDTO toRuleDTO(StockWarningRule rule) {
        StockWarningRule.RuleType ruleType = StockWarningRule.RuleType.fromCode(rule.getRuleType());
        String enabledLabel = rule.getEnabled() != null && rule.getEnabled() == 1 ? "启用" : "禁用";

        String notificationMethodsLabel = "";
        if (rule.getNotificationMethods() != null && !rule.getNotificationMethods().isEmpty()) {
            notificationMethodsLabel = java.util.Arrays.stream(rule.getNotificationMethods().split(","))
                    .map(m -> {
                        StockWarningRule.NotificationMethod notificationMethod =
                                StockWarningRule.NotificationMethod.fromCode(m.trim());
                        return notificationMethod != null ? notificationMethod.getLabel() : m.trim();
                    })
                    .collect(java.util.stream.Collectors.joining(", "));
        }

        return StockWarningRuleDTO.builder()
                .id(rule.getId())
                .ruleName(rule.getRuleName())
                .ruleType(rule.getRuleType())
                .ruleTypeLabel(ruleType != null ? ruleType.getLabel() : rule.getRuleType())
                .skuCode(rule.getSkuCode())
                .skuName(rule.getSkuName())
                .warehouseId(rule.getWarehouseId())
                .warehouseName(rule.getWarehouseName())
                .safetyStockMin(rule.getSafetyStockMin())
                .safetyStockMax(rule.getSafetyStockMax())
                .warningThreshold(rule.getWarningThreshold())
                .maxStockThreshold(rule.getMaxStockThreshold())
                .enabled(rule.getEnabled())
                .enabledLabel(enabledLabel)
                .notificationMethods(rule.getNotificationMethods())
                .notificationMethodsLabel(notificationMethodsLabel)
                .notificationEmails(rule.getNotificationEmails())
                .dingtalkWebhook(rule.getDingtalkWebhook())
                .repeatIntervalMinutes(rule.getRepeatIntervalMinutes())
                .remark(rule.getRemark())
                .createdAt(rule.getCreatedAt())
                .updatedAt(rule.getUpdatedAt())
                .createdByName(rule.getCreatedByName())
                .build();
    }

    private String getMethodLabel(String method) {
        if (method == null) return "未知";
        return switch (method) {
            case "system" -> "系统通知";
            case "email" -> "邮件";
            case "dingtalk" -> "钉钉";
            default -> method;
        };
    }
}
