package com.gzzm.lobster.context;

import com.gzzm.lobster.workspace.ResourceMetadata;
import com.gzzm.lobster.workspace.WorkspaceResource;

import java.util.List;

/**
 * WorkspaceIndexPolicy —— 工作区薄索引策略 / Thin-index policy for workspace.
 *
 * <p>按资源数动态调节索引形态：
 * <ul>
 * <li>≤ 5：显示名 + summary 或 outline topSections（若有）</li>
 * <li>6–20：仅显示名 + summary（若有）</li>
 * <li>&gt; 20：最近 10 项 + "共 N 项"（只显示名）</li>
 * </ul>
 *
 * <p>summary 由 LLM 通过 {@code save_resource_summary} 工具回写到 metadataJson；
 * 新上传但尚未 summary 的 USER_UPLOAD 资源会退回用 outlineSummary.topSections 当提示.
 */
public final class WorkspaceIndexPolicy {

    /** 附加提示行的字符上限，避免单行把 context 撑爆. */
    private static final int HINT_MAX_CHARS = 120;

    public String build(long totalCount, List<WorkspaceResource> recent) {
        if (recent == null || recent.isEmpty()) {
            return "(工作区当前无资源)";
        }
        int size = recent.size();
        StringBuilder sb = new StringBuilder();
        if (size <= 5) {
            sb.append("## Workspace (").append(totalCount).append(" 项)\n");
            sb.append("资源区文件需要读取正文时，使用 read_file(resourceId)。\n");
            for (WorkspaceResource r : recent) {
                appendRow(sb, r, true);
            }
        } else if (size <= 20) {
            sb.append("## Workspace (").append(totalCount).append(" 项)\n");
            sb.append("资源区文件需要读取正文时，使用 read_file(resourceId)。\n");
            for (WorkspaceResource r : recent) {
                appendRow(sb, r, true);
            }
        } else {
            sb.append("## Workspace (").append(totalCount)
              .append(" 项，显示最近 10 项，可用 list_files 查看全部)\n");
            sb.append("资源区文件需要读取正文时，使用 read_file(resourceId)。\n");
            int shown = 0;
            for (WorkspaceResource r : recent) {
                if (shown++ >= 10) break;
                appendRow(sb, r, false);
            }
        }
        return sb.toString();
    }

    private void appendRow(StringBuilder sb, WorkspaceResource r, boolean withHint) {
        sb.append("- [").append(sourceLabel(r)).append("] ")
                .append(r.getDisplayName() == null ? r.getResourceId() : r.getDisplayName())
                .append(" (").append(r.getResourceId()).append(")");
        if (r.getArtifactType() != null) sb.append(" (").append(r.getArtifactType()).append(")");
        if (withHint) {
            String hint = buildHint(r);
            if (hint != null && !hint.isEmpty()) {
                sb.append(" — ").append(truncate(hint, HINT_MAX_CHARS));
            }
        }
        sb.append("\n");
    }

    private String sourceLabel(WorkspaceResource r) {
        if (r == null || r.getSourceType() == null) return "UNKNOWN";
        if ("OA_FILE".equals(r.getSourceType().name())) {
            String label = ResourceMetadata.getOaFileTypeLabel(r);
            if (label != null && !label.isEmpty()) return "OA_FILE/" + label;
            String type = ResourceMetadata.getOaFileType(r);
            if ("MAIL".equalsIgnoreCase(type)) return "OA_FILE/邮件";
            if ("DOCUMENT".equalsIgnoreCase(type)) return "OA_FILE/公文";
        }
        return r.getSourceType().name();
    }

    /** 优先返回 summary；没有 summary 就拿 outlineSummary.topSections 拼一个短串. */
    private String buildHint(WorkspaceResource r) {
        String summary = ResourceMetadata.getSummary(r);
        if (summary != null && !summary.isEmpty()) return summary;
        List<String> top = ResourceMetadata.getTopSections(r);
        if (top == null || top.isEmpty()) return null;
        StringBuilder s = new StringBuilder("目录：");
        int take = Math.min(3, top.size());
        for (int i = 0; i < take; i++) {
            if (i > 0) s.append(" / ");
            s.append(top.get(i));
        }
        if (top.size() > take) s.append(" …");
        return s.toString();
    }

    private static String truncate(String s, int max) {
        if (s == null || s.length() <= max) return s;
        return s.substring(0, max - 1) + "…";
    }
}
