#!/usr/bin/env node

/**
 * Project Intake & PRD Agent — SF-01
 *
 * 将用户的一句话需求自动转换为结构化 PRD。
 *
 * 核心功能：
 *   - 需求解析：从自然语言提取关键信息
 *   - 领域识别：自动匹配项目领域（宠物/电商/教育/健身/企业/笔记等）
 *   - PRD 生成：输出产品简介、用户画像、用户故事、功能清单、页面清单、API 需求
 *   - 任务拆解：自动拆分为可执行的开发任务列表
 *   - MVP 范围：自动确定最小可行产品范围
 *
 * Usage:
 *   node scripts/project-intake-agent.mjs --input <text> [options]
 *   node scripts/project-intake-agent.mjs --input-file <path> [options]
 *
 * Options:
 *   --input <text>        一句话需求（直接输入）
 *   --input-file <path>   从 JSON 文件读取需求
 *   --output <path>       输出 PRD JSON 文件路径
 *   --pretty              格式化 JSON 输出
 *   --verbose             详细输出
 *   --help                显示帮助
 *
 * @module project-intake-agent
 */

import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(resolve(fileURLToPath(import.meta.url)));
const WORKSPACE = resolve(__dirname, "..");

// ═══════════════════════════════════════════════════════
// 1. Domain Knowledge Base
// ═══════════════════════════════════════════════════════

/**
 * Domain definitions: keyword → domain metadata.
 * Each domain provides templates for PRD generation.
 */
const DOMAINS = {
  pet: {
    keywords: ["宠物", "猫", "狗", "动物", "领养", "遛狗", "萌宠"],
    projectName: "PetCare",
    chineseName: "宠物管理",
    summary: "一款帮助宠物主人管理宠物健康、日常活动和成长记录的移动应用。",
    personas: [
      { name: "宠物主人", description: "养有1-3只宠物的都市青年，希望科学管理宠物健康", painPoints: ["忘记打疫苗时间", "找不到附近靠谱宠物医院", "宠物异常行为无法判断"] },
      { name: "宠物医生", description: "社区宠物医院的执业兽医", painPoints: ["病历管理混乱", "与宠物主人沟通低效"] },
    ],
    features: [
      { name: "宠物档案", description: "记录宠物的基本信息、品种、年龄、体重", priority: "P0" },
      { name: "健康日程", description: "疫苗提醒、驱虫提醒、体检预约", priority: "P0" },
      { name: "日常记录", description: "饮食、运动、排泄、体重变化记录", priority: "P1" },
      { name: "成长相册", description: "按时间线记录宠物成长照片", priority: "P1" },
      { name: "附近医院", description: "地图显示附近宠物医院，支持预约挂号", priority: "P1" },
      { name: "健康百科", description: "常见宠物疾病、护理知识库", priority: "P2" },
      { name: "社区分享", description: "宠物主人社区，分享萌宠日常", priority: "P2" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "宠物卡片、今日提醒、快捷入口" },
      { name: "宠物档案", route: "/pet/:id", description: "宠物详细信息、健康记录" },
      { name: "健康日程", route: "/schedule", description: "疫苗、驱虫、体检日历" },
      { name: "日常记录", route: "/daily-log", description: "饮食/运动/排泄记录表单" },
      { name: "成长相册", route: "/album", description: "时间线照片浏览" },
      { name: "附近医院", route: "/hospitals", description: "地图+列表视图" },
      { name: "我的", route: "/profile", description: "个人中心、设置" },
    ],
    apiRequirements: [
      { method: "POST", path: "/api/pets", description: "添加宠物档案" },
      { method: "GET", path: "/api/pets/:id", description: "获取宠物详情" },
      { method: "PUT", path: "/api/pets/:id", description: "更新宠物信息" },
      { method: "GET", path: "/api/schedules", description: "获取健康日程列表" },
      { method: "POST", path: "/api/schedules", description: "创建健康日程" },
      { method: "POST", path: "/api/daily-logs", description: "记录日常活动" },
      { method: "GET", path: "/api/daily-logs", description: "查询日常记录" },
      { method: "GET", path: "/api/hospitals", description: "查询附近医院" },
      { method: "POST", path: "/api/albums", description: "上传宠物照片" },
    ],
  },

  ecommerce: {
    keywords: ["电商", "商城", "购物", "店铺", "商品", "订单", "支付", "微信支付", "物流", "快递", "小程序"],
    projectName: "ShopApp",
    chineseName: "电商平台",
    summary: "一款支持商品浏览、购物车、在线支付和物流追踪的电商应用。",
    personas: [
      { name: "消费者", description: "在线购物的普通用户", painPoints: ["商品选择困难", "物流进度不透明", "售后流程复杂"] },
      { name: "商家", description: "入驻平台的店铺经营者", painPoints: ["订单管理繁琐", "库存同步不及时"] },
    ],
    features: [
      { name: "商品浏览", description: "分类浏览、搜索、筛选、商品详情", priority: "P0" },
      { name: "购物车", description: "加入购物车、修改数量、批量结算", priority: "P0" },
      { name: "订单管理", description: "创建订单、支付、取消、退款", priority: "P0" },
      { name: "收货地址", description: "管理多个收货地址", priority: "P0" },
      { name: "商品评价", description: "评分、文字评价、晒图", priority: "P1" },
      { name: "优惠券", description: "领取、使用、过期提醒", priority: "P1" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "轮播图、分类导航、推荐商品" },
      { name: "商品详情", route: "/product/:id", description: "商品图片、价格、规格、评价" },
      { name: "购物车", route: "/cart", description: "商品列表、价格汇总、去结算" },
      { name: "订单列表", route: "/orders", description: "全部订单、状态筛选" },
      { name: "订单详情", route: "/order/:id", description: "订单信息、物流追踪" },
      { name: "我的", route: "/profile", description: "个人中心、地址管理、优惠券" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/products", description: "商品列表（分页、筛选）" },
      { method: "GET", path: "/api/products/:id", description: "商品详情" },
      { method: "POST", path: "/api/orders", description: "创建订单" },
      { method: "GET", path: "/api/orders/:id", description: "订单详情" },
      { method: "POST", path: "/api/payments", description: "发起支付" },
      { method: "GET", path: "/api/logistics/:orderId", description: "物流追踪" },
      { method: "GET", path: "/api/coupons", description: "优惠券列表" },
    ],
  },

  education: {
    keywords: ["教育", "学习", "课程", "在线", "培训", "考试", "题库", "教学", "直播课", "录播"],
    projectName: "EduPlatform",
    chineseName: "在线教育平台",
    summary: "一个支持在线课程学习、直播授课、题库练习和学情追踪的教育平台。",
    personas: [
      { name: "学生", description: "希望通过线上学习提升技能的在校生或职场人", painPoints: ["课程质量参差不齐", "缺乏学习动力", "疑惑无人解答"] },
      { name: "讲师", description: "发布课程内容的专业讲师", painPoints: ["课件管理不便", "学生互动效率低"] },
    ],
    features: [
      { name: "课程中心", description: "课程分类、搜索、推荐、试看", priority: "P0" },
      { name: "视频播放", description: "在线播放、倍速、清晰度切换、断点续播", priority: "P0" },
      { name: "题库练习", description: "章节练习、模拟考试、错题本", priority: "P0" },
      { name: "直播课堂", description: "实时直播、弹幕互动、回放", priority: "P1" },
      { name: "学习进度", description: "课程进度追踪、学习时长统计", priority: "P1" },
      { name: "问答社区", description: "课程问答、讲师答疑", priority: "P2" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "推荐课程、热门讲师、学习统计" },
      { name: "课程详情", route: "/course/:id", description: "课程介绍、目录、评价" },
      { name: "学习页", route: "/learn/:courseId/:lessonId", description: "视频播放器+笔记区" },
      { name: "题库", route: "/exercises", description: "章节练习、模拟考试" },
      { name: "直播", route: "/live", description: "直播列表、直播间" },
      { name: "我的", route: "/profile", description: "学习报告、已购课程、设置" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/courses", description: "课程列表（分页、分类）" },
      { method: "GET", path: "/api/courses/:id", description: "课程详情（含章节）" },
      { method: "GET", path: "/api/lessons/:id", description: "获取课时内容（视频URL）" },
      { method: "GET", path: "/api/exercises", description: "题库列表" },
      { method: "POST", path: "/api/exercises/submit", description: "提交练习答案" },
      { method: "GET", path: "/api/progress", description: "学习进度查询" },
    ],
  },

  fitness: {
    keywords: ["健身", "运动", "打卡", "跑步", "瑜伽", "训练", "减肥", "跳绳", "游泳"],
    projectName: "FitTracker",
    chineseName: "健身打卡",
    summary: "一款帮助用户记录运动数据、制定训练计划和坚持打卡的健身应用。",
    personas: [
      { name: "健身爱好者", description: "规律运动的都市白领，希望数据化追踪训练效果", painPoints: ["训练计划不科学", "缺少坚持的动力", "运动数据分散"] },
    ],
    features: [
      { name: "打卡记录", description: "每日运动打卡、连续天数统计", priority: "P0" },
      { name: "训练计划", description: "自定义训练日程、模板推荐", priority: "P0" },
      { name: "数据统计", description: "周/月运动时长、卡路里消耗趋势", priority: "P0" },
      { name: "运动教程", description: "视频教程、动作指导", priority: "P1" },
      { name: "社交分享", description: "分享打卡、好友PK", priority: "P2" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "今日打卡、本周统计、训练计划" },
      { name: "打卡", route: "/checkin", description: "选择运动类型、记录时长/数据" },
      { name: "统计", route: "/stats", description: "运动趋势图表、成就徽章" },
      { name: "教程", route: "/tutorials", description: "分类视频教程" },
      { name: "我的", route: "/profile", description: "个人资料、目标设置" },
    ],
    apiRequirements: [
      { method: "POST", path: "/api/checkins", description: "提交运动打卡" },
      { method: "GET", path: "/api/checkins", description: "打卡记录查询" },
      { method: "GET", path: "/api/stats", description: "运动统计" },
      { method: "GET", path: "/api/plans", description: "训练计划列表" },
    ],
  },

  enterprise: {
    keywords: ["企业", "办公", "OA", "审批", "考勤", "打卡", "部门", "请假", "报销", "人事", "行政", "自动化", "流程"],
    projectName: "OAFlow",
    chineseName: "企业办公自动化",
    summary: "一款支持审批流、考勤管理、部门协作的企业办公自动化系统。",
    personas: [
      { name: "普通员工", description: "需要日常考勤打卡、发起审批的企业员工", painPoints: ["审批流程繁琐", "考勤异常处理麻烦"] },
      { name: "部门主管", description: "负责审批、团队管理的管理者", painPoints: ["审批堆积", "团队出勤无法一目了然"] },
      { name: "HR/行政", description: "负责考勤统计、人事管理的HR", painPoints: ["考勤数据手工统计", "跨部门流程混乱"] },
    ],
    features: [
      { name: "考勤打卡", description: "GPS定位打卡、外勤打卡、补卡申请", priority: "P0" },
      { name: "审批流程", description: "自定义审批模板、多级审批、催办", priority: "P0" },
      { name: "部门管理", description: "组织架构、人员管理、角色权限", priority: "P0" },
      { name: "请假管理", description: "请假申请、余额查询、审批记录", priority: "P0" },
      { name: "考勤统计", description: "日报/月报、异常汇总、导出", priority: "P1" },
      { name: "公告通知", description: "公司公告、部门通知、已读确认", priority: "P1" },
      { name: "报销管理", description: "报销申请、发票上传、审批", priority: "P2" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "待办审批、考勤状态、公告" },
      { name: "考勤", route: "/attendance", description: "打卡、考勤记录、统计" },
      { name: "审批", route: "/approvals", description: "我发起的、待我审批、已处理" },
      { name: "通讯录", route: "/contacts", description: "组织架构、人员搜索" },
      { name: "公告", route: "/notices", description: "公告列表、详情" },
      { name: "我的", route: "/profile", description: "个人资料、请假余额、设置" },
    ],
    apiRequirements: [
      { method: "POST", path: "/api/attendance/checkin", description: "考勤打卡" },
      { method: "GET", path: "/api/attendance/records", description: "考勤记录查询" },
      { method: "POST", path: "/api/approvals", description: "发起审批" },
      { method: "GET", path: "/api/approvals", description: "审批列表" },
      { method: "PUT", path: "/api/approvals/:id", description: "审批处理（通过/驳回）" },
      { method: "GET", path: "/api/departments", description: "部门列表" },
      { method: "GET", path: "/api/users", description: "人员查询" },
      { method: "POST", path: "/api/notices", description: "发布公告" },
    ],
  },

  note: {
    keywords: ["笔记", "备忘录", "记事本", "便签", "日记", "记录", "写作", "文档", "Markdown", "todo"],
    projectName: "NoteApp",
    chineseName: "笔记应用",
    summary: "一款支持多端同步、Markdown 编辑和标签管理的笔记应用。",
    personas: [
      { name: "知识工作者", description: "需要记录灵感和整理知识的职场人", painPoints: ["笔记分散多处", "搜索困难", "格式化繁琐"] },
    ],
    features: [
      { name: "笔记编辑", description: "富文本/Markdown编辑器、实时保存", priority: "P0" },
      { name: "文件夹/标签", description: "分类管理、多级文件夹", priority: "P0" },
      { name: "全文搜索", description: "标题+内容全文检索", priority: "P0" },
      { name: "多端同步", description: "手机/PC/Web 实时同步", priority: "P1" },
      { name: "协作分享", description: "分享链接、协作编辑", priority: "P2" },
    ],
    pages: [
      { name: "笔记列表", route: "/notes", description: "文件夹导航、笔记列表、搜索" },
      { name: "笔记编辑", route: "/note/:id", description: "编辑器页面" },
      { name: "标签管理", route: "/tags", description: "标签列表、关联笔记" },
      { name: "设置", route: "/settings", description: "主题、同步、账户" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/notes", description: "笔记列表" },
      { method: "POST", path: "/api/notes", description: "创建笔记" },
      { method: "PUT", path: "/api/notes/:id", description: "更新笔记" },
      { method: "DELETE", path: "/api/notes/:id", description: "删除笔记" },
      { method: "GET", path: "/api/tags", description: "标签列表" },
    ],
  },

  social: {
    keywords: ["社交", "社区", "朋友圈", "动态", "关注", "粉丝", "私信", "评论", "点赞", "分享"],
    projectName: "SocialApp",
    chineseName: "社交平台",
    summary: "一款以内容分享和用户互动为核心的社交应用。",
    personas: [
      { name: "内容创作者", description: "发布图文/视频内容的活跃用户", painPoints: ["内容曝光不足", "互动管理复杂"] },
      { name: "普通用户", description: "浏览内容和互动的用户", painPoints: ["信息过载", "隐私顾虑"] },
    ],
    features: [
      { name: "动态发布", description: "图文/视频发布、滤镜编辑", priority: "P0" },
      { name: "信息流", description: "关注动态推荐、时间线", priority: "P0" },
      { name: "互动系统", description: "点赞、评论、转发、收藏", priority: "P0" },
      { name: "个人主页", description: "用户资料、动态列表", priority: "P0" },
      { name: "私信", description: "一对一聊天、群聊", priority: "P1" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "信息流" },
      { name: "发布", route: "/publish", description: "编辑器、相册选择" },
      { name: "消息", route: "/messages", description: "私信列表、聊天" },
      { name: "个人", route: "/profile/:userId", description: "个人主页" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/feed", description: "信息流" },
      { method: "POST", path: "/api/posts", description: "发布动态" },
      { method: "POST", path: "/api/posts/:id/like", description: "点赞" },
      { method: "POST", path: "/api/comments", description: "发表评论" },
      { method: "GET", path: "/api/users/:id", description: "用户信息" },
    ],
  },

  food: {
    keywords: ["外卖", "点餐", "美食", "餐厅", "食谱", "烹饪", "菜谱", "食材", "厨房"],
    projectName: "FoodApp",
    chineseName: "美食应用",
    summary: "一款支持餐厅浏览、在线点餐或食谱管理的餐饮应用。",
    personas: [
      { name: "食客", description: "喜欢尝试不同美食的用户", painPoints: ["不知道吃什么", "排队等待时间长"] },
    ],
    features: [
      { name: "餐厅浏览", description: "附近餐厅、评分、评价", priority: "P0" },
      { name: "在线点餐", description: "菜单浏览、下单、支付", priority: "P0" },
      { name: "订单追踪", description: "订单状态、配送进度", priority: "P0" },
      { name: "评价系统", description: "评分、评价、晒图", priority: "P1" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "附近推荐、搜索" },
      { name: "餐厅详情", route: "/restaurant/:id", description: "菜单、评价" },
      { name: "购物车", route: "/cart", description: "已选菜品、下单" },
      { name: "订单", route: "/orders", description: "订单列表、状态" },
      { name: "我的", route: "/profile", description: "个人中心" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/restaurants", description: "餐厅列表" },
      { method: "GET", path: "/api/menus/:restaurantId", description: "菜单" },
      { method: "POST", path: "/api/orders", description: "创建订单" },
      { method: "GET", path: "/api/orders/:id", description: "订单详情" },
    ],
  },

  travel: {
    keywords: ["旅游", "旅行", "酒店", "机票", "攻略", "行程", "景点", "民宿", "签证"],
    projectName: "TravelApp",
    chineseName: "旅游应用",
    summary: "一款支持行程规划、酒店预订和旅游攻略浏览的旅行应用。",
    personas: [
      { name: "旅行者", description: "喜欢自由行的年轻旅行者", painPoints: ["行程规划费时", "当地信息获取困难"] },
    ],
    features: [
      { name: "行程规划", description: "多日行程编排、景点添加", priority: "P0" },
      { name: "攻略浏览", description: "目的地攻略、游记分享", priority: "P0" },
      { name: "预订服务", description: "酒店/门票预订", priority: "P1" },
      { name: "地图导航", description: "景点地图、路线规划", priority: "P1" },
    ],
    pages: [
      { name: "首页", route: "/home", description: "热门目的地、推荐攻略" },
      { name: "攻略详情", route: "/guide/:id", description: "图文攻略" },
      { name: "行程", route: "/itinerary", description: "行程编辑器" },
      { name: "预订", route: "/booking", description: "酒店/门票搜索" },
      { name: "我的", route: "/profile", description: "我的行程、收藏" },
    ],
    apiRequirements: [
      { method: "GET", path: "/api/destinations", description: "目的地列表" },
      { method: "GET", path: "/api/guides", description: "攻略列表" },
      { method: "POST", path: "/api/itineraries", description: "创建行程" },
      { method: "GET", path: "/api/hotels", description: "酒店搜索" },
    ],
  },
};

/**
 * Default / generic domain for unrecognized inputs.
 * Only provides personas — features/pages/APIs must come from user input.
 */
const DEFAULT_DOMAIN = {
  keywords: [],
  projectName: "MyProject",
  chineseName: "通用应用",
  summary: "一款根据用户需求定制的应用。",
  personas: [
    { name: "用户", description: "目标用户群体", painPoints: ["待明确"] },
  ],
  features: [],
  pages: [],
  apiRequirements: [],
};

// ═══════════════════════════════════════════════════════
// 2. Input Parser
// ═══════════════════════════════════════════════════════

/**
 * Detect platform preference from input text.
 *
 * @param {string} input
 * @returns {string[]}
 */
export function detectPlatforms(input) {
  const platforms = [];
  const patterns = [
    { keyword: "小程序", platform: "miniapp" },
    { keyword: "微信小程序", platform: "wechat-miniapp" },
    { keyword: "iOS", platform: "ios" },
    { keyword: "Android", platform: "android" },
    { keyword: "安卓", platform: "android" },
    { keyword: "Web", platform: "web" },
    { keyword: "网页", platform: "web" },
    { keyword: "H5", platform: "h5" },
    { keyword: "桌面", platform: "desktop" },
    { keyword: "PC", platform: "desktop" },
    { keyword: "移动端", platform: "mobile" },
    { keyword: "手机", platform: "mobile" },
  ];
  for (const { keyword, platform } of patterns) {
    if (input.includes(keyword) && !platforms.includes(platform)) {
      platforms.push(platform);
    }
  }
  return platforms.length > 0 ? platforms : ["mobile", "web"];
}

/**
 * Detect special feature requirements from input text.
 *
 * @param {string} input
 * @returns {string[]}
 */
export function detectExtraFeatures(input) {
  const features = [];
  const patterns = [
    { keyword: "微信支付", feature: "wechat-pay" },
    { keyword: "支付宝", feature: "alipay" },
    { keyword: "支付", feature: "online-payment" },
    { keyword: "物流", feature: "logistics-tracking" },
    { keyword: "推送", feature: "push-notification" },
    { keyword: "通知", feature: "push-notification" },
    { keyword: "AI", feature: "ai-powered" },
    { keyword: "智能推荐", feature: "smart-recommendation" },
    { keyword: "离线", feature: "offline-mode" },
    { keyword: "多语言", feature: "i18n" },
    { keyword: "国际化", feature: "i18n" },
    { keyword: "暗黑模式", feature: "dark-mode" },
    { keyword: "深色模式", feature: "dark-mode" },
    { keyword: "实时", feature: "real-time" },
    { keyword: "语音", feature: "voice-input" },
  ];
  for (const { keyword, feature } of patterns) {
    if (input.includes(keyword) && !features.includes(feature)) {
      features.push(feature);
    }
  }
  return features;
}

// ═══════════════════════════════════════════════════════
// 3. Domain Matcher
// ═══════════════════════════════════════════════════════

/**
 * Match input to the best-fitting domain.
 * Returns matchCount so caller can decide confidence.
 *
 * @param {string} input — User input text
 * @returns {{ domain: object, domainKey: string, matchCount: number }}
 */
export function matchDomain(input) {
  let bestDomain = { domain: DEFAULT_DOMAIN, domainKey: "generic", matchCount: 0 };

  for (const [key, domain] of Object.entries(DOMAINS)) {
    let count = 0;
    for (const kw of domain.keywords) {
      if (input.includes(kw)) count++;
    }
    if (count > bestDomain.matchCount) {
      bestDomain = { domain, domainKey: key, matchCount: count };
    }
  }

  return bestDomain;
}

// ═══════════════════════════════════════════════════════
// 3b. User Input Extractor (P0 fix: user input > domain template)
// ═══════════════════════════════════════════════════════

/**
 * Extract project name from user input.
 * Patterns: "叫 XXX", "命名为 XXX", "名为 XXX", "叫做 XXX"
 */
function extractProjectName(input) {
  const patterns = [
    /叫[\s]*["「]?([A-Za-z\u4e00-\u9fff]{2,20})["」]?/,
    /命名[为]?[\s]*["「]?([A-Za-z\u4e00-\u9fff]{2,20})["」]?/,
    /名为[\s]*["「]?([A-Za-z\u4e00-\u9fff]{2,20})["」]?/,
    /叫做[\s]*["「]?([A-Za-z\u4e00-\u9fff]{2,20})["」]?/,
  ];
  for (const p of patterns) {
    const m = input.match(p);
    if (m && m[1]) return m[1];
  }
  return null;
}

/**
 * Extract features from user input.
 * Looks for numbered items (1. 2. 3.) and Chinese feature keywords.
 */
function extractFeaturesFromInput(input) {
  const features = [];

  // Pattern 1: numbered items "1. 功能名：描述" or "1、功能名"
  const numbered = input.matchAll(/\d+[.、)）][\s]*([^\d\.、)）\n]{2,60})/g);
  for (const m of numbered) {
    const text = m[1].trim();
    // Split on colon/description separator
    const parts = text.split(/[：:]/);
    const name = parts[0].trim().replace(/[。，、；：！？\.\,\;\!\?]+$/g, "").trim();
    const desc = parts[1]?.trim() || name;
    if (name.length >= 2 && name.length <= 30) {
      features.push({ name, description: desc, priority: "P0" });
    }
  }

  // Pattern 2: if no numbered items, try comma-separated features after "功能" or "支持"
  if (features.length === 0) {
    const funcMatch = input.match(/(?:功能|支持)[：:]*([^。]+)/);
    if (funcMatch) {
      const items = funcMatch[1].split(/[,，、和]/);
      for (const item of items) {
        const name = item.trim().replace(/^[\s]+/, "");
        if (name.length >= 2 && name.length <= 20) {
          features.push({ name, description: name, priority: "P0" });
        }
      }
    }
  }

  return features;
}

/**
 * Extract pages/screens from user input.
 * Looks for page-related keywords.
 */
function extractPagesFromInput(input, features) {
  const pages = [];
  const pageKeywords = ["首页", "列表", "详情", "编辑", "设置", "管理", "统计", "仪表盘", "搜索", "个人", "我的", "登录", "注册"];

  // Extract from numbered items that contain page-like words
  const numbered = input.matchAll(/\d+[.、)）][\s]*([^\d\.、)）\n]{2,60})/g);
  for (const m of numbered) {
    const text = m[1].trim();
    const parts = text.split(/[：:]/);
    const name = parts[0].trim();
    const desc = parts[1]?.trim() || "";
    if (pageKeywords.some(kw => name.includes(kw) || desc.includes(kw))) {
      const route = "/" + _toSlug(name);
      pages.push({ name, route, description: desc || name });
    }
  }

  // Derive pages from features — each feature becomes a page
  if (features.length > 0) {
    const existingNames = new Set(pages.map(p => p.name));
    for (const f of features) {
      if (!existingNames.has(f.name)) {
        const route = "/" + _toSlug(f.name);
        pages.push({ name: f.name, route, description: f.description || f.name });
      }
    }
  }

  // Always add home page if not present
  if (!pages.some(p => p.name === "首页")) {
    pages.unshift({ name: "首页", route: "/home", description: "应用首页" });
  }

  return pages;
}

/**
 * Extract API requirements from user input.
 * Derives CRUD APIs from features.
 */

/**
 * Chinese-to-English slug for API paths and page routes.
 */
const _ZH_SLUG = {
  "书籍库": "books", "书籍": "books", "书评": "reviews", "阅读状态": "reading_status", "阅读进度": "reading_progress",
  "笔记": "notes", "标注": "annotations", "标签": "tags", "统计": "stats", "仪表盘": "dashboard",
  "看板": "boards", "任务": "tasks", "成员": "members", "活动日志": "activity_logs", "日志": "logs",
  "食物库": "foods", "食物": "foods", "客户": "clients", "餐计划": "meal_plans", "营养": "nutrition",
  "购物清单": "shopping_lists", "模板": "templates", "商品": "products", "订单": "orders",
  "库存": "inventory", "供应商": "suppliers", "预警": "alerts", "操作日志": "operation_logs",
  "工单": "tickets", "审批": "approvals", "考勤": "attendance", "员工": "employees",
  "课程": "courses", "章节": "chapters", "学员": "students", "作业": "assignments",
  "预约": "appointments", "服务": "services", "宠物": "pets", "日程": "schedules",
  "记录": "records", "相册": "albums", "医院": "hospitals", "文章": "articles",
  "评论": "comments", "媒体": "media", "项目": "projects", "资产": "assets",
  "客户管理": "customers", "销售漏斗": "sales_pipeline", "跟进记录": "follow_ups",
  // v1.1: Contract / Inspection / Callback / Warehouse / Schedule
  "合同": "contracts", "合同创建": "contracts", "合同归档": "contracts", "到期提醒": "reminders",
  "巡检": "inspections", "巡检计划": "inspection_plans", "巡检记录": "inspection_records",
  "故障": "faults", "故障上报": "faults", "设备": "equipment", "设备台账": "equipment",
  "回访": "callbacks", "回访计划": "callback_plans", "回访记录": "callback_records",
  "满意度": "satisfaction", "满意度评价": "satisfaction",
  "入库": "stock_in", "入库登记": "stock_in", "出库": "stock_out", "出库审批": "stock_out",
  "盘点": "stocktaking", "库存盘点": "stocktaking", "库存预警": "stock_alerts",
  "教室": "classrooms", "教室管理": "classrooms", "排课": "schedules", "排课冲突检测": "schedules",
  "课表": "schedules", "课表查看": "schedules",
  "合同管理": "contracts", "巡检系统": "inspections", "回访系统": "callbacks",
  "出入库": "warehouse", "排课系统": "schedules",
};
function _toSlug(name) {
  const c = name.replace(/[。，、；：！？\.\,\;\!\?]+$/g, "").trim();
  if (/^[a-z][a-z0-9_]*$/.test(c)) return c;
  if (_ZH_SLUG[c]) return _ZH_SLUG[c];
  // Longest-match-first: sort keys by length descending
  for (const zh of Object.keys(_ZH_SLUG).sort((a,b) => b.length - a.length)) {
    if (c.includes(zh)) return _ZH_SLUG[zh];
  }
  return c.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase().replace(/_+/g, "_").replace(/^_|_$/g, "") || "items";
}

function extractAPIsFromInput(input, features) {
  const apis = [];

  // Check for explicit API mentions
  const apiPattern = /(?:API|接口|api)[：:]*([^。]+)/g;
  const apiMatches = input.matchAll(apiPattern);
  for (const m of apiMatches) {
    const desc = m[1].trim();
    apis.push({ method: "GET", path: "/api/data", description: desc });
  }

  // If no explicit APIs, derive CRUD from features
  if (apis.length === 0 && features.length > 0) {
    for (const f of features.slice(0, 4)) {
      const slug = _toSlug(f.name);
      apis.push({ method: "GET", path: `/api/${slug}`, description: `获取${f.name}列表` });
      apis.push({ method: "POST", path: `/api/${slug}`, description: `创建${f.name}` });
    }
    // Always add auth
    apis.push({ method: "POST", path: "/api/auth/login", description: "用户登录" });
    apis.push({ method: "GET", path: "/api/auth/me", description: "获取当前用户" });
  }

  return apis;
}

// ═══════════════════════════════════════════════════════
// 4. PRD Generator
// ═══════════════════════════════════════════════════════

/**
 * Generate user stories from personas.
 *
 * @param {object[]} personas
 * @param {object[]} features
 * @returns {object[]}
 */
export function generateUserStories(personas, features) {
  const stories = [];
  let id = 1;

  for (const persona of personas) {
    for (const feature of features.slice(0, 3)) {
      stories.push({
        id: `US-${String(id).padStart(3, "0")}`,
        as: persona.name,
        want: feature.description,
        soThat: `解决痛点：${persona.painPoints[0] || "提升使用体验"}`,
        priority: feature.priority,
      });
      id++;
    }
  }

  return stories;
}

/**
 * Determine tech constraints based on domain and extra features.
 *
 * @param {object} domain
 * @param {string[]} platforms
 * @param {string[]} extraFeatures
 * @returns {object}
 */
export function determineTechConstraints(domain, platforms, extraFeatures) {
  const constraints = {
    platforms,
    recommendedStack: "",
    considerations: [],
  };

  if (platforms.includes("miniapp") || platforms.includes("wechat-miniapp")) {
    constraints.recommendedStack = "微信小程序原生 / Taro / uni-app";
    constraints.considerations.push("需通过微信审核");
    constraints.considerations.push("包大小限制 2MB（分包后可至 20MB）");
  } else if (platforms.includes("ios") && platforms.length === 1) {
    constraints.recommendedStack = "SwiftUI / UIKit";
    constraints.considerations.push("需通过 App Store 审核");
  } else if (platforms.includes("android") && platforms.length === 1) {
    constraints.recommendedStack = "Jetpack Compose / Kotlin";
    constraints.considerations.push("需适配 Android 各版本");
  } else {
    constraints.recommendedStack = "React Native / Flutter（跨平台）";
    constraints.considerations.push("建议跨平台框架减少开发成本");
  }

  if (extraFeatures.includes("wechat-pay")) {
    constraints.considerations.push("需接入微信支付商户平台");
  }
  if (extraFeatures.includes("alipay")) {
    constraints.considerations.push("需接入支付宝开放平台");
  }
  if (extraFeatures.includes("logistics-tracking")) {
    constraints.considerations.push("需对接物流公司 API（如快递鸟、菜鸟）");
  }
  if (extraFeatures.includes("ai-powered")) {
    constraints.considerations.push("需对接 AI 服务（如 OpenAI / 文心 / 通义）");
  }
  if (extraFeatures.includes("real-time")) {
    constraints.recommendedStack += " + WebSocket";
    constraints.considerations.push("需 WebSocket 或 SSE 支持实时通信");
  }
  if (extraFeatures.includes("offline-mode")) {
    constraints.considerations.push("需实现本地缓存和离线数据同步策略");
  }
  if (extraFeatures.includes("i18n")) {
    constraints.considerations.push("需集成 i18n 国际化方案");
  }
  if (extraFeatures.includes("push-notification")) {
    constraints.considerations.push("需对接推送服务（APNs / FCM / 个推）");
  }

  // Domain-specific constraints
  if (domain.chineseName?.includes("企业") || domain.chineseName?.includes("OA")) {
    constraints.considerations.push("需支持 RBAC 权限模型");
    constraints.considerations.push("需考虑企业 SSO 集成");
  }
  if (domain.chineseName?.includes("电商")) {
    constraints.considerations.push("需考虑高并发秒杀场景");
    constraints.considerations.push("需 PCI-DSS 或等保合规");
  }

  return constraints;
}

/**
 * Generate development tasks from features.
 *
 * @param {string} projectName
 * @param {object[]} features
 * @param {object[]} pages
 * @param {object[]} apiRequirements
 * @returns {object[]}
 */
export function generateDevTasks(projectName, features, pages, apiRequirements) {
  const tasks = [];
  let id = 1;

  // Foundation tasks
  tasks.push({
    id: `T-${String(id).padStart(3, "0")}`,
    title: "项目脚手架搭建",
    description: `初始化 ${projectName} 项目结构，配置构建工具和 CI/CD`,
    phase: "Foundation",
    estimatedHours: 8,
    priority: "P0",
  });
  id++;

  tasks.push({
    id: `T-${String(id).padStart(3, "0")}`,
    title: "数据库设计与初始化",
    description: "设计数据模型，创建数据库迁移脚本",
    phase: "Foundation",
    estimatedHours: 16,
    priority: "P0",
  });
  id++;

  // Page tasks
  for (const page of pages.slice(0, 4)) {
    tasks.push({
      id: `T-${String(id).padStart(3, "0")}`,
      title: `页面开发：${page.name}`,
      description: `开发 ${page.name} 页面（${page.route}）：${page.description}`,
      phase: "UI Development",
      estimatedHours: 8,
      priority: "P0",
    });
    id++;
  }

  // API tasks
  for (const api of apiRequirements.slice(0, 4)) {
    tasks.push({
      id: `T-${String(id).padStart(3, "0")}`,
      title: `API 开发：${api.method} ${api.path}`,
      description: api.description,
      phase: "Backend Development",
      estimatedHours: 4,
      priority: "P0",
    });
    id++;
  }

  // Integration & polish
  tasks.push({
    id: `T-${String(id).padStart(3, "0")}`,
    title: "前后端联调",
    description: "前端页面与后端 API 集成联调",
    phase: "Integration",
    estimatedHours: 16,
    priority: "P0",
  });
  id++;

  tasks.push({
    id: `T-${String(id).padStart(3, "0")}`,
    title: "测试与修复",
    description: "功能测试、Bug 修复、性能优化",
    phase: "Testing",
    estimatedHours: 24,
    priority: "P1",
  });
  id++;

  return tasks;
}

// ═══════════════════════════════════════════════════════
// 5. Main PRD Pipeline
// ═══════════════════════════════════════════════════════

/**
 * Generate a full PRD from user input.
 *
 * P0 FIX: User input is parsed FIRST. Domain template is supplementary only.
 * If user input provides features/pages/APIs, those take priority.
 * If extraction yields empty results, fail with error.
 *
 * @param {string} input — User's requirement description
 * @returns {object} — Structured PRD
 */
export function generatePRD(input) {
  const trimmed = (input || "").trim();

  if (!trimmed) {
    return {
      error: "EMPTY_INPUT",
      message: "请输入需求描述。例如：做一个宠物管理 App",
    };
  }

  // ── Step 1: Extract from user input (HIGHEST PRIORITY) ──
  const extractedName = extractProjectName(trimmed);
  const extractedFeatures = extractFeaturesFromInput(trimmed);
  const extractedAPIs = extractAPIsFromInput(trimmed, extractedFeatures);

  // ── Step 2: Match domain (supplementary only) ──
  const { domain, domainKey, matchCount } = matchDomain(trimmed);

  // ── Step 3: Merge — user input wins, domain fills gaps ──
  const projectName = extractedName || domain.projectName;
  const features = extractedFeatures.length > 0 ? extractedFeatures : domain.features;

  // Merge APIs: prefer domain template when user didn't mention explicit APIs
  // (extractedAPIs always includes CRUD per feature + auth; explicit API mentions use API/接口 pattern)
  const userMentionedAPIs = /(?:API|接口|api)/g.test(trimmed);
  const apiRequirements = userMentionedAPIs
    ? (extractedAPIs.length > 0 ? extractedAPIs : domain.apiRequirements)
    : (domain.apiRequirements.length > 0 ? domain.apiRequirements : extractedAPIs);

  // Extract pages AFTER features are resolved (so derived pages use final features)
  const extractedPages = extractPagesFromInput(trimmed, features);
  // Merge pages: prefer domain template when user didn't mention specific pages
  // (extractPagesFromInput always adds 首页 + feature-derived pages; explicit mentions are numbered lists)
  const userMentionedPages = /\d+[.、)）]/g.test(trimmed);
  const pages = userMentionedPages ? extractedPages : domain.pages;

  // ── Step 4: Fail if still empty (P0: prevent empty generation) ──
  if (features.length === 0 || pages.length === 0 || apiRequirements.length === 0) {
    return {
      error: "EXTRACTION_FAILED",
      message: `Requirement extraction failed: no ${features.length === 0 ? "features" : ""}${pages.length === 0 ? "/pages" : ""}${apiRequirements.length === 0 ? "/apis" : ""} detected. Please provide more detailed requirements.`,
      projectName,
      domain: domainKey,
      features,
      pages,
      apiRequirements,
    };
  }

  // ── Step 5: Build PRD ──
  const platforms = detectPlatforms(trimmed);
  const extraFeatures = detectExtraFeatures(trimmed);
  const userStories = generateUserStories(domain.personas, features);
  const techConstraints = determineTechConstraints(domain, platforms, extraFeatures);
  const devTasks = generateDevTasks(projectName, features, pages, apiRequirements);

  const mvpFeatures = features.filter(f => f.priority === "P0").map(f => f.name);
  const mvpPages = pages.slice(0, Math.ceil(pages.length * 0.6)).map(p => p.name);
  const totalEstimatedHours = devTasks.reduce((sum, t) => sum + t.estimatedHours, 0);

  return {
    projectName,
    chineseName: domain.chineseName || projectName,
    domain: domainKey,
    matchConfidence: matchCount > 0 ? (extractedFeatures.length > 0 ? "high" : "medium") : "low",
    summary: domain.summary || `${projectName} — 根据用户需求定制的应用。`,
    personas: domain.personas,
    userStories,
    mvpScope: {
      description: `MVP 聚焦 ${mvpFeatures.join("、")}，包含页面：${mvpPages.join("、")}`,
      features: mvpFeatures,
      pages: mvpPages,
      estimatedWeeks: Math.ceil(totalEstimatedHours / 40) || 2,
    },
    features,
    pages,
    apiRequirements,
    techConstraints,
    extraFeatures,
    devTasks,
    meta: {
      generatedAt: new Date().toISOString(),
      inputLength: trimmed.length,
      domainMatchCount: matchCount,
      extractedFeatureCount: extractedFeatures.length,
      extractedPageCount: extractedPages.length,
      extractedAPICount: extractedAPIs.length,
    },
  };
}

// ═══════════════════════════════════════════════════════
// 6. File I/O
// ═══════════════════════════════════════════════════════

export function loadInput(path) {
  try {
    if (!existsSync(path)) {
      return { data: null, error: `Input file not found: ${path}` };
    }
    const raw = readFileSync(path, "utf-8");
    return { data: JSON.parse(raw), error: null };
  } catch (e) {
    return { data: null, error: `Failed to load input: ${e.message}` };
  }
}

export function writeOutput(prd, outputPath, pretty = false) {
  const dir = dirname(outputPath);
  mkdirSync(dir, { recursive: true });
  const content = pretty ? JSON.stringify(prd, null, 2) : JSON.stringify(prd);
  writeFileSync(outputPath, content);
}

// ═══════════════════════════════════════════════════════
// 7. CLI Entry
// ═══════════════════════════════════════════════════════

function parseArgs() {
  const args = process.argv.slice(2);
  const opts = {
    input: null, inputFile: null, output: null,
    pretty: false, verbose: false, help: false,
  };
  for (let i = 0; i < args.length; i++) {
    if (args[i] === "--input" && args[i + 1]) opts.input = args[++i];
    else if (args[i] === "--input-file" && args[i + 1]) opts.inputFile = args[++i];
    else if (args[i] === "--output" && args[i + 1]) opts.output = args[++i];
    else if (args[i] === "--pretty") opts.pretty = true;
    else if (args[i] === "--verbose") opts.verbose = true;
    else if (args[i] === "--help" || args[i] === "-h") opts.help = true;
  }
  return opts;
}

function printJSON(data, pretty) {
  console.log(pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data));
}

async function main() {
  const opts = parseArgs();

  if (opts.help) {
    console.log(`
Project Intake & PRD Agent — SF-01

Usage:
  node scripts/project-intake-agent.mjs --input <text> [options]
  node scripts/project-intake-agent.mjs --input-file <path> [options]

Options:
  --input <text>        一句话需求
  --input-file <path>   从 JSON 文件读取需求（字段名：input）
  --output <path>       输出 PRD JSON 文件路径
  --pretty              Format JSON with indentation
  --verbose             详细输出
  --help                显示帮助

Examples:
  node scripts/project-intake-agent.mjs --input "做一个宠物管理 App" --pretty
  node scripts/project-intake-agent.mjs --input-file test/fixtures/project-intake/pet-management.json --output prd-output.json
`);
    return;
  }

  let inputText = null;

  if (opts.input) {
    inputText = opts.input;
  } else if (opts.inputFile) {
    const { data, error } = loadInput(opts.inputFile);
    if (error) { console.error(error); process.exit(1); }
    inputText = data.input || "";
  }

  if (!inputText) {
    console.error("Error: --input <text> or --input-file <path> is required. Use --help for usage.");
    process.exit(1);
  }

  const prd = generatePRD(inputText);

  if (opts.verbose) {
    console.error(`Input: "${inputText}"`);
    console.error(`Domain: ${prd.domain} (confidence: ${prd.matchConfidence})`);
    console.error(`Features: ${prd.features.length}, Pages: ${prd.pages.length}, APIs: ${prd.apiRequirements.length}`);
    console.error(`Dev Tasks: ${prd.devTasks.length}, Est. Hours: ${prd.devTasks.reduce((s,t) => s + t.estimatedHours, 0)}`);
  }

  if (opts.output) {
    writeOutput(prd, resolve(opts.output), opts.pretty);
    if (opts.verbose) console.error(`PRD written to: ${opts.output}`);
  }

  // Check for extraction failure
  if (prd.error === "EXTRACTION_FAILED") {
    console.error(prd.message);
    if (opts.output) writeOutput(prd, resolve(opts.output), opts.pretty);
    process.exit(1);
  }

  // Output project name + summary as minified summary
  printJSON({
    projectName: prd.projectName,
    chineseName: prd.chineseName,
    domain: prd.domain,
    summary: prd.summary,
    featureCount: prd.features.length,
    pageCount: prd.pages.length,
    apiCount: prd.apiRequirements.length,
    taskCount: prd.devTasks.length,
    totalEstimatedHours: prd.devTasks.reduce((s, t) => s + t.estimatedHours, 0),
    outputPath: opts.output || null,
  }, opts.pretty);
}

if (process.argv[1] && (import.meta.url === `file://${process.argv[1]}` || import.meta.url.endsWith(process.argv[1]))) {
  main();
}
