package com.agent.management.parser;

import com.agent.management.model.dto.IOField;
import com.agent.management.model.dto.SkillDTO;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

/**
 * SKILL.md 文件解析器
 * 解析文件头部的 name、description、inputs、outputs 字段
 */
@Slf4j
@Component
public class SkillMarkdownParser {

    private static final String NAME_PREFIX = "name:";
    private static final String DISPLAY_NAME_PREFIX = "displayname:";
    private static final String DESC_PREFIX = "description:";
    private static final String INPUTS_PREFIX = "inputs:";
    private static final String OUTPUTS_PREFIX = "outputs:";
    private static final String CAN_GEN_PREFIX = "cangenerateskill:";

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 解析 SKILL.md 文件，提取 name、description、inputs、outputs
     *
     * @param skillMdPath SKILL.md 文件路径
     * @return 解析后的 SkillDTO，若解析失败返回 empty
     */
    public Optional<SkillDTO> parse(Path skillMdPath) {
        SkillDTO dto = new SkillDTO();
        dto.setPath(skillMdPath.getParent().toString());
        dto.setFolderName(skillMdPath.getParent().getFileName().toString());

        try (BufferedReader reader = Files.newBufferedReader(skillMdPath, StandardCharsets.UTF_8)) {
            String name = null;
            String displayName = null;
            String description = null;
            List<IOField> inputs = null;
            List<IOField> outputs = null;
            Boolean canGenerateSkill = null;
            String line;
            int lineCount = 0;
            int maxLinesToScan = 30;

            while ((line = reader.readLine()) != null && lineCount < maxLinesToScan) {
                lineCount++;
                String trimmed = line.trim();

                // 跳过空行、注释行、Markdown 标题行、frontmatter 分隔符
                if (trimmed.isEmpty() || trimmed.startsWith("<!--") || trimmed.startsWith("#") || trimmed.equals("---")) {
                    continue;
                }

                if (name == null && trimmed.toLowerCase().startsWith(NAME_PREFIX)) {
                    name = trimmed.substring(NAME_PREFIX.length()).trim();
                    continue;
                }

                if (displayName == null && trimmed.toLowerCase().startsWith(DISPLAY_NAME_PREFIX)) {
                    displayName = trimmed.substring(DISPLAY_NAME_PREFIX.length()).trim();
                    continue;
                }

                if (description == null && trimmed.toLowerCase().startsWith(DESC_PREFIX)) {
                    description = trimmed.substring(DESC_PREFIX.length()).trim();
                    continue;
                }

                if (inputs == null && trimmed.toLowerCase().startsWith(INPUTS_PREFIX)) {
                    inputs = parseJsonArray(trimmed.substring(INPUTS_PREFIX.length()).trim());
                    continue;
                }

                if (outputs == null && trimmed.toLowerCase().startsWith(OUTPUTS_PREFIX)) {
                    outputs = parseJsonArray(trimmed.substring(OUTPUTS_PREFIX.length()).trim());
                    continue;
                }

                if (canGenerateSkill == null && trimmed.toLowerCase().startsWith(CAN_GEN_PREFIX)) {
                    String val = trimmed.substring(CAN_GEN_PREFIX.length()).trim().toLowerCase();
                    canGenerateSkill = "true".equals(val);
                    continue;
                }

                // 所有字段都已解析完成，提前退出
                if (name != null && displayName != null && description != null && inputs != null && outputs != null && canGenerateSkill != null) {
                    break;
                }
            }

            if (name == null || name.isEmpty() || description == null || description.isEmpty()) {
                log.warn("SKILL.md 解析失败，缺少必要字段: name={}, description={}, path={}",
                        name, description, skillMdPath);
                return Optional.empty();
            }

            dto.setName(name);
            dto.setDisplayName(displayName);
            dto.setDescription(description);
            dto.setInputs(inputs);
            dto.setOutputs(outputs);
            dto.setCanGenerateSkill(Boolean.TRUE.equals(canGenerateSkill));
            return Optional.of(dto);

        } catch (IOException e) {
            log.error("读取 SKILL.md 文件失败: {}", skillMdPath, e);
            return Optional.empty();
        }
    }

    private List<IOField> parseJsonArray(String json) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(json, new TypeReference<List<IOField>>() {});
        } catch (IOException e) {
            log.warn("解析 JSON 数组失败: {}", e.getMessage());
            return null;
        }
    }
}
