#!/usr/bin/env node

/**
 * Architecture Agent — SF-02
 *
 * 根据 SF-01 生成的 PRD 自动生成技术架构。
 *
 * 核心功能：
 *   - 技术选型：前端/后端/数据库/部署
 *   - 系统架构图：ASCII art 三层架构
 *   - 数据流：请求链路文档
 *   - 模块划分：按功能域拆解
 *   - 数据库设计：表结构 + 字段 + 关系
 *   - API 设计：按资源分组
 *   - 目录结构：完整 /src 树
 *
 * Usage:
 *   node scripts/architecture-agent.mjs --input <prd.json> [options]
 *   node scripts/architecture-agent.mjs --input-text "做一个宠物管理 App" [options]
 *
 * Options:
 *   --input <path>         PRD JSON 文件路径
 *   --input-text <text>   直接传入需求（先调 SF-01 生成 PRD）
 *   --output <path>        输出架构 JSON 文件路径
 *   --pretty               格式化 JSON 输出
 *   --verbose              详细输出
 *   --help                 显示帮助
 *
 * @module architecture-agent
 */

import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { createContract } from "./model-contract.mjs";

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

// ═══════════════════════════════════════════════════════
// 1. Tech Stack Templates
// ═══════════════════════════════════════════════════════

/**
 * Tech stack options keyed by platform combination.
 */
const TECH_STACKS = {
  "wechat-miniapp": {
    frontend: "微信小程序原生 / Taro 3.x + React",
    backend: "Node.js + Express / 云函数（微信云开发）",
    database: "MySQL 8.0（用户数据）+ 微信云数据库（小程序数据）",
    deployment: "微信云托管 / 腾讯云 Lighthouse",
  },
  miniapp: {
    frontend: "uni-app 3.x（多端小程序）",
    backend: "Node.js + Koa2 / NestJS",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "阿里云 ECS / Docker + Nginx",
  },
  "ios-only": {
    frontend: "SwiftUI + Combine（iOS 17+）",
    backend: "Vapor 4（Swift 服务端）/ Node.js + Express",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "AWS EC2 / Railway + App Store Connect",
  },
  "android-only": {
    frontend: "Jetpack Compose + Kotlin Coroutines",
    backend: "Spring Boot 3 / Ktor",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "GCP Cloud Run / AWS ECS",
  },
  "web-only": {
    frontend: "React 19 + TypeScript + Vite",
    backend: "NestJS / Fastify",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "Docker + Nginx / Vercel + Railway",
  },
  "mobile-web": {
    frontend: "React Native 0.76 + Expo / Flutter 3.x",
    backend: "NestJS + Prisma",
    database: "PostgreSQL 15 + Redis 7 + MinIO（文件存储）",
    deployment: "Docker Compose + Nginx / K8s（规模化）",
  },
  mobile: {
    frontend: "React Native 0.76 + Expo",
    backend: "NestJS + Prisma",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "Docker Compose + Nginx",
  },
  default: {
    frontend: "React 19 + TypeScript + Vite",
    backend: "NestJS + Prisma",
    database: "PostgreSQL 15 + Redis 7",
    deployment: "Docker + Nginx",
  },
};

// ═══════════════════════════════════════════════════════
// 2. Architecture Diagram Generator (ASCII)
// ═══════════════════════════════════════════════════════

/**
 * Generate an ASCII architecture diagram.
 *
 * @param {string} projectName
 * @param {object} stack — Tech stack
 * @param {string[]} modules — Module names
 * @returns {string}
 */
export function generateArchDiagram(projectName, stack, modules) {
  const modList = modules.slice(0, 6).map((m, i) => `│  ${String(i + 1).padEnd(3)} ${m.padEnd(24)} │`).join("\n");

  return [
    `┌─────────────────────────────────────────────────────────┐`,
    `│              ${projectName} — System Architecture              │`,
    `├─────────────────────────────────────────────────────────┤`,
    `│                                                         │`,
    `│  ┌──────────────────────┐    ┌──────────────────────┐   │`,
    `│  │    Client Layer       │    │    Admin / Web       │   │`,
    `│  │  ${(stack.frontend || "Mobile App").padEnd(20)} │    │  React + Vite (Web)  │   │`,
    `│  └──────────┬───────────┘    └──────────┬───────────┘   │`,
    `│             │                           │                │`,
    `│             └──────────┬────────────────┘                │`,
    `│                        │                                 │`,
    `│              ┌─────────▼──────────┐                      │`,
    `│              │   API Gateway       │                      │`,
    `│              │  Nginx / Kong       │                      │`,
    `│              └─────────┬──────────┘                      │`,
    `│                        │                                 │`,
    `│              ┌─────────▼──────────┐                      │`,
    `│              │   Backend Services  │                      │`,
    `│              │  ${(stack.backend || "NestJS").padEnd(20)} │                      │`,
    `│              └─────────┬──────────┘                      │`,
    `│                        │                                 │`,
    `│        ┌───────────────┼───────────────┐                 │`,
    `│        │               │               │                 │`,
    `│  ┌─────▼─────┐  ┌──────▼──────┐  ┌────▼─────┐           │`,
    `│  │ ${(stack.database || "PostgreSQL").split("+")[0].trim().padEnd(12)}│  │ Redis Cache │  │   MinIO   │           │`,
    `│  │  Primary   │  │   Session   │  │  Files    │           │`,
    `│  └───────────┘  └─────────────┘  └──────────┘           │`,
    `│                                                         │`,
    `├─────────────────────────────────────────────────────────┤`,
    `│  Modules:                                                │`,
    `${modList}`,
    `│                                                         │`,
    `└─────────────────────────────────────────────────────────┘`,
  ].join("\n");
}

// ═══════════════════════════════════════════════════════
// 3. Data Flow Generator
// ═══════════════════════════════════════════════════════

/**
 * Generate data flow documentation from pages and API requirements.
 *
 * @param {object[]} pages
 * @param {object[]} apis
 * @returns {object[]}
 */
export function generateDataFlows(pages, apis) {
  const flows = [];

  for (const page of pages.slice(0, 5)) {
    const pageName = page.name;
    const route = page.route;

    // Find APIs related to this page (simple heuristic: route name in API path)
    const relatedApis = apis.filter(a =>
      route.replace(/[:/]/g, "").split("/").some(seg =>
        a.path.includes(seg.replace(":id", ""))
      )
    ).slice(0, 2);

    if (relatedApis.length > 0) {
      flows.push({
        page: pageName,
        route,
        description: page.description,
        dataFlow: relatedApis.map(a => `${a.method} ${a.path} → ${a.description}`),
        direction: "Client → API Gateway → Backend → Database → Response → Client",
      });
    }
  }

  // If no specific flows found, generate generic ones from APIs
  if (flows.length === 0 && apis.length > 0) {
    flows.push({
      page: "通用页面",
      route: "/*",
      description: "通用数据流",
      dataFlow: apis.slice(0, 4).map(a => `${a.method} ${a.path} → ${a.description}`),
      direction: "Client → API Gateway → Backend → Database → Response → Client",
    });
  }

  return flows;
}

// ═══════════════════════════════════════════════════════
// 4. Module Decomposition Engine
// ═══════════════════════════════════════════════════════

/**
 * Decompose features into backend modules.
 *
 * @param {object[]} features
 * @param {string} domain
 * @returns {object[]}
 */
export function decomposeModules(features, domain) {
  // Group features into logical modules by keyword
  const moduleMap = new Map();
  const modulePatterns = {
    auth: ["用户", "登录", "注册", "权限", "角色", "auth", "profile"],
    settings: ["设置", "偏好", "配置"],
    notification: ["通知", "提醒", "推送", "消息"],
    storage: ["上传", "文件", "图片", "相册", "照片"],
    analytics: ["统计", "报告", "分析", "趋势"],
    content: ["社区", "分享", "动态", "评论", "评价"],
    payment: ["支付", "订单", "购物车", "优惠券"],
    schedule: ["日程", "日历", "提醒", "预约"],
    workflow: ["审批", "流程", "考勤", "请假", "报销"],
  };

  // Default grouping: 1 feature = 1 module
  for (const feature of features) {
    let assigned = false;
    for (const [modKey, keywords] of Object.entries(modulePatterns)) {
      if (keywords.some(kw => feature.name.includes(kw))) {
        if (!moduleMap.has(modKey)) {
          moduleMap.set(modKey, { name: modKey, label: modKey.charAt(0).toUpperCase() + modKey.slice(1), features: [] });
        }
        moduleMap.get(modKey).features.push(feature.name);
        assigned = true;
        break;
      }
    }
    if (!assigned) {
      const key = feature.name;
      if (!moduleMap.has(key)) {
        moduleMap.set(key, { name: key, label: feature.name, features: [feature.name] });
      }
    }
  }

  // Domain-specific module additions
  const domainModules = {
    pet: [{ name: "pet", label: "宠物管理", features: ["宠物档案", "健康日程"] }],
    ecommerce: [
      { name: "product", label: "商品管理", features: ["商品浏览"] },
      { name: "order", label: "订单管理", features: ["订单管理"] },
    ],
    education: [
      { name: "course", label: "课程管理", features: ["课程中心", "视频播放"] },
      { name: "exercise", label: "题库管理", features: ["题库练习"] },
    ],
    enterprise: [
      { name: "approval", label: "审批引擎", features: ["审批流程"] },
      { name: "attendance", label: "考勤管理", features: ["考勤打卡"] },
      { name: "department", label: "组织架构", features: ["部门管理"] },
    ],
    fitness: [
      { name: "checkin", label: "打卡引擎", features: ["打卡记录"] },
      { name: "plan", label: "训练计划", features: ["训练计划"] },
    ],
    note: [
      { name: "editor", label: "编辑器", features: ["笔记编辑"] },
      { name: "search", label: "搜索引擎", features: ["全文搜索"] },
    ],
  };

  const extraModules = domainModules[domain] || [];
  for (const em of extraModules) {
    if (!moduleMap.has(em.name)) {
      moduleMap.set(em.name, em);
    }
  }

  return Array.from(moduleMap.values());
}

// ═══════════════════════════════════════════════════════
// 5. Database Design Engine
// ═══════════════════════════════════════════════════════

/**
 * Generate database schema from PRD.
 *
 * @param {object[]} features
 * @param {object[]} apis
 * @param {string} domain
 * @returns {object[]} — Array of table definitions
 */

/**
 * Chinese-to-English slug mapping for common entity names.
 */
const ZH_SLUG_MAP = {
  "书籍库": "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",
  "公告": "notices", "通知": "notifications", "报销": "expenses", "请假": "leaves",
  "打卡": "checkins", "部门": "departments", "薪资": "salaries", "绩效": "performance",
  "客户管理": "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 toSafeSlug(name) {
  // Strip trailing Chinese/English punctuation
  const cleaned = name.replace(/[。，、；：！？\.\,\;\!\?]+$/g, "").trim();
  if (/^[a-z][a-z0-9_]*$/.test(cleaned)) return cleaned;
  if (ZH_SLUG_MAP[cleaned]) return ZH_SLUG_MAP[cleaned];
  // Longest-match-first
  for (const zh of Object.keys(ZH_SLUG_MAP).sort((a,b) => b.length - a.length)) {
    if (cleaned.includes(zh)) return ZH_SLUG_MAP[zh];
  }
  const slug = cleaned.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase().replace(/_+/g, "_").replace(/^_|_$/g, "");
  return slug || "items";
}

/**
 * Domain-specific field templates keyed by keyword match.
 * Each entry: { match: string[], fields: [...extra fields beyond id/user_id/timestamps] }
 * These are inserted BETWEEN user_id and created_at.
 */
const FIELD_TEMPLATES = [
  // ── Books / Reading ──
  { match: ["book", "书籍"], fields: [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "author", type: "VARCHAR(128)" },
    { name: "isbn", type: "VARCHAR(20)" },
    { name: "cover_url", type: "TEXT" },
    { name: "publisher", type: "VARCHAR(128)" },
    { name: "publish_date", type: "DATE" },
    { name: "genre", type: "VARCHAR(64)" },
  ]},
  { match: ["reading_status", "阅读状态"], fields: [
    { name: "book_id", type: "UUID", constraints: "FK → books.id" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'unread', CHECK (status IN ('unread','reading','finished','abandoned'))" },
    { name: "started_at", type: "TIMESTAMPTZ" },
    { name: "finished_at", type: "TIMESTAMPTZ" },
  ]},
  { match: ["reading_progress", "阅读进度"], fields: [
    { name: "book_id", type: "UUID", constraints: "FK → books.id" },
    { name: "current_page", type: "INTEGER", constraints: "DEFAULT 0" },
    { name: "total_pages", type: "INTEGER" },
    { name: "percentage", type: "DECIMAL(5,2)", constraints: "DEFAULT 0" },
  ]},
  { match: ["review", "书评"], fields: [
    { name: "book_id", type: "UUID", constraints: "FK → books.id" },
    { name: "rating", type: "INTEGER", constraints: "CHECK (rating >= 1 AND rating <= 5)" },
    { name: "content", type: "TEXT" },
  ]},
  // ── Tasks / Boards ──
  { match: ["task"], fields: [
    { name: "board_id", type: "UUID", constraints: "FK → boards.id" },
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'todo'" },
    { name: "priority", type: "VARCHAR(16)", constraints: "DEFAULT 'medium'" },
    { name: "due_date", type: "DATE" },
    { name: "assignee_id", type: "UUID", constraints: "FK → users.id" },
  ]},
  { match: ["board", "看板"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "color", type: "VARCHAR(7)" },
  ]},
  { match: ["member", "成员"], fields: [
    { name: "board_id", type: "UUID", constraints: "FK → boards.id" },
    { name: "user_id", type: "UUID", constraints: "FK → users.id" },
    { name: "role", type: "VARCHAR(32)", constraints: "DEFAULT 'member'" },
  ]},
  { match: ["activity_log", "活动日志"], fields: [
    { name: "board_id", type: "UUID", constraints: "FK → boards.id" },
    { name: "action", type: "VARCHAR(64)", constraints: "NOT NULL" },
    { name: "entity_type", type: "VARCHAR(32)" },
    { name: "entity_id", type: "UUID" },
    { name: "detail", type: "JSONB" },
  ]},
  // ── Food / Meal ──
  { match: ["food", "食物"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "category", type: "VARCHAR(64)" },
    { name: "calories_per_100g", type: "INTEGER" },
    { name: "protein_g", type: "DECIMAL(5,2)" },
    { name: "fat_g", type: "DECIMAL(5,2)" },
    { name: "carb_g", type: "DECIMAL(5,2)" },
  ]},
  { match: ["meal_plan", "餐计划"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "start_date", type: "DATE" },
    { name: "end_date", type: "DATE" },
    { name: "target_calories", type: "INTEGER" },
  ]},
  { match: ["nutrition", "营养"], fields: [
    { name: "food_id", type: "UUID", constraints: "FK → foods.id" },
    { name: "meal_plan_id", type: "UUID", constraints: "FK → meal_plans.id" },
    { name: "serving_g", type: "DECIMAL(6,2)" },
    { name: "meal_type", type: "VARCHAR(32)" },
  ]},
  { match: ["shopping_list", "购物清单"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "items", type: "JSONB", constraints: "DEFAULT '[]'" },
    { name: "completed", type: "BOOLEAN", constraints: "DEFAULT false" },
  ]},
  // ── CRM ──
  { match: ["customer", "客户管理"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "email", type: "VARCHAR(256)" },
    { name: "phone", type: "VARCHAR(20)" },
    { name: "company", type: "VARCHAR(128)" },
    { name: "source", type: "VARCHAR(64)" },
    { name: "tags", type: "JSONB", constraints: "DEFAULT '[]'" },
  ]},
  { match: ["sales_pipeline", "销售漏斗"], fields: [
    { name: "customer_id", type: "UUID", constraints: "FK → customers.id" },
    { name: "stage", type: "VARCHAR(32)", constraints: "NOT NULL" },
    { name: "amount", type: "DECIMAL(12,2)" },
    { name: "probability", type: "INTEGER" },
    { name: "expected_close", type: "DATE" },
  ]},
  { match: ["follow_up", "跟进记录"], fields: [
    { name: "customer_id", type: "UUID", constraints: "FK → customers.id" },
    { name: "type", type: "VARCHAR(32)" },
    { name: "content", type: "TEXT" },
    { name: "next_action", type: "VARCHAR(256)" },
    { name: "next_action_date", type: "DATE" },
  ]},
  // ── Inventory ──
  { match: ["inventory", "库存"], exclude: ["stocktaking", "stock_alert", "库存盘点", "库存预警"], fields: [
    { name: "product_id", type: "UUID", constraints: "FK → products.id" },
    { name: "quantity", type: "INTEGER", constraints: "DEFAULT 0" },
    { name: "warehouse", type: "VARCHAR(64)" },
    { name: "min_stock", type: "INTEGER", constraints: "DEFAULT 0" },
    { name: "max_stock", type: "INTEGER" },
  ]},
  { match: ["supplier", "供应商"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "contact", type: "VARCHAR(64)" },
    { name: "phone", type: "VARCHAR(20)" },
    { name: "email", type: "VARCHAR(256)" },
    { name: "address", type: "TEXT" },
  ]},
  // ── Ticket / OA ──
  { match: ["ticket", "工单"], fields: [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "priority", type: "VARCHAR(16)", constraints: "DEFAULT 'medium'" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'open'" },
    { name: "assignee_id", type: "UUID", constraints: "FK → users.id" },
    { name: "category", type: "VARCHAR(64)" },
  ]},
  { match: ["employee", "员工"], fields: [
    { name: "name", type: "VARCHAR(64)", constraints: "NOT NULL" },
    { name: "email", type: "VARCHAR(256)" },
    { name: "phone", type: "VARCHAR(20)" },
    { name: "department", type: "VARCHAR(64)" },
    { name: "position", type: "VARCHAR(64)" },
    { name: "hire_date", type: "DATE" },
    { name: "salary", type: "DECIMAL(12,2)" },
  ]},
  // ── Education ──
  { match: ["course", "课程"], fields: [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "instructor", type: "VARCHAR(64)" },
    { name: "price", type: "DECIMAL(10,2)" },
    { name: "cover_url", type: "TEXT" },
    { name: "category", type: "VARCHAR(64)" },
  ]},
  { match: ["chapter", "章节"], fields: [
    { name: "course_id", type: "UUID", constraints: "FK → courses.id" },
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "sort_order", type: "INTEGER", constraints: "DEFAULT 0" },
    { name: "duration_min", type: "INTEGER" },
  ]},
  { match: ["student", "学员"], fields: [
    { name: "name", type: "VARCHAR(64)", constraints: "NOT NULL" },
    { name: "email", type: "VARCHAR(256)" },
    { name: "enrolled_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
    { name: "progress", type: "DECIMAL(5,2)", constraints: "DEFAULT 0" },
  ]},
  { match: ["assignment", "作业"], fields: [
    { name: "course_id", type: "UUID", constraints: "FK → courses.id" },
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "due_date", type: "DATE" },
    { name: "max_score", type: "INTEGER", constraints: "DEFAULT 100" },
  ]},
  // ── Appointment / Service ──
  { match: ["appointment", "预约"], fields: [
    { name: "client_id", type: "UUID", constraints: "FK → clients.id" },
    { name: "service_id", type: "UUID", constraints: "FK → services.id" },
    { name: "start_time", type: "TIMESTAMPTZ", constraints: "NOT NULL" },
    { name: "end_time", type: "TIMESTAMPTZ" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'pending'" },
    { name: "notes", type: "TEXT" },
  ]},
  { match: ["service", "服务"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "duration_min", type: "INTEGER" },
    { name: "price", type: "DECIMAL(10,2)" },
  ]},
  // ── Asset ──
  { match: ["asset", "资产"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "category", type: "VARCHAR(64)" },
    { name: "purchase_date", type: "DATE" },
    { name: "purchase_price", type: "DECIMAL(12,2)" },
    { name: "current_value", type: "DECIMAL(12,2)" },
    { name: "location", type: "VARCHAR(128)" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'available'" },
  ]},
  // ── Pet ──
  { match: ["pet", "宠物"], fields: [
    { name: "name", type: "VARCHAR(64)", constraints: "NOT NULL" },
    { name: "species", type: "VARCHAR(32)" },
    { name: "breed", type: "VARCHAR(64)" },
    { name: "birth_date", type: "DATE" },
    { name: "weight_kg", type: "DECIMAL(5,2)" },
    { name: "avatar_url", type: "TEXT" },
  ]},
  { match: ["album", "相册"], fields: [
    { name: "title", type: "VARCHAR(128)" },
    { name: "image_url", type: "TEXT", constraints: "NOT NULL" },
    { name: "caption", type: "TEXT" },
    { name: "taken_at", type: "TIMESTAMPTZ" },
  ]},
  { match: ["hospital", "医院"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "address", type: "TEXT" },
    { name: "phone", type: "VARCHAR(20)" },
    { name: "rating", type: "DECIMAL(2,1)" },
    { name: "lat", type: "DECIMAL(9,6)" },
    { name: "lng", type: "DECIMAL(9,6)" },
  ]},
  // ── Blog / CMS ──
  { match: ["article", "文章"], fields: [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "content", type: "TEXT" },
    { name: "excerpt", type: "TEXT" },
    { name: "cover_url", type: "TEXT" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'draft'" },
    { name: "author_id", type: "UUID", constraints: "FK → users.id" },
    { name: "category", type: "VARCHAR(64)" },
    { name: "published_at", type: "TIMESTAMPTZ" },
  ]},
  { match: ["comment", "评论"], fields: [
    { name: "entity_type", type: "VARCHAR(32)", constraints: "NOT NULL" },
    { name: "entity_id", type: "UUID", constraints: "NOT NULL" },
    { name: "content", type: "TEXT", constraints: "NOT NULL" },
    { name: "parent_id", type: "UUID", constraints: "FK → comments.id (自引用)" },
  ]},
  { match: ["media", "媒体"], fields: [
    { name: "filename", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "url", type: "TEXT", constraints: "NOT NULL" },
    { name: "mime_type", type: "VARCHAR(64)" },
    { name: "size_bytes", type: "INTEGER" },
  ]},
  // ── Tags (通用) ──
  { match: ["tag", "标签"], fields: [
    { name: "name", type: "VARCHAR(64)", constraints: "NOT NULL, UNIQUE" },
    { name: "color", type: "VARCHAR(7)" },
  ]},
  // ── Stats / Dashboard ──
  { match: ["stat", "统计", "dashboard", "仪表盘"], fields: [
    { name: "metric", type: "VARCHAR(64)", constraints: "NOT NULL" },
    { name: "value", type: "DECIMAL(12,2)" },
    { name: "period", type: "VARCHAR(32)" },
    { name: "recorded_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  // ── Contract ──
  { match: ["contract", "合同"], fields: [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "party_a", type: "VARCHAR(128)" },
    { name: "party_b", type: "VARCHAR(128)" },
    { name: "amount", type: "DECIMAL(14,2)" },
    { name: "signed_at", type: "DATE" },
    { name: "expires_at", type: "DATE" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'draft'" },
    { name: "file_url", type: "TEXT" },
  ]},
  // ── Approval / Reminder ──
  { match: ["approval", "审批"], exclude: ["stock_out", "出库审批"], fields: [
    { name: "entity_type", type: "VARCHAR(32)", constraints: "NOT NULL" },
    { name: "entity_id", type: "UUID" },
    { name: "applicant_id", type: "UUID", constraints: "FK → users.id" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'pending'" },
    { name: "form_data", type: "JSONB" },
  ]},
  { match: ["reminder", "提醒", "到期提醒"], fields: [
    { name: "entity_type", type: "VARCHAR(32)", constraints: "NOT NULL" },
    { name: "entity_id", type: "UUID" },
    { name: "remind_at", type: "TIMESTAMPTZ", constraints: "NOT NULL" },
    { name: "message", type: "TEXT" },
    { name: "sent", type: "BOOLEAN", constraints: "DEFAULT false" },
  ]},
  // ── Inspection ──
  { match: ["inspection_plan", "巡检计划"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "frequency", type: "VARCHAR(32)" },
    { name: "equipment_id", type: "UUID", constraints: "FK → equipment.id" },
    { name: "next_run", type: "TIMESTAMPTZ" },
    { name: "active", type: "BOOLEAN", constraints: "DEFAULT true" },
  ]},
  { match: ["inspection_record", "巡检记录"], fields: [
    { name: "plan_id", type: "UUID", constraints: "FK → inspection_plans.id" },
    { name: "equipment_id", type: "UUID", constraints: "FK → equipment.id" },
    { name: "inspector_id", type: "UUID", constraints: "FK → users.id" },
    { name: "result", type: "VARCHAR(32)" },
    { name: "notes", type: "TEXT" },
    { name: "inspected_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  { match: ["fault", "故障"], fields: [
    { name: "equipment_id", type: "UUID", constraints: "FK → equipment.id" },
    { name: "reported_by", type: "UUID", constraints: "FK → users.id" },
    { name: "description", type: "TEXT", constraints: "NOT NULL" },
    { name: "severity", type: "VARCHAR(16)", constraints: "DEFAULT 'medium'" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'open'" },
    { name: "resolved_at", type: "TIMESTAMPTZ" },
  ]},
  { match: ["equipment", "设备"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "code", type: "VARCHAR(64)", constraints: "UNIQUE" },
    { name: "location", type: "VARCHAR(128)" },
    { name: "model", type: "VARCHAR(64)" },
    { name: "installed_at", type: "DATE" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'active'" },
  ]},
  // ── Callback / Satisfaction ──
  { match: ["callback_plan", "回访计划"], fields: [
    { name: "customer_id", type: "UUID", constraints: "FK → clients.id" },
    { name: "scheduled_at", type: "TIMESTAMPTZ", constraints: "NOT NULL" },
    { name: "assigned_to", type: "UUID", constraints: "FK → users.id" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'pending'" },
  ]},
  { match: ["callback_record", "回访记录"], fields: [
    { name: "plan_id", type: "UUID", constraints: "FK → callback_plans.id" },
    { name: "customer_id", type: "UUID", constraints: "FK → clients.id" },
    { name: "content", type: "TEXT" },
    { name: "result", type: "VARCHAR(32)" },
    { name: "visited_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  { match: ["satisfaction", "满意度"], fields: [
    { name: "customer_id", type: "UUID", constraints: "FK → clients.id" },
    { name: "callback_record_id", type: "UUID", constraints: "FK → callback_records.id" },
    { name: "rating", type: "INTEGER", constraints: "CHECK (rating >= 1 AND rating <= 5)" },
    { name: "feedback", type: "TEXT" },
  ]},
  // ── Warehouse / Stock ──
  { match: ["stock_in", "入库"], fields: [
    { name: "product_name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "quantity", type: "INTEGER", constraints: "NOT NULL" },
    { name: "supplier", type: "VARCHAR(128)" },
    { name: "received_by", type: "UUID", constraints: "FK → users.id" },
    { name: "received_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  { match: ["stock_out", "出库"], fields: [
    { name: "product_name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "quantity", type: "INTEGER", constraints: "NOT NULL" },
    { name: "recipient", type: "VARCHAR(128)" },
    { name: "approved_by", type: "UUID", constraints: "FK → users.id" },
    { name: "shipped_at", type: "TIMESTAMPTZ" },
  ]},
  { match: ["stocktaking", "盘点"], fields: [
    { name: "warehouse", type: "VARCHAR(64)" },
    { name: "product_name", type: "VARCHAR(128)" },
    { name: "expected_qty", type: "INTEGER" },
    { name: "actual_qty", type: "INTEGER" },
    { name: "diff", type: "INTEGER" },
    { name: "stocktaken_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  { match: ["stock_alert", "库存预警"], fields: [
    { name: "product_name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "current_qty", type: "INTEGER" },
    { name: "threshold", type: "INTEGER" },
    { name: "alerted_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ]},
  // ── Classroom / Schedule ──
  { match: ["classroom", "教室"], fields: [
    { name: "name", type: "VARCHAR(128)", constraints: "NOT NULL" },
    { name: "building", type: "VARCHAR(64)" },
    { name: "capacity", type: "INTEGER" },
    { name: "equipment", type: "JSONB" },
  ]},
  { match: ["schedule", "排课", "课表"], fields: [
    { name: "course_id", type: "UUID", constraints: "FK → courses.id" },
    { name: "classroom_id", type: "UUID", constraints: "FK → classrooms.id" },
    { name: "instructor_id", type: "UUID", constraints: "FK → users.id" },
    { name: "day_of_week", type: "INTEGER", constraints: "CHECK (day_of_week >= 0 AND day_of_week <= 6)" },
    { name: "start_time", type: "TIME" },
    { name: "end_time", type: "TIME" },
  ]},
];

/**
 * Match a table name against field templates to get domain-specific fields.
 * Returns the best-matching template's fields, or generic fields as fallback.
 */
function getDomainFields(tableName, featureName) {
  const lower = tableName.toLowerCase();
  const featureLower = (featureName || "").toLowerCase();
  for (const template of FIELD_TEMPLATES) {
    // Check exclusions first
    if (template.exclude && template.exclude.some(ex => lower === ex || lower.includes(ex) || featureLower.includes(ex))) {
      continue;
    }
    for (const keyword of template.match) {
      if (lower === keyword || lower.includes(keyword) || featureLower.includes(keyword)) {
        return template.fields;
      }
    }
  }
  // Generic fallback
  return [
    { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
    { name: "description", type: "TEXT" },
    { name: "status", type: "VARCHAR(32)", constraints: "DEFAULT 'active'" },
    { name: "data", type: "JSONB" },
  ];
}

function deriveTableFromFeature(feature) {
  const tableName = toSafeSlug(feature.name);
  if (tableName === "users" || tableName === "auth") return null;
  const domainFields = getDomainFields(tableName, feature.name);
  // Deduplicate: domain fields override base fields with same name
  const baseNames = new Set(["id", "user_id", "created_at", "updated_at"]);
  const merged = [
    { name: "id", type: "UUID", constraints: "PK, DEFAULT gen_random_uuid()" },
    { name: "user_id", type: "UUID", constraints: "FK → users.id" },
    ...domainFields.filter(f => !baseNames.has(f.name)),
    { name: "created_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
    { name: "updated_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
  ];
  return {
    table: tableName,
    description: (feature.description || feature.name) + "表",
    fields: merged,
    indexes: ["idx_" + tableName + "_user ON " + tableName + "(user_id)"],
  };
}

export function generateDatabaseSchema(features, apis, domain) {
  const tables = [];

  // Always: users table
  tables.push({
    table: "users",
    description: "用户表",
    fields: [
      { name: "id", type: "UUID", constraints: "PK, DEFAULT gen_random_uuid()" },
      { name: "phone", type: "VARCHAR(20)", constraints: "UNIQUE" },
      { name: "nickname", type: "VARCHAR(64)" },
      { name: "avatar_url", type: "TEXT" },
      { name: "created_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
      { name: "updated_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
    ],
    indexes: ["idx_users_phone ON users(phone)"],
  });

  // Resource tables derived from API paths
  const resourceMap = new Map();
  for (const api of apis) {
    // Extract resource name from path: /api/pets → pets, /api/orders → orders
    const match = api.path.match(/^\/api\/([^/:]+)/);
    if (match) {
      const resource = match[1];
      if (resource === "auth" || resource === "health") continue;
      if (!resourceMap.has(resource)) resourceMap.set(resource, []);
      resourceMap.get(resource).push(api);
    }
  }


  // Derive tables from features (P0 fix: user input > domain template)
  const derivedTableNames = new Set();
  for (const feature of features) {
    const table = deriveTableFromFeature(feature);
    if (table && !derivedTableNames.has(table.table)) {
      derivedTableNames.add(table.table);
      tables.push(table);
    }
  }

  // Also add tables from API paths not covered by features
  for (const [resource] of resourceMap) {
    if (!derivedTableNames.has(resource) && resource !== "users") {
      derivedTableNames.add(resource);
      tables.push({
        table: resource,
        description: resource + "表",
        fields: [
          { name: "id", type: "UUID", constraints: "PK, DEFAULT gen_random_uuid()" },
          { name: "user_id", type: "UUID", constraints: "FK → users.id" },
          { name: "title", type: "VARCHAR(256)", constraints: "NOT NULL" },
          { name: "data", type: "JSONB" },
          { name: "created_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
          { name: "updated_at", type: "TIMESTAMPTZ", constraints: "DEFAULT NOW()" },
        ],
      });
    }
  }

  return tables;
}

// ═══════════════════════════════════════════════════════
// 6. API Design Generator
// ═══════════════════════════════════════════════════════

/**
 * Group and enrich API requirements.
 *
 * @param {object[]} apiRequirements
 * @returns {object[]}
 */
export function designAPI(apiRequirements) {
  // Group APIs by resource
  const resourceMap = new Map();

  for (const api of apiRequirements) {
    const match = api.path.match(/^\/api\/([^/:]+)/);
    const resource = match ? match[1] : "misc";

    if (!resourceMap.has(resource)) {
      resourceMap.set(resource, {
        resource,
        basePath: `/api/${resource}`,
        endpoints: [],
      });
    }
    resourceMap.get(resource).endpoints.push({
      method: api.method,
      path: api.path,
      description: api.description,
    });
  }

  // Sort resources alphabetically
  return Array.from(resourceMap.values()).sort((a, b) => a.resource.localeCompare(b.resource));
}

// ═══════════════════════════════════════════════════════
// 7. Directory Structure Generator
// ═══════════════════════════════════════════════════════

/**
 * Generate a project directory structure from the architecture.
 *
 * @param {string} projectName
 * @param {string} domain
 * @param {object[]} modules
 * @returns {string[]} — Lines of directory tree text
 */
export function generateDirectoryStructure(projectName, domain, modules) {
  const dirName = projectName.toLowerCase();
  const lines = [];

  lines.push(`${dirName}/`);
  lines.push(`├── apps/`);
  lines.push(`│   ├── mobile/                    # React Native / Flutter 移动端`);
  lines.push(`│   │   ├── src/`);
  lines.push(`│   │   │   ├── screens/           # 页面组件`);

  // Screen directories from modules
  for (const mod of modules.slice(0, 4)) {
    lines.push(`│   │   │   │   ├── ${mod.name}/`);
  }
  lines.push(`│   │   │   ├── components/        # 通用组件`);
  lines.push(`│   │   │   ├── hooks/             # 自定义 Hooks`);
  lines.push(`│   │   │   ├── services/          # API 调用层`);
  lines.push(`│   │   │   ├── store/             # 状态管理`);
  lines.push(`│   │   │   └── utils/             # 工具函数`);
  lines.push(`│   │   ├── app.json`);
  lines.push(`│   │   └── package.json`);
  lines.push(`│   └── web/                       # Web 管理后台`);
  lines.push(`│       ├── src/`);
  lines.push(`│       │   ├── pages/`);
  lines.push(`│       │   ├── components/`);
  lines.push(`│       │   └── layouts/`);
  lines.push(`│       └── package.json`);
  lines.push(`├── packages/`);
  lines.push(`│   └── shared/                    # 共享类型/常量`);

  // Backend
  lines.push(`├── server/                        # NestJS 后端服务`);
  lines.push(`│   ├── src/`);
  lines.push(`│   │   ├── modules/               # 业务模块`);

  for (const mod of modules.slice(0, 5)) {
    const modName = mod.name.replace(/\s+/g, "-").toLowerCase();
    lines.push(`│   │   │   ├── ${modName}/`);
    lines.push(`│   │   │   │   ├── ${modName}.controller.ts`);
    lines.push(`│   │   │   │   ├── ${modName}.service.ts`);
    lines.push(`│   │   │   │   ├── ${modName}.module.ts`);
    lines.push(`│   │   │   │   └── dto/`);
  }

  lines.push(`│   │   ├── common/                # 通用（guards, filters, interceptors）`);
  lines.push(`│   │   ├── prisma/                # Prisma ORM`);
  lines.push(`│   │   │   └── schema.prisma`);
  lines.push(`│   │   ├── config/                # 环境配置`);
  lines.push(`│   │   └── main.ts`);
  lines.push(`│   ├── test/`);
  lines.push(`│   ├── Dockerfile`);
  lines.push(`│   └── package.json`);

  // Root-level files
  lines.push(`├── docker-compose.yml`);
  lines.push(`├── .github/workflows/             # CI/CD`);
  lines.push(`│   └── ci.yml`);
  lines.push(`├── .env.example`);
  lines.push(`├── README.md`);
  lines.push(`└── turbo.json                     # Monorepo 配置`);

  return lines;
}

// ═══════════════════════════════════════════════════════
// 8. Main Architecture Pipeline
// ═══════════════════════════════════════════════════════

/**
 * Resolve tech stack from PRD.
 *
 * @param {object} prd
 * @returns {object}
 */
export function resolveTechStack(prd) {
  const platforms = prd.techConstraints?.platforms || ["web"];
  const constraints = prd.techConstraints?.considerations || [];
  const extraFeatures = prd.extraFeatures || [];
  const recommended = prd.techConstraints?.recommendedStack || "";

  // Determine platform key
  let key = "default";
  if (platforms.includes("wechat-miniapp")) key = "wechat-miniapp";
  else if (platforms.includes("miniapp")) key = "miniapp";
  else if (platforms.length === 1 && platforms[0] === "ios") key = "ios-only";
  else if (platforms.length === 1 && platforms[0] === "android") key = "android-only";
  else if (platforms.length === 1 && platforms[0] === "web") key = "web-only";
  else if (platforms.includes("mobile") && platforms.includes("web")) key = "mobile-web";
  else if (platforms.includes("mobile")) key = "mobile";

  const stack = { ...TECH_STACKS[key] };

  // Extra feature adjustments
  if (extraFeatures.includes("wechat-pay") || extraFeatures.includes("alipay")) {
    stack.considerations = stack.considerations || [];
    stack.considerations.push("需集成第三方支付 SDK");
  }
  if (extraFeatures.includes("logistics-tracking")) {
    stack.considerations = stack.considerations || [];
    stack.considerations.push("需集成物流追踪 API（如快递鸟）");
  }
  if (extraFeatures.includes("real-time")) {
    stack.backend += " + WebSocket (Socket.io)";
  }
  if (extraFeatures.includes("ai-powered")) {
    stack.backend += " + AI 服务（OpenAI / 文心）";
  }

  return stack;
}

/**
 * Generate full architecture from PRD.
 *
 * @param {object} prd — PRD from SF-01
 * @returns {object}
 */
export function generateArchitecture(prd) {
  // Validate input
  if (!prd || prd.error) {
    return {
      error: "INVALID_PRD",
      message: prd?.message || "Invalid PRD input",
    };
  }
  if (!prd.projectName || !prd.features) {
    return {
      error: "INCOMPLETE_PRD",
      message: "PRD missing required fields: projectName, features",
    };
  }

  const {
    projectName, domain = "generic", features = [], pages = [],
    apiRequirements = [], techConstraints = {}, extraFeatures = [], meta = {},
  } = prd;

  // 1. Resolve tech stack
  const stack = resolveTechStack(prd);

  // 2. Decompose modules
  const modules = decomposeModules(features, domain);

  // 3. Generate architecture diagram
  const moduleNames = modules.map(m => m.label);
  const archDiagram = generateArchDiagram(projectName, stack, moduleNames);

  // 4. Generate data flows
  const dataFlows = generateDataFlows(pages, apiRequirements);

  // 5. Generate database schema
  const databaseSchema = generateDatabaseSchema(features, apiRequirements, domain);

  // 6. Design API
  const apiDesign = designAPI(apiRequirements);

  // 7. Generate directory structure
  const directoryStructure = generateDirectoryStructure(projectName, domain, modules);

  // 8. Deployment strategy
  const deployment = {
    environments: ["development", "staging", "production"],
    strategy: stack.deployment || "Docker + Nginx",
    services: [
      "API Server (NestJS)",
      "PostgreSQL 15",
      "Redis 7",
      ...(extraFeatures.includes("real-time") ? ["WebSocket Server"] : []),
    ],
    ci: "GitHub Actions → Build → Test → Deploy",
  };

  // Generate contract AFTER schema is built
  const contractArch = { databaseSchema };
  const contract = createContract(prd, contractArch);

  return {
    projectName,
    domain,
    contract,
    techStack: {
      frontend: stack.frontend,
      backend: stack.backend,
      database: stack.database,
      deployment: stack.deployment,
      considerations: stack.considerations || [],
    },
    architectureDiagram: archDiagram,
    dataFlows,
    modules: modules.map(m => ({
      name: m.name,
      label: m.label,
      features: m.features,
      responsibilities: m.features.map(f => `提供 ${f} 相关功能`),
    })),
    databaseSchema,
    apiDesign,
    directoryStructure,
    deployment,
    meta: {
      generatedAt: new Date().toISOString(),
      sourceDomain: domain,
      moduleCount: modules.length,
      tableCount: databaseSchema.length,
      apiEndpointCount: apiRequirements.length,
    },
  };
}

// ═══════════════════════════════════════════════════════
// 9. File I/O
// ═══════════════════════════════════════════════════════

export function loadPRD(path) {
  try {
    if (!existsSync(path)) {
      return { data: null, error: `PRD 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 PRD: ${e.message}` };
  }
}

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

// ═══════════════════════════════════════════════════════
// 10. CLI Entry
// ═══════════════════════════════════════════════════════

function parseArgs() {
  const args = process.argv.slice(2);
  const opts = {
    input: null, inputText: 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-text" && args[i + 1]) opts.inputText = 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(`
Architecture Agent — SF-02

Usage:
  node scripts/architecture-agent.mjs --input <prd.json> [options]
  node scripts/architecture-agent.mjs --input-text "<需求>" [options]

Options:
  --input <path>         PRD JSON 文件路径（SF-01 输出）
  --input-text <text>   直接传入需求（自动调 SF-01 生成 PRD）
  --output <path>        输出架构 JSON 文件路径
  --pretty               Format JSON with indentation
  --verbose              详细输出
  --help                 显示帮助

Examples:
  node scripts/architecture-agent.mjs --input prd-example.json --pretty
  node scripts/architecture-agent.mjs --input-text "做一个电商小程序" --output architecture.json
`);
    return;
  }

  let prd = null;

  if (opts.input) {
    const { data, error } = loadPRD(opts.input);
    if (error) { console.error(error); process.exit(1); }
    prd = data;
  } else if (opts.inputText) {
    // Auto-generate PRD from SF-01
    try {
      const mod = await import("./project-intake-agent.mjs");
      prd = mod.generatePRD(opts.inputText);
      if (prd.error) {
        console.error(`SF-01 PRD generation failed: ${prd.message}`);
        process.exit(1);
      }
    } catch (e) {
      console.error(`Failed to load SF-01 agent: ${e.message}`);
      process.exit(1);
    }
  }

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

  const architecture = generateArchitecture(prd);

  if (architecture.error) {
    console.error(`Architecture generation failed: ${architecture.message}`);
    process.exit(1);
  }

  if (opts.verbose) {
    console.error(`Project: ${architecture.projectName}`);
    console.error(`Domain: ${architecture.domain}`);
    console.error(`Modules: ${architecture.meta.moduleCount}`);
    console.error(`Tables: ${architecture.meta.tableCount}`);
    console.error(`API Endpoints: ${architecture.meta.apiEndpointCount}`);
  }

  if (opts.output) {
    writeArchitecture(architecture, resolve(opts.output), opts.pretty);
    if (opts.verbose) console.error(`Architecture written to: ${opts.output}`);
  }

  printJSON({
    projectName: architecture.projectName,
    domain: architecture.domain,
    techStack: architecture.techStack,
    moduleCount: architecture.meta.moduleCount,
    tableCount: architecture.meta.tableCount,
    apiEndpointCount: architecture.meta.apiEndpointCount,
    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();
}
