/**
 * @module        core/wiki/types
 * @description   Wiki page 数据模型 + zod schemas
 *
 * @layer         core
 *
 * doc-28 §6 Page Schema 的运行时表示。Frontmatter 用 zod 严格校验——
 * 因为 wiki page 来自 LLM 写入，松散 schema 会让格式漂移失控。
 *
 * 类型分流：5 类 page（module/concept/decision/lesson/source）共享 Base 字段，
 * 每类有 type-specific 加字段。Frontmatter 类型用 discriminated union。
 */
import { z } from 'zod';
// ─── Page type enum ───────────────────────────────────────────────
export const PageTypeSchema = z.enum(['module', 'concept', 'decision', 'lesson', 'source']);
// ─── Status enum ──────────────────────────────────────────────────
export const StatusSchema = z.enum(['seed', 'developing', 'mature', 'evergreen', 'stale']);
// ─── Generated marker ─────────────────────────────────────────────
export const GeneratedSchema = z.enum(['auto', 'manual', 'semi']);
// ─── ISO date helpers ─────────────────────────────────────────────
const IsoDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'expected YYYY-MM-DD');
// ─── Source reference (frontmatter sources 字段) ───────────────────
//
// 三种形态（discriminated by which field is present）：
//   { path: 'src/X.ts', hash: '...' }    项目原生文件
//   { card: '17' }                         SPS 卡片溯源
//   { commit: 'abcd123' }                  git commit 溯源
//
// 注意：YAML 输出可能是字符串（如 ".raw/x.md"）也可能是对象。解析时归一化。
export const SourceRefSchema = z.union([
    z.object({ path: z.string(), hash: z.string().optional() }),
    z.object({ card: z.string() }),
    z.object({ commit: z.string() }),
    // 简写：纯字符串路径
    z.string().transform((s) => ({ path: s })),
]);
// ─── Wikilink string format: "[[Page Name]]" or "[[type/Page Name]]" ───
export const WikilinkSchema = z
    .string()
    .regex(/^\[\[[^[\]]+\]\]$/, 'expected [[Page Name]] wikilink format');
// ─── Base frontmatter (all page types share) ─────────────────────
const BaseFrontmatterSchema = z.object({
    title: z.string().min(1),
    created: IsoDateSchema,
    updated: IsoDateSchema,
    tags: z.array(z.string()).default([]),
    status: StatusSchema.default('developing'),
    related: z.array(WikilinkSchema).default([]),
    sources: z.array(SourceRefSchema).default([]),
    generated: GeneratedSchema.default('manual'),
});
// ─── Type-specific frontmatter ────────────────────────────────────
export const ModuleFrontmatterSchema = BaseFrontmatterSchema.extend({
    type: z.literal('module'),
    module_path: z.string().min(1).describe('Source file path relative to repo root'),
});
export const ConceptFrontmatterSchema = BaseFrontmatterSchema.extend({
    type: z.literal('concept'),
    complexity: z.enum(['basic', 'intermediate', 'advanced']).optional(),
    domain: z.string().optional(),
    aliases: z.array(z.string()).default([]).optional(),
});
export const DecisionFrontmatterSchema = BaseFrontmatterSchema.extend({
    type: z.literal('decision'),
    version: z.string().optional().describe('e.g. v0.51.0'),
    superseded_by: WikilinkSchema.optional(),
});
export const LessonFrontmatterSchema = BaseFrontmatterSchema.extend({
    type: z.literal('lesson'),
    severity: z.enum(['critical', 'major', 'minor']).default('major'),
    seen_in_cards: z.array(z.string()).default([]).optional(),
});
export const SourceFrontmatterSchema = BaseFrontmatterSchema.extend({
    type: z.literal('source'),
    source_type: z
        .enum(['pdf', 'article', 'image', 'transcript', 'data', 'note', 'unknown'])
        .default('unknown'),
    original_path: z.string().min(1),
});
export const FrontmatterSchema = z.discriminatedUnion('type', [
    ModuleFrontmatterSchema,
    ConceptFrontmatterSchema,
    DecisionFrontmatterSchema,
    LessonFrontmatterSchema,
    SourceFrontmatterSchema,
]);
// ─── Manifest (.manifest.json) ────────────────────────────────────
export const ManifestEntrySchema = z.object({
    /** 'code' | 'doc' | 'pdf' | 'article' | 'image' | 'transcript' | 'readme' | 'changelog' | ... */
    type: z.string().min(1),
    /** sha256 hex (64 chars) */
    sha256: z.string().regex(/^[0-9a-f]{64}$/, 'expected sha256 hex'),
    /** ISO 8601 timestamp */
    ingested_at: z.string(),
    /** Page ids this source contributed to */
    pages: z.array(z.string()).default([]),
});
export const ManifestSchema = z.object({
    version: z.literal(1),
    updated_at: z.string(),
    /** Key = source path relative to repo root (e.g. "src/X.ts" or ".raw/pdfs/y.pdf") */
    sources: z.record(ManifestEntrySchema).default({}),
});
export const EMPTY_MANIFEST = {
    version: 1,
    updated_at: '1970-01-01T00:00:00Z',
    sources: {},
};
//# sourceMappingURL=types.js.map