package com.datamate.datamanagement.application;

import com.datamate.datamanagement.common.enums.KnowledgeItemPreviewStatus;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;

/**
 * 知识条目预览元数据解析与写入辅助类
 */
public final class KnowledgeItemPreviewMetadataHelper {
    public static final String PREVIEW_STATUS_KEY = "previewStatus";
    public static final String PREVIEW_PDF_PATH_KEY = "previewPdfPath";
    public static final String PREVIEW_ERROR_KEY = "previewError";
    public static final String PREVIEW_UPDATED_AT_KEY = "previewUpdatedAt";

    private KnowledgeItemPreviewMetadataHelper() {
    }

    public static PreviewInfo readPreviewInfo(String metadata, ObjectMapper objectMapper) {
        if (StringUtils.isBlank(metadata) || objectMapper == null) {
            return PreviewInfo.empty();
        }
        try {
            JsonNode node = objectMapper.readTree(metadata);
            if (node == null || !node.isObject()) {
                return PreviewInfo.empty();
            }
            String statusText = textValue(node, PREVIEW_STATUS_KEY);
            KnowledgeItemPreviewStatus status = parseStatus(statusText);
            return new PreviewInfo(
                status,
                textValue(node, PREVIEW_PDF_PATH_KEY),
                textValue(node, PREVIEW_ERROR_KEY),
                textValue(node, PREVIEW_UPDATED_AT_KEY)
            );
        } catch (Exception ignore) {
            return PreviewInfo.empty();
        }
    }

    public static String applyPreviewInfo(
        String metadata,
        ObjectMapper objectMapper,
        KnowledgeItemPreviewStatus status,
        String pdfPath,
        String error,
        String updatedAt
    ) {
        if (objectMapper == null) {
            return metadata;
        }
        ObjectNode root = parseRoot(metadata, objectMapper);
        if (status == null) {
            root.remove(PREVIEW_STATUS_KEY);
        } else {
            root.put(PREVIEW_STATUS_KEY, status.name());
        }
        if (StringUtils.isBlank(pdfPath)) {
            root.remove(PREVIEW_PDF_PATH_KEY);
        } else {
            root.put(PREVIEW_PDF_PATH_KEY, pdfPath);
        }
        if (StringUtils.isBlank(error)) {
            root.remove(PREVIEW_ERROR_KEY);
        } else {
            root.put(PREVIEW_ERROR_KEY, error);
        }
        if (StringUtils.isBlank(updatedAt)) {
            root.remove(PREVIEW_UPDATED_AT_KEY);
        } else {
            root.put(PREVIEW_UPDATED_AT_KEY, updatedAt);
        }
        return root.size() == 0 ? null : root.toString();
    }

    public static String clearPreviewInfo(String metadata, ObjectMapper objectMapper) {
        if (objectMapper == null) {
            return metadata;
        }
        ObjectNode root = parseRoot(metadata, objectMapper);
        root.remove(PREVIEW_STATUS_KEY);
        root.remove(PREVIEW_PDF_PATH_KEY);
        root.remove(PREVIEW_ERROR_KEY);
        root.remove(PREVIEW_UPDATED_AT_KEY);
        return root.size() == 0 ? null : root.toString();
    }

    private static ObjectNode parseRoot(String metadata, ObjectMapper objectMapper) {
        if (StringUtils.isBlank(metadata)) {
            return objectMapper.createObjectNode();
        }
        try {
            JsonNode node = objectMapper.readTree(metadata);
            if (node instanceof ObjectNode objectNode) {
                return objectNode;
            }
        } catch (Exception ignore) {
            return objectMapper.createObjectNode();
        }
        return objectMapper.createObjectNode();
    }

    private static String textValue(JsonNode node, String key) {
        if (node == null || StringUtils.isBlank(key)) {
            return null;
        }
        JsonNode value = node.get(key);
        return value == null || value.isNull() ? null : value.asText();
    }

    private static KnowledgeItemPreviewStatus parseStatus(String statusText) {
        if (StringUtils.isBlank(statusText)) {
            return null;
        }
        try {
            return KnowledgeItemPreviewStatus.valueOf(statusText);
        } catch (Exception ignore) {
            return null;
        }
    }

    public record PreviewInfo(
        KnowledgeItemPreviewStatus status,
        String pdfPath,
        String error,
        String updatedAt
    ) {
        public static PreviewInfo empty() {
            return new PreviewInfo(null, null, null, null);
        }
    }
}
