/**
 * SF-02 Requirement Engineering Factory — Domain Model
 *
 * Part A：统一需求领域模型。
 *
 * 定义需求工程所需的全部类型：
 *   RequirementPackage / Epic / Feature / UserStory
 *   AcceptanceCriteria / BusinessRule / Constraint
 *   NonFunctionalRequirement / PermissionRequirement
 *   IntegrationRequirement / DataRequirement / RiskRequirement
 *   TraceabilityLink / Priority / Dependency / RequirementVersion
 *
 * 设计原则：
 *   - 纯类型定义 + 工厂函数，无副作用
 *   - 不可变创建模式
 *   - 所有类型通过 metadata 支持扩展
 *   - 与 PR-35/PR-36/SF-01 类型系统兼容
 *   - 零外部依赖
 *   - 禁止：代码生成、数据库设计、架构设计、UI 设计
 *   - 只负责：产品战略 → 完整需求体系
 *
 * @module sf-02-requirement-engineering/domain-model
 * @since SF-02
 */

// ═══════════════════════════════════════════════════════
// 1. RequirementPackage — 需求包
// ═══════════════════════════════════════════════════════

let _rpSeq = 0;

/**
 * 需求包 — SF-02 产出的顶层容器。
 *
 * 包含从产品战略转换而来的完整需求体系。
 * 这是 SF-03 Product Design Factory 的唯一需求输入源。
 *
 * @param {object} p
 * @param {string} p.productName        — 产品名称
 * @param {object} p.strategyPackage    — 上游 SF-01 Strategy Package
 * @param {object} p.executiveSummary   — 执行摘要
 * @param {object[]} p.epics            — Epic 列表
 * @param {object[]} p.features         — Feature 列表
 * @param {object[]} p.userStories      — User Story 列表
 * @param {object[]} p.acceptanceCriteria — 验收标准列表
 * @param {object[]} p.businessRules    — 业务规则列表
 * @param {object[]} p.constraints      — 约束列表
 * @param {object[]} p.nonFunctionalReqs — 非功能需求列表
 * @param {object[]} p.permissionReqs   — 权限需求列表
 * @param {object[]} p.integrationReqs  — 集成需求列表
 * @param {object[]} p.dataReqs         — 数据需求列表
 * @param {object[]} p.riskReqs         — 风险需求列表
 * @param {object[]} p.traceabilityLinks — 追踪链接列表
 * @param {object[]} p.dependencies     — 依赖列表
 * @param {object[]} p.priorities       — 优先级列表
 * @param {object} p.mvpScope           — MVP 范围
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createRequirementPackage({
  productName, strategyPackage, executiveSummary,
  epics = [], features = [], userStories = [],
  acceptanceCriteria = [], businessRules = [], constraints = [],
  nonFunctionalReqs = [], permissionReqs = [], integrationReqs = [],
  dataReqs = [], riskReqs = [], traceabilityLinks = [],
  dependencies = [], priorities = [],
  mvpScope = null, metadata = {},
}) {
  if (!productName) throw new TypeError("RequirementPackage.productName is required");

  return {
    id: `rp-${++_rpSeq}`,
    productName,
    strategyPackage,
    executiveSummary,
    epics: [...epics],
    features: [...features],
    userStories: [...userStories],
    acceptanceCriteria: [...acceptanceCriteria],
    businessRules: [...businessRules],
    constraints: [...constraints],
    nonFunctionalReqs: [...nonFunctionalReqs],
    permissionReqs: [...permissionReqs],
    integrationReqs: [...integrationReqs],
    dataReqs: [...dataReqs],
    riskReqs: [...riskReqs],
    traceabilityLinks: [...traceabilityLinks],
    dependencies: [...dependencies],
    priorities: [...priorities],
    mvpScope,
    metadata: {
      factoryId: "SF-02",
      version: "1.0",
      generatedAt: new Date().toISOString(),
      ...metadata,
    },
  };
}

// ═══════════════════════════════════════════════════════
// 2. Epic — 史诗级需求
// ═══════════════════════════════════════════════════════

let _epSeq = 0;

export const EPIC_CATEGORY = Object.freeze({
  USER_MANAGEMENT:   "用户管理",
  CONTENT_MANAGEMENT: "内容管理",
  BUSINESS_PROCESS:  "业务流程",
  ANALYTICS:         "运营分析",
  SYSTEM:            "系统设置",
  INTEGRATION:       "集成对接",
  SECURITY:          "安全合规",
  PLATFORM:          "平台基础",
  EXPERIENCE:        "用户体验",
  AI_ML:             "智能/AI",
});

/**
 * 史诗需求 — 最高层级需求，可分解为多个 Feature。
 *
 * @param {object} p
 * @param {string} p.title            — Epic 标题
 * @param {string} p.description      — Epic 描述
 * @param {string} p.category         — 分类（EPIC_CATEGORY）
 * @param {string} [p.objective=""]   — 业务目标
 * @param {string[]} [p.stakeholders=[]] — 干系人
 * @param {string} [p.successMetric=""]  — 成功度量
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createEpic({
  title, description, category,
  objective = "", stakeholders = [], successMetric = "",
  metadata = {},
}) {
  if (!title) throw new TypeError("Epic.title is required");
  if (!description) throw new TypeError("Epic.description is required");
  if (!category) throw new TypeError("Epic.category is required");

  return {
    id: `ep-${++_epSeq}`,
    title,
    description,
    category,
    objective,
    stakeholders: [...stakeholders],
    successMetric,
    metadata: {
      featureCount: 0,
      storyCount: 0,
      ...metadata,
    },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 3. Feature — 功能需求
// ═══════════════════════════════════════════════════════

let _ftSeq = 0;

/**
 * 功能需求 — 属于某个 Epic，可分解为多个 User Story。
 *
 * @param {object} p
 * @param {string} p.title            — Feature 标题
 * @param {string} p.description      — Feature 描述
 * @param {string} p.epicId           — 所属 Epic ID
 * @param {"CRUD"|"workflow"|"analytics"|"integration"|"configuration"|"notification"|"search"} [p.featureType="CRUD"]
 * @param {string} [p.userValue=""]   — 用户价值描述
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createFeature({
  title, description, epicId,
  featureType = "CRUD", userValue = "",
  metadata = {},
}) {
  if (!title) throw new TypeError("Feature.title is required");
  if (!description) throw new TypeError("Feature.description is required");
  if (!epicId) throw new TypeError("Feature.epicId is required");

  return {
    id: `ft-${++_ftSeq}`,
    title,
    description,
    epicId,
    featureType,
    userValue,
    metadata: {
      storyCount: 0,
      ...metadata,
    },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 4. UserStory — 用户故事
// ═══════════════════════════════════════════════════════

let _usSeq = 0;

export const STORY_PRIORITY = Object.freeze({
  MUST_HAVE:   "Must Have",
  SHOULD_HAVE: "Should Have",
  COULD_HAVE:  "Could Have",
  WONT_HAVE:   "Won't Have",
});

/**
 * 用户故事 — 标准格式 As a / I want / So that。
 *
 * @param {object} p
 * @param {string} p.role              — 用户角色
 * @param {string} p.goal              — 用户目标
 * @param {string} p.value             — 业务价值
 * @param {string} p.featureId         — 所属 Feature ID
 * @param {string} p.epicId            — 所属 Epic ID
 * @param {"Must Have"|"Should Have"|"Could Have"|"Won't Have"} [p.priority="Must Have"]
 * @param {number} [p.storyPoints=1]   — 故事点数
 * @param {string[]} [p.dependencies=[]]  — 依赖的其他 Story ID
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createUserStory({
  role, goal, value,
  featureId, epicId,
  priority = "Must Have",
  storyPoints = 1,
  dependencies = [],
  metadata = {},
}) {
  if (!role) throw new TypeError("UserStory.role is required");
  if (!goal) throw new TypeError("UserStory.goal is required");
  if (!value) throw new TypeError("UserStory.value is required");
  if (!featureId) throw new TypeError("UserStory.featureId is required");
  if (!epicId) throw new TypeError("UserStory.epicId is required");

  return {
    id: `us-${++_usSeq}`,
    role,
    goal,
    value,
    statement: `As a ${role}, I want ${goal}, so that ${value}.`,
    featureId,
    epicId,
    priority,
    storyPoints,
    dependencies: [...dependencies],
    metadata: {
      acCount: 0,
      ...metadata,
    },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 5. AcceptanceCriteria — 验收标准
// ═══════════════════════════════════════════════════════

let _acSeq = 0;

/**
 * 验收标准 — Given/When/Then 格式。
 *
 * @param {object} p
 * @param {string} p.storyId           — 所属 User Story ID
 * @param {string} p.given             — 前置条件
 * @param {string} p.when              — 触发动作
 * @param {string} p.then              — 预期结果
 * @param {number} [p.order=1]         — 排序
 * @param {string} [p.scenario=""]     — 场景名称
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createAcceptanceCriteria({
  storyId, given, when, then,
  order = 1, scenario = "",
  metadata = {},
}) {
  if (!storyId) throw new TypeError("AcceptanceCriteria.storyId is required");
  if (!given) throw new TypeError("AcceptanceCriteria.given is required");
  if (!when) throw new TypeError("AcceptanceCriteria.when is required");
  if (!then) throw new TypeError("AcceptanceCriteria.then is required");

  return {
    id: `ac-${++_acSeq}`,
    storyId,
    scenario,
    given,
    when,
    then,
    order,
    statement: `Given ${given}, When ${when}, Then ${then}.`,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 6. BusinessRule — 业务规则
// ═══════════════════════════════════════════════════════

let _brSeq = 0;

export const RULE_TYPE = Object.freeze({
  CONSTRAINT:      "业务约束",
  PROCESS:         "流程规则",
  PERMISSION:      "权限规则",
  APPROVAL:        "审批规则",
  STATE_MACHINE:   "状态机规则",
  VALIDATION:      "验证规则",
  CALCULATION:     "计算规则",
  NOTIFICATION:    "通知规则",
});

/**
 * 业务规则 — 定义业务流程中的约束和规范。
 *
 * @param {object} p
 * @param {string} p.name             — 规则名称
 * @param {string} p.description      — 规则描述
 * @param {"业务约束"|"流程规则"|"权限规则"|"审批规则"|"状态机规则"|"验证规则"|"计算规则"|"通知规则"} p.ruleType
 * @param {string} [p.condition=""]   — 触发条件
 * @param {string} [p.action=""]      — 执行动作
 * @param {string} [p.exception=""]   — 异常处理
 * @param {string[]} [p.relatedEpics=[]] — 关联 Epic
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createBusinessRule({
  name, description, ruleType,
  condition = "", action = "", exception = "",
  relatedEpics = [], metadata = {},
}) {
  if (!name) throw new TypeError("BusinessRule.name is required");
  if (!description) throw new TypeError("BusinessRule.description is required");
  if (!ruleType) throw new TypeError("BusinessRule.ruleType is required");

  return {
    id: `br-${++_brSeq}`,
    name,
    description,
    ruleType,
    condition,
    action,
    exception,
    relatedEpics: [...relatedEpics],
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 7. Constraint — 约束
// ═══════════════════════════════════════════════════════

let _ctSeq = 0;

export const CONSTRAINT_TYPE = Object.freeze({
  TECHNICAL:     "技术约束",
  BUSINESS:      "业务约束",
  REGULATORY:    "合规约束",
  RESOURCE:      "资源约束",
  TIME:          "时间约束",
  BUDGET:        "预算约束",
  PLATFORM:      "平台约束",
  ORGANIZATIONAL: "组织约束",
});

/**
 * 约束 — 限制需求实现的外部或内部条件。
 *
 * @param {object} p
 * @param {string} p.name
 * @param {string} p.description
 * @param {"技术约束"|"业务约束"|"合规约束"|"资源约束"|"时间约束"|"预算约束"|"平台约束"|"组织约束"} p.constraintType
 * @param {string} [p.impact=""]      — 对需求的影响
 * @param {string} [p.mitigation=""]  — 缓解措施
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createConstraint({
  name, description, constraintType,
  impact = "", mitigation = "", metadata = {},
}) {
  if (!name) throw new TypeError("Constraint.name is required");
  if (!description) throw new TypeError("Constraint.description is required");
  if (!constraintType) throw new TypeError("Constraint.constraintType is required");

  return {
    id: `ct-${++_ctSeq}`,
    name,
    description,
    constraintType,
    impact,
    mitigation,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 8. NonFunctionalRequirement — 非功能需求
// ═══════════════════════════════════════════════════════

let _nfrSeq = 0;

export const NFR_CATEGORY = Object.freeze({
  PERFORMANCE:   "性能需求",
  SECURITY:      "安全需求",
  RELIABILITY:   "可靠性需求",
  MAINTAINABILITY: "可维护性需求",
  SCALABILITY:   "扩展性需求",
  OBSERVABILITY: "可观测性需求",
  I18N:          "国际化需求",
  COMPATIBILITY: "兼容性需求",
  USABILITY:     "可用性需求",
  ACCESSIBILITY: "可访问性需求",
});

/**
 * 非功能需求 — 定义系统质量属性。
 *
 * @param {object} p
 * @param {string} p.name
 * @param {string} p.description
 * @param {"性能需求"|"安全需求"|"可靠性需求"|"可维护性需求"|"扩展性需求"|"可观测性需求"|"国际化需求"|"兼容性需求"|"可用性需求"|"可访问性需求"} p.category
 * @param {string} [p.metric=""]      — 量化指标
 * @param {string} [p.target=""]      — 目标值
 * @param {string} [p.measurement=""] — 测量方法
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createNonFunctionalRequirement({
  name, description, category,
  metric = "", target = "", measurement = "",
  metadata = {},
}) {
  if (!name) throw new TypeError("NFR.name is required");
  if (!description) throw new TypeError("NFR.description is required");
  if (!category) throw new TypeError("NFR.category is required");

  return {
    id: `nfr-${++_nfrSeq}`,
    name,
    description,
    category,
    metric,
    target,
    measurement,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 9. PermissionRequirement — 权限需求
// ═══════════════════════════════════════════════════════

let _prSeq = 0;

export const ACCESS_MODEL = Object.freeze({
  RBAC:  "RBAC",
  ABAC:  "ABAC",
  HYBRID: "Hybrid",
});

export const ROLE_TYPE = Object.freeze({
  SUPER_ADMIN: "超级管理员",
  ADMIN:       "管理员",
  OPERATOR:    "运营人员",
  USER:        "普通用户",
  GUEST:       "访客",
  AUDITOR:     "审计员",
});

/**
 * 权限需求 — 定义访问控制需求。
 *
 * @param {object} p
 * @param {"RBAC"|"ABAC"|"Hybrid"} p.accessModel
 * @param {object[]} p.roles            — 角色列表
 * @param {object[]} p.permissions      — 权限列表
 * @param {object[]} [p.rolePermissions=[]] — 角色-权限映射
 * @param {object[]} [p.resourceTypes=[]]   — 资源类型列表
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createPermissionRequirement({
  accessModel, roles, permissions,
  rolePermissions = [], resourceTypes = [],
  metadata = {},
}) {
  if (!accessModel) throw new TypeError("PermissionRequirement.accessModel is required");
  if (!roles?.length) throw new TypeError("PermissionRequirement.roles is required");
  if (!permissions?.length) throw new TypeError("PermissionRequirement.permissions is required");

  return {
    id: `pr-${++_prSeq}`,
    accessModel,
    roles: roles.map(r => ({
      id: `role-${r.name || r}`,
      name: r.name || r,
      description: r.description || "",
      level: r.level || 0,
      ...r,
    })),
    permissions: permissions.map(p => ({
      id: `perm-${p.resource}-${p.action}`,
      resource: p.resource,
      action: p.action,
      description: p.description || "",
      ...p,
    })),
    rolePermissions: [...rolePermissions],
    resourceTypes: [...resourceTypes],
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 10. IntegrationRequirement — 集成需求
// ═══════════════════════════════════════════════════════

let _irSeq = 0;

export const INTEGRATION_CATEGORY = Object.freeze({
  PAYMENT:       "支付系统",
  SMS:           "短信服务",
  EMAIL:         "邮件服务",
  THIRD_PARTY_AUTH: "第三方登录",
  AI_MODEL:      "AI模型服务",
  MAPS:          "地图服务",
  OBJECT_STORAGE: "对象存储",
  SEARCH:        "搜索引擎",
  MESSAGE_QUEUE: "消息队列",
  PUSH:          "推送服务",
  CDN:           "CDN",
  MONITORING:    "监控服务",
});

/**
 * 集成需求 — 定义外部系统集成需求。
 *
 * @param {object} p
 * @param {string} p.name
 * @param {"支付系统"|"短信服务"|...} p.category
 * @param {string} p.description
 * @param {"required"|"optional"|"conditional"} [p.necessity="required"]
 * @param {string[]} [p.providers=[]]    — 候选供应商
 * @param {string[]} [p.dataFlow=[]]     — 数据流向
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createIntegrationRequirement({
  name, category, description,
  necessity = "required", providers = [], dataFlow = [],
  metadata = {},
}) {
  if (!name) throw new TypeError("IntegrationRequirement.name is required");
  if (!category) throw new TypeError("IntegrationRequirement.category is required");
  if (!description) throw new TypeError("IntegrationRequirement.description is required");

  return {
    id: `ir-${++_irSeq}`,
    name,
    category,
    description,
    necessity,
    providers: [...providers],
    dataFlow: [...dataFlow],
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 11. DataRequirement — 数据需求
// ═══════════════════════════════════════════════════════

let _drSeq = 0;

export const DATA_CLASSIFICATION = Object.freeze({
  PUBLIC:      "公开数据",
  INTERNAL:    "内部数据",
  CONFIDENTIAL: "机密数据",
  RESTRICTED:  "受限数据",
  PII:         "个人隐私数据",
});

export const DATA_LIFECYCLE = Object.freeze({
  CREATE:  "创建",
  READ:    "读取",
  UPDATE:  "更新",
  DELETE:  "删除",
  ARCHIVE: "归档",
  PURGE:   "清除",
});

/**
 * 数据需求 — 只定义数据需求，禁止设计数据库。
 *
 * @param {object} p
 * @param {string} p.entityName           — 实体名称
 * @param {string} p.description          — 业务含义
 * @param {string[]} p.requiredFields     — 必需字段（业务视角）
 * @param {string[]} p.relationships      — 与其他实体的关系
 * @param {string} p.dataClassification   — 数据分类
 * @param {string[]} p.lifecycle          — 数据生命周期
 * @param {string} p.owner                — 数据所有者
 * @param {string[]} [p.complianceReqs=[]] — 合规需求
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createDataRequirement({
  entityName, description, requiredFields,
  relationships, dataClassification, lifecycle,
  owner, complianceReqs = [], metadata = {},
}) {
  if (!entityName) throw new TypeError("DataRequirement.entityName is required");
  if (!description) throw new TypeError("DataRequirement.description is required");
  if (!dataClassification) throw new TypeError("DataRequirement.dataClassification is required");
  if (!owner) throw new TypeError("DataRequirement.owner is required");

  return {
    id: `dr-${++_drSeq}`,
    entityName,
    description,
    requiredFields: [...requiredFields],
    relationships: [...relationships],
    dataClassification,
    lifecycle: [...lifecycle],
    owner,
    complianceReqs: [...complianceReqs],
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 12. RiskRequirement — 风险需求
// ═══════════════════════════════════════════════════════

let _rrSeq = 0;

export const RISK_LEVEL = Object.freeze({
  CRITICAL: "critical",
  HIGH:     "high",
  MEDIUM:   "medium",
  LOW:      "low",
});

/**
 * 风险需求 — 识别和管理需求相关风险。
 *
 * @param {object} p
 * @param {string} p.name
 * @param {string} p.description
 * @param {"critical"|"high"|"medium"|"low"} p.level
 * @param {number} p.probability            — 发生概率 0-1
 * @param {number} p.impact                 — 影响程度 0-1
 * @param {string} [p.mitigation=""]
 * @param {string[]} [p.relatedReqs=[]]     — 关联需求 ID
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createRiskRequirement({
  name, description, level,
  probability, impact, mitigation = "",
  relatedReqs = [], metadata = {},
}) {
  if (!name) throw new TypeError("RiskRequirement.name is required");
  if (!level) throw new TypeError("RiskRequirement.level is required");

  return {
    id: `rr-${++_rrSeq}`,
    name,
    description,
    level,
    probability: probability ?? 0.5,
    impact: impact ?? 0.5,
    riskScore: (probability ?? 0.5) * (impact ?? 0.5),
    mitigation,
    relatedReqs: [...relatedReqs],
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 13. TraceabilityLink — 追踪链接
// ═══════════════════════════════════════════════════════

let _tlSeq = 0;

export const LINK_TYPE = Object.freeze({
  STRATEGY_TO_EPIC:    "strategy→epic",
  EPIC_TO_FEATURE:     "epic→feature",
  FEATURE_TO_STORY:    "feature→story",
  STORY_TO_AC:         "story→ac",
  STORY_TO_BUSINESS_RULE: "story→business-rule",
  STORY_TO_NFR:        "story→nfr",
  EPIC_TO_PERMISSION:  "epic→permission",
  EPIC_TO_INTEGRATION: "epic→integration",
  STORY_TO_DATA:       "story→data",
});

/**
 * 追踪链接 — 建立需求元素之间的可追溯关系。
 *
 * @param {object} p
 * @param {string} p.sourceId          — 源元素 ID
 * @param {string} p.sourceType        — 源元素类型 (epic/feature/story/ac 等)
 * @param {string} p.targetId          — 目标元素 ID
 * @param {string} p.targetType        — 目标元素类型
 * @param {string} p.linkType          — 链接类型
 * @param {string} [p.description=""]
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createTraceabilityLink({
  sourceId, sourceType, targetId, targetType, linkType,
  description = "", metadata = {},
}) {
  if (!sourceId) throw new TypeError("TraceabilityLink.sourceId is required");
  if (!targetId) throw new TypeError("TraceabilityLink.targetId is required");
  if (!linkType) throw new TypeError("TraceabilityLink.linkType is required");

  return {
    id: `tl-${++_tlSeq}`,
    sourceId,
    sourceType,
    targetId,
    targetType,
    linkType,
    description,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 14. Priority — 优先级
// ═══════════════════════════════════════════════════════

let _priSeq = 0;

export const PRIORITY_CATEGORY = Object.freeze({
  MUST_HAVE:   "Must Have",
  SHOULD_HAVE: "Should Have",
  COULD_HAVE:  "Could Have",
  WONT_HAVE:   "Won't Have",
});

export const PRIORITY_METHOD = Object.freeze({
  MOSCOW: "MoSCoW",
  RICE:   "RICE",
  WSJF:   "WSJF",
});

/**
 * 优先级 — 需求优先级评定。
 *
 * @param {object} p
 * @param {string} p.itemId             — 需求项 ID
 * @param {string} p.itemType           — 需求项类型 (epic/feature/story)
 * @param {"Must Have"|"Should Have"|"Could Have"|"Won't Have"} p.category
 * @param {"MoSCoW"|"RICE"|"WSJF"} p.method
 * @param {number} [p.score=0]          — 综合评分
 * @param {object} [p.scores={}]        — 分维度评分
 * @param {string} [p.rationale=""]
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createPriority({
  itemId, itemType, category, method,
  score = 0, scores = {}, rationale = "",
  metadata = {},
}) {
  if (!itemId) throw new TypeError("Priority.itemId is required");
  if (!itemType) throw new TypeError("Priority.itemType is required");
  if (!category) throw new TypeError("Priority.category is required");

  return {
    id: `pri-${++_priSeq}`,
    itemId,
    itemType,
    category,
    method,
    score,
    scores: { ...scores },
    rationale,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 15. Dependency — 依赖关系
// ═══════════════════════════════════════════════════════

let _depSeq = 0;

export const DEPENDENCY_TYPE = Object.freeze({
  BLOCKS:       "blocks",
  REQUIRED_BY:  "required_by",
  RELATED_TO:   "related_to",
  DUPLICATES:   "duplicates",
  SUPERSEDES:   "supersedes",
});

/**
 * 依赖 — 需求项之间的依赖关系。
 *
 * @param {object} p
 * @param {string} p.fromId            — 依赖源 ID
 * @param {string} p.fromType          — 依赖源类型
 * @param {string} p.toId              — 被依赖项 ID
 * @param {string} p.toType            — 被依赖项类型
 * @param {"blocks"|"required_by"|"related_to"|"duplicates"|"supersedes"} p.depType
 * @param {string} [p.description=""]
 * @param {boolean} [p.critical=true]  — 是否关键依赖
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createDependency({
  fromId, fromType, toId, toType, depType,
  description = "", critical = true, metadata = {},
}) {
  if (!fromId) throw new TypeError("Dependency.fromId is required");
  if (!toId) throw new TypeError("Dependency.toId is required");
  if (!depType) throw new TypeError("Dependency.depType is required");

  return {
    id: `dep-${++_depSeq}`,
    fromId,
    fromType,
    toId,
    toType,
    depType,
    description,
    critical,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// 16. RequirementVersion — 需求版本
// ═══════════════════════════════════════════════════════

let _rvSeq = 0;

/**
 * 需求版本 — 需求变更追踪。
 *
 * @param {object} p
 * @param {string} p.requirementId      — 需求 ID
 * @param {string} p.requirementType    — 需求类型
 * @param {number} p.versionNumber      — 版本号
 * @param {string} p.changeDescription  — 变更描述
 * @param {string} [p.author=""]
 * @param {string} [p.previousSnapshot=""] — 变更前快照
 * @param {object} [p.metadata={}]
 * @returns {object}
 */
export function createRequirementVersion({
  requirementId, requirementType, versionNumber,
  changeDescription, author = "", previousSnapshot = "",
  metadata = {},
}) {
  if (!requirementId) throw new TypeError("RequirementVersion.requirementId is required");
  if (!requirementType) throw new TypeError("RequirementVersion.requirementType is required");
  if (versionNumber == null) throw new TypeError("RequirementVersion.versionNumber is required");

  return {
    id: `rv-${++_rvSeq}`,
    requirementId,
    requirementType,
    versionNumber,
    changeDescription,
    author,
    previousSnapshot,
    metadata: { ...metadata },
    createdAt: new Date().toISOString(),
  };
}

// ═══════════════════════════════════════════════════════
// Prompt 列表（供 LLM 驱动的 Agent 版本使用）
// ═══════════════════════════════════════════════════════

export const SF02_PROMPTS = Object.freeze({
  EPIC_DECOMPOSITION: `
你是一个资深的 BA（业务分析师）。
给定一个产品战略包，请将产品拆解为 Epic（史诗级需求）。

输入包含：
- 产品名称和描述
- 问题陈述（Problem Statement）
- 目标客户（Target Customer）
- 价值主张（Value Proposition）
- 路线图（Roadmap）

要求：
1. 识别 5~12 个 Epic
2. 每个 Epic 覆盖一个核心业务领域
3. 从以下标准分类中选择：用户管理、内容管理、业务流程、运营分析、系统设置、集成对接、安全合规、平台基础、用户体验、智能/AI
4. 每个 Epic 包含：标题、描述、业务目标、成功度量

输出 JSON 数组。
`,

  FEATURE_DECOMPOSITION: `
你是一个资深的 BA。
给定一个 Epic，请将其拆解为 Feature（功能需求）。

要求：
1. 每个 Epic 拆解 3~10 个 Feature
2. Feature 类型：CRUD、workflow、analytics、integration、configuration、notification、search
3. 每个 Feature 包含：标题、描述、用户价值

输出 JSON 数组。
`,

  USER_STORY_GENERATION: `
你是一个资深的 BA。
给定一个 Feature，请生成 User Story。

格式：As a [角色], I want [目标], so that [价值].

要求：
1. 每个 Feature 生成 2~8 个 User Story
2. 角色来自实际业务场景
3. 价值明确可衡量
4. 标注优先级：Must Have / Should Have / Could Have

输出 JSON 数组。
`,

  ACCEPTANCE_CRITERIA_GENERATION: `
你是一个资深的 QA。
给定一个 User Story，请生成 Acceptance Criteria。

格式：Given [前置条件], When [触发动作], Then [预期结果].

要求：
1. 每个 Story 生成 3~10 条 AC
2. 覆盖正常流程、异常流程、边界条件
3. 场景命名清晰

输出 JSON 数组。
`,
});
