// cli/src/index-loader.ts
// 岗位数据按年份分片(data/positions/<year>.json.gz + meta.json)。全量约82万岗,
// 单一JSON超过node字符串上限无法解析,故分片懒加载——查询只载入所需年份。
import { readFileSync, existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { gunzipSync } from "node:zlib";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const CANDIDATE_DIRS = [
    join(__dirname, "..", "data", "positions"),
    join(__dirname, "..", "..", "data", "positions"),
    join(__dirname, "..", "..", "cli", "data", "positions"),
];
function positionsDir() {
    for (const d of CANDIDATE_DIRS)
        if (existsSync(join(d, "meta.json")))
            return d;
    throw new Error("data/positions/meta.json not found (run: npx tsx src/ingest-sharded.ts)");
}
let metaCache = null;
export function loadMeta() {
    if (metaCache)
        return metaCache;
    return (metaCache = JSON.parse(readFileSync(join(positionsDir(), "meta.json"), "utf-8")));
}
export function latestYear() {
    return Math.max(...loadMeta().years);
}
const yearCache = new Map();
/** 载入某年份分片的全部岗位(懒加载+缓存)。年份不存在返回空数组。 */
export function loadYear(year) {
    if (yearCache.has(year))
        return yearCache.get(year);
    const p = join(positionsDir(), `${year}.json.gz`);
    if (!existsSync(p)) {
        yearCache.set(year, []);
        return [];
    }
    const parsed = JSON.parse(gunzipSync(readFileSync(p)).toString("utf-8"));
    yearCache.set(year, parsed.positions);
    return parsed.positions;
}
/** 解析查询年份：显式 --year 或默认最新年份。 */
export function resolveYear(flagYear) {
    if (flagYear !== undefined && flagYear !== "") {
        const y = Number(flagYear);
        if (Number.isFinite(y))
            return y;
    }
    return latestYear();
}
export function availableYears() { return loadMeta().years; }
export function filterPositions(positions, f) {
    return positions.filter((p) => {
        if (f.year && p.year !== f.year)
            return false;
        if (f.exam && p.exam !== f.exam)
            return false;
        if (f.education && !p.education.includes(f.education))
            return false;
        if (f.major && !matchMajor(p.major, f.major))
            return false;
        if (f.political && f.political !== "不限" && p.political !== "不限" && !p.political.includes(f.political))
            return false;
        // 省考/事业单位有结构化 province 字段→精确匹配(避免"观山东路"等路名子串误匹配)；
        // 国考/北京无 province→按 work_location 含省名(其工作地点为省市级，无街路名，低风险)。
        if (f.province) {
            if (p.province) {
                if (p.province !== f.province)
                    return false;
            }
            else if (!p.work_location.includes(f.province))
                return false;
        }
        if (f.dept && !p.dept_name.includes(f.dept))
            return false;
        if (f.inst_type && p.inst_type !== f.inst_type)
            return false;
        if (f.grassroots && p.grassroots_years !== "无限制" && p.grassroots_years !== f.grassroots)
            return false;
        if (f.exam_category && p.exam_category !== f.exam_category)
            return false;
        if (f.program && !(p.programs ?? []).includes(f.program))
            return false;
        // 补充退役记录仅在按专项检索时可见，避免在全量检索中与全量职位表里同一岗位重复计数
        if (p.supplementary && !f.program)
            return false;
        return true;
    });
}
function matchMajor(positionMajor, userMajor) {
    if (positionMajor.includes("不限"))
        return true;
    const normalized = positionMajor.replace(/[;；,，、]/g, "|");
    return normalized.split("|").some((m) => m.trim().includes(userMajor) || userMajor.includes(m.trim()));
}
