package com.controllers;




import com.common.entity.ApiResponse;
import com.influx.dto.SyslogQueryDto;
import com.common.service.InfluxSyslogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import com.Modules.NormalData.LogNormalProcessor;
import com.common.entity.SyslogNonNormalMessage;
import java.util.*;
import java.util.stream.Collectors;
import com.common.service.SyslogNonNormalMessageService;
import java.time.LocalDateTime;

@Slf4j
@Validated
@RestController
@RequestMapping("/api/syslog")
public class SyslogController {

    @Autowired
    private InfluxSyslogService syslogService;
    @Autowired
    private SyslogNonNormalMessageService messageService;
    @Autowired
    private LogNormalProcessor logNormalProcessor;
    /**
     * 接口1：按时间范围查询
     * GET /api/syslog/time-range?startTime=2023-11-20T00:00:00Z&endTime=2023-11-20T23:59:59Z
     */
    @GetMapping("/time-range")
    public ApiResponse<List<Map<String, Object>>> queryByTimeRange(
            @RequestParam @NotBlank(message = "开始时间不能为空") String startTime,
            @RequestParam @NotBlank(message = "结束时间不能为空") String endTime) {

        log.info("收到时间范围查询请求: startTime={}, endTime={}", startTime, endTime);
        List<Map<String, Object>> results = syslogService.queryByTimeRange(startTime, endTime);
        return ApiResponse.success(results);
    }

    /**
     * 接口2：按UUID查询详细日志
     * GET /api/syslog/uuid/{uuid}
     */
    @GetMapping("/uuid/{uuid}")
    public ApiResponse<List<Map<String, Object>>> queryByUuid(
            @PathVariable @NotBlank(message = "UUID不能为空") String uuid) {

        log.info("收到UUID查询请求: uuid={}", uuid);
        List<Map<String, Object>> results = syslogService.queryByUuid(uuid);
        return ApiResponse.success(results);
    }

    /**
     * 接口3：按设备ID和时间范围查询
     * GET /api/syslog/device?deviceId=device123&startTime=2023-11-20T00:00:00Z&endTime=2023-11-20T23:59:59Z
     */
    @GetMapping("/device")
    public ApiResponse<List<Map<String, Object>>> queryByDeviceId(
            @RequestParam @NotBlank(message = "设备ID不能为空") String deviceId,
            @RequestParam @NotBlank(message = "开始时间不能为空") String startTime,
            @RequestParam @NotBlank(message = "结束时间不能为空") String endTime) {

        log.info("收到设备ID查询请求: deviceId={}, startTime={}, endTime={}", deviceId, startTime, endTime);
        List<Map<String, Object>> results = syslogService.queryByDeviceIdAndTime(deviceId, startTime, endTime);
        return ApiResponse.success(results);
    }

    /**
     * 接口4：模糊查询message内容
     * GET /api/syslog/search?startTime=2023-11-20T00:00:00Z&endTime=2023-11-20T23:59:59Z&keyword=error
     */
    @GetMapping("/search")
    public ApiResponse<List<Map<String, Object>>> searchByMessage(
            @RequestParam @NotBlank(message = "开始时间不能为空") String startTime,
            @RequestParam @NotBlank(message = "结束时间不能为空") String endTime,
            @RequestParam @NotBlank(message = "搜索关键字不能为空") String keyword) {

        log.info("收到模糊查询请求: startTime={}, endTime={}, keyword={}", startTime, endTime, keyword);
        List<Map<String, Object>> results = syslogService.queryByMessageContent(startTime, endTime, keyword);
        return ApiResponse.success(results);
    }
    /**
     * 接口：按多个UUID批量查询详细日志
     * POST /api/syslog/uuids
     * 请求体：{"uuids": ["uuid1", "uuid2", "uuid3"]}
     */
    @PostMapping("/uuids")
    public ApiResponse<Map<String, List<Map<String, Object>>>> queryByUuids(
            @RequestBody @Valid UuidBatchRequest request) {

        log.info("收到批量UUID查询请求，数量: {}", request.getUuids().size());
        Map<String, List<Map<String, Object>>> results = syslogService.queryByUuids(request.getUuids());
        return ApiResponse.success(results);
    }


    /**
     * 非标日志再次泛化处理
     * 入参：List<Map<String, Object>> 多个map方式 两个参数: id, created_at
     * 返回：ApiResponse<List<Map<String, Object>>>
     */
    @PostMapping("/re-generalize")
    public ApiResponse<List<Map<String, Object>>> reGeneralizeNonNormalMessages(
            @RequestBody List<Map<String, String>> paramList) {

        List<Map<String, Object>> results = new ArrayList<>();

        try {
            log.info("开始非标日志再次泛化处理，处理记录数: {}", paramList.size());

            // 1. 参数校验
            if (paramList == null || paramList.isEmpty()) {
                return ApiResponse.error("参数不能为空");
            }
            if (paramList.size()>100) {
                return ApiResponse.error("再次泛化处理一次不能超过100条记录");
            }
            // 2. 提取参数并查询非标日志记录
            List<String> ids = new ArrayList<>();
            //List<LocalDateTime> createdAts = new ArrayList<>();
            List<String> createdAts = new ArrayList<>();
            for (Map<String, String> param : paramList) {
                String id = (String) param.get("id");
                String createdAtObj = param.get("created_at");

                if (id != null) {
                    ids.add(id);
                    createdAts.add(  createdAtObj);
                }
            }

            if (ids.isEmpty()) {
                return ApiResponse.error("有效的ID列表为空");
            }

            // 3. 批量查询非标日志记录
            List<SyslogNonNormalMessage> messages = messageService.getMessagesByIdsAndCreatedAts(ids, createdAts);

            if (messages.isEmpty()) {
                return ApiResponse.error("未找到对应的非标日志记录");
            }

            log.info("查询到非标日志记录数: {}", messages.size());

            // 4. 按照syslog_uuid分组，确保相同uuid只处理一次
            Map<String, List<SyslogNonNormalMessage>> uuidGroups = messages.stream()
                    .filter(msg -> msg.getSyslogUuid() != null && !msg.getSyslogUuid().trim().isEmpty())
                    .collect(Collectors.groupingBy(SyslogNonNormalMessage::getSyslogUuid));

            // 处理没有syslog_uuid的记录
            List<SyslogNonNormalMessage> noUuidMessages = messages.stream()
                    .filter(msg -> msg.getSyslogUuid() == null || msg.getSyslogUuid().trim().isEmpty())
                    .collect(Collectors.toList());

            log.info("按syslog_uuid分组后组数: {}, 无UUID记录数: {}", uuidGroups.size(), noUuidMessages.size());

            // 5. 处理每个分组，相同uuid只泛化一次
            Map<String, Boolean> uuidProcessResult = new HashMap<>();
            Map<String, String> uuidProcessMessage = new HashMap<>();

            for (Map.Entry<String, List<SyslogNonNormalMessage>> entry : uuidGroups.entrySet()) {
                String syslogUuid = entry.getKey();
                List<SyslogNonNormalMessage> groupMessages = entry.getValue();

                if (groupMessages.isEmpty()) {
                    continue;
                }

                // 取第一条记录进行泛化处理（相同uuid的日志内容应该相同）
                SyslogNonNormalMessage firstMessage = groupMessages.get(0);
                boolean processSuccess = false;
                String processMessage = "";

                try {
                    // 构建泛化处理器需要的参数
                    String headerMessage = firstMessage.getHeaderMessage() != null ? firstMessage.getHeaderMessage() : "";
                    String syslogMessage = firstMessage.getSyslogMessage() != null ? firstMessage.getSyslogMessage() : "";
                    String combinedMessage = headerMessage + syslogMessage;
                    String syslogTopic = firstMessage.getSyslogTopic();

                    log.debug("开始泛化处理，syslog_uuid: {}, topic: {}", syslogUuid, syslogTopic);

                    // 调用泛化处理类（Spring管理的Bean）
                    logNormalProcessor.process(combinedMessage, syslogUuid, syslogTopic);

                    processSuccess = true;
                    processMessage = "泛化处理成功";
                    log.debug("泛化处理成功，syslog_uuid: {}", syslogUuid);

                } catch (Exception e) {
                    processSuccess = false;
                    processMessage = "泛化处理失败: " + e.getMessage();
                    log.error("泛化处理失败，syslog_uuid: {}, 错误: {}", syslogUuid, e.getMessage(), e);
                }

                uuidProcessResult.put(syslogUuid, processSuccess);
                uuidProcessMessage.put(syslogUuid, processMessage);
            }

            // 6. 批量更新处理结果和del_flag
            List<SyslogNonNormalMessage> messagesToUpdate = new ArrayList<>();

            // 处理有UUID的记录
            for (SyslogNonNormalMessage message : messages) {
                Map<String, Object> resultItem = new HashMap<>();
                resultItem.put("id", message.getId());
                resultItem.put("created_at", message.getCreatedAt());
                resultItem.put("syslog_uuid", message.getSyslogUuid());

                String syslogUuid = message.getSyslogUuid();
                if (syslogUuid != null && !syslogUuid.trim().isEmpty() && uuidProcessResult.containsKey(syslogUuid)) {
                    boolean success = uuidProcessResult.get(syslogUuid);
                    String msg = uuidProcessMessage.get(syslogUuid);

                    resultItem.put("success", success);
                    resultItem.put("message", msg);

                    // 更新记录状态，无论成功失败都标记del_flag为1（表示已处理）
                    message.setDelFlag("1");
                    messagesToUpdate.add(message);
                } else if (syslogUuid == null || syslogUuid.trim().isEmpty()) {
                    // 没有syslog_uuid的记录
                    resultItem.put("success", false);
                    resultItem.put("message", "syslog_uuid为空，无法进行泛化处理");
                    message.setDelFlag("1"); // 仍然标记为已处理
                    messagesToUpdate.add(message);
                }

                results.add(resultItem);
            }

            // 7. 批量更新数据库
            if (!messagesToUpdate.isEmpty()) {
                int updateCount = messageService.updateBatchDelFlag(messagesToUpdate);
                log.info("批量更新del_flag完成，更新记录数: {}", updateCount);
            }

            // 8. 统计处理结果
            long successCount = results.stream()
                    .filter(result -> Boolean.TRUE.equals(result.get("success")))
                    .count();

            String finalMessage = String.format("处理完成，成功: %d, 失败: %d",
                    successCount, results.size() - successCount);

            log.info("非标日志再次泛化处理完成，{}", finalMessage);

            return ApiResponse.success(finalMessage, results);

        } catch (Exception e) {
            log.error("非标日志再次泛化处理异常: {}", e.getMessage(), e);
            //return ApiResponse.error("处理异常: " + e.getMessage(), results);
            return ApiResponse.error("处理异常: " + e.getMessage());
        }
    }

    /**
     * 非标日志再次泛化处理 - 简化版本（仅通过ID批量处理）
     */
    //@PostMapping("/regeneralize-by-ids")
    public ApiResponse<List<Map<String, Object>>> reGeneralizeByIds(
            @RequestBody List<String> ids) {

        List<Map<String, Object>> results = new ArrayList<>();

        try {
            if (ids == null || ids.isEmpty()) {
                return ApiResponse.error("ID列表不能为空");
            }

            log.info("开始通过ID批量泛化处理，ID数量: {}", ids.size());

            // 查询记录
            List<SyslogNonNormalMessage> messages = messageService.getMessagesByIds(ids);

            if (messages.isEmpty()) {
                return ApiResponse.error("未找到对应的非标日志记录");
            }

            // 按syslog_uuid分组
            Map<String, List<SyslogNonNormalMessage>> uuidGroups = messages.stream()
                    .filter(msg -> msg.getSyslogUuid() != null && !msg.getSyslogUuid().trim().isEmpty())
                    .collect(Collectors.groupingBy(SyslogNonNormalMessage::getSyslogUuid));

            List<SyslogNonNormalMessage> noUuidMessages = messages.stream()
                    .filter(msg -> msg.getSyslogUuid() == null || msg.getSyslogUuid().trim().isEmpty())
                    .collect(Collectors.toList());

            // 处理每个uuid组
            for (String syslogUuid : uuidGroups.keySet()) {
                List<SyslogNonNormalMessage> groupMessages = uuidGroups.get(syslogUuid);
                SyslogNonNormalMessage firstMessage = groupMessages.get(0);

                boolean processSuccess = false;
                String processMessage = "";

                try {
                    String headerMessage = firstMessage.getHeaderMessage() != null ?
                            firstMessage.getHeaderMessage() : "";
                    String syslogMessage = firstMessage.getSyslogMessage() != null ?
                            firstMessage.getSyslogMessage() : "";
                    String combinedMessage = headerMessage + syslogMessage;

                    logNormalProcessor.process(combinedMessage, syslogUuid,
                            firstMessage.getSyslogTopic());

                    processSuccess = true;
                    processMessage = "处理成功";
                } catch (Exception e) {
                    processSuccess = false;
                    processMessage = "处理失败: " + e.getMessage();
                }

                // 更新该组所有记录
                for (SyslogNonNormalMessage msg : groupMessages) {
                    Map<String, Object> resultItem = new HashMap<>();
                    resultItem.put("id", msg.getId());
                    resultItem.put("syslog_uuid", msg.getSyslogUuid());
                    resultItem.put("success", processSuccess);
                    resultItem.put("message", processMessage);
                    results.add(resultItem);

                    msg.setDelFlag("1");
                }
            }

            // 处理没有UUID的记录
            for (SyslogNonNormalMessage msg : noUuidMessages) {
                Map<String, Object> resultItem = new HashMap<>();
                resultItem.put("id", msg.getId());
                resultItem.put("syslog_uuid", msg.getSyslogUuid());
                resultItem.put("success", false);
                resultItem.put("message", "syslog_uuid为空，无法进行泛化处理");
                results.add(resultItem);

                msg.setDelFlag("1");
            }

            // 批量更新
            if (!messages.isEmpty()) {
                messageService.updateBatch(messages);
            }

            long successCount = results.stream()
                    .filter(result -> Boolean.TRUE.equals(result.get("success")))
                    .count();

            String finalMessage = String.format("处理完成，成功: %d, 失败: %d",
                    successCount, results.size() - successCount);

            return ApiResponse.success(finalMessage, results);

        } catch (Exception e) {
            log.error("通过ID批量泛化处理异常: {}", e.getMessage(), e);
            //return ApiResponse.error("处理异常: " + e.getMessage(), results);
            return ApiResponse.error("处理异常: " + e.getMessage());
        }
    }


    // 请求体DTO
    @Data
    public class UuidBatchRequest {
        @NotEmpty(message = "UUID列表不能为空")
        @Size(max = 100, message = "一次最多查询100个UUID")
        private List<@NotBlank(message = "UUID不能为空") String> uuids;
    }
    /**
         * 统一异常处理
         */
        @ExceptionHandler(Exception.class)
        public ApiResponse<Object> handleException(Exception e) {
            log.error("API处理异常: {}", e.getMessage(), e);
            return ApiResponse.error(e.getMessage());
    }
}