/**
 * PR-37 Part D — Industry Feature Generator
 *
 * Generates domain-specific Feature objects for each epic, using the
 * domain registry's `coreFeatures` as a template. Falls back to generic
 * feature generation for unknown domains or epics without registered features.
 *
 * @module pr-37-domain-intelligence/industry-feature-generator
 * @since PR-37
 */

import { getDomain } from "./domain-registry.mjs";

// ══════════════════════════════════════════════════════════
// Internal: ID counter
// ══════════════════════════════════════════════════════════

let _featureCounter = 0;

/**
 * Reset the internal feature ID counter (useful in tests).
 */
export function resetFeatureCounter() {
  _featureCounter = 0;
}

/**
 * Generate the next sequential feature ID.
 *
 * @returns {string} ID like "ft-001"
 */
function nextFeatureId() {
  _featureCounter++;
  return `ft-${String(_featureCounter).padStart(3, "0")}`;
}

// ══════════════════════════════════════════════════════════
// Feature type auto-detection
// ══════════════════════════════════════════════════════════

/**
 * Feature type constants.
 *
 * @readonly
 * @enum {string}
 */
export const FEATURE_TYPE = Object.freeze({
  CRUD: "CRUD",
  WORKFLOW: "workflow",
  ANALYTICS: "analytics",
  CONFIGURATION: "configuration",
  INTEGRATION: "integration",
  SEARCH: "search",
  NOTIFICATION: "notification",
});

/**
 * Keywords that hint at each feature type.
 *
 * @type {object<string, RegExp[]>}
 */
const TYPE_PATTERNS = Object.freeze({
  [FEATURE_TYPE.ANALYTICS]: [/分析/i, /报表/i, /看板/i, /统计/i, /趋势/i, /洞察/i, /仪表盘/i, /report/i, /dashboard/i, /analysis/i],
  [FEATURE_TYPE.CONFIGURATION]: [/配置/i, /参数/i, /设置/i, /规则/i, /策略/i, /模板/i, /setting/i, /config/i],
  [FEATURE_TYPE.INTEGRATION]: [/集成/i, /接口/i, /对接/i, /同步/i, /API/i, /导入/i, /导出/i, /import/i, /export/i, /webhook/i],
  [FEATURE_TYPE.SEARCH]: [/搜索/i, /检索/i, /查询/i, /查找/i, /search/i, /query/i],
  [FEATURE_TYPE.NOTIFICATION]: [/通知/i, /消息/i, /告警/i, /提醒/i, /预警/i, /notification/i, /alert/i, /remind/i],
  [FEATURE_TYPE.WORKFLOW]: [/流程/i, /审批/i, /审核/i, /流转/i, /工单/i, /workflow/i, /approval/i, /process/i],
  [FEATURE_TYPE.CRUD]: [/管理/i, /维护/i, /档案/i, /台账/i, /登记/i, /录入/i, /编辑/i, /创建/i],
});

/**
 * Auto-detect the feature type based on the feature title/description.
 *
 * @param {string} title - Feature title
 * @param {string} [description=""] - Feature description
 * @returns {string} Detected feature type
 */
export function detectFeatureType(title, description = "") {
  const text = `${title} ${description}`;

  // Check patterns in priority order (CRUD last as fallback)
  const ordered = [
    FEATURE_TYPE.ANALYTICS,
    FEATURE_TYPE.CONFIGURATION,
    FEATURE_TYPE.INTEGRATION,
    FEATURE_TYPE.SEARCH,
    FEATURE_TYPE.NOTIFICATION,
    FEATURE_TYPE.WORKFLOW,
    FEATURE_TYPE.CRUD,
  ];

  for (const type of ordered) {
    const patterns = TYPE_PATTERNS[type];
    for (const pattern of patterns) {
      if (pattern.test(text)) return type;
    }
  }

  // Default
  return FEATURE_TYPE.CRUD;
}

// ══════════════════════════════════════════════════════════
// Public API
// ══════════════════════════════════════════════════════════

/**
 * Generate features for a set of epics within a given domain.
 *
 * @param {string} domainName - Target domain (e.g., "ERP", "MES", "CRM")
 * @param {object[]} epics - Array of epic objects (each must have at least `title`)
 * @returns {object[]} Array of feature objects, each with:
 *   - id (string): "ft-xxx"
 *   - title (string): Feature title
 *   - description (string): Feature description
 *   - epicId (string): ID of the parent epic
 *   - featureType (string): Auto-detected feature type
 *
 * @example
 * const epics = generateIndustryEpics("WMS", "智能仓储");
 * const features = generateIndustryFeatures("WMS", epics);
 * // => [ { id: "ft-001", title: "ASN收货", description: "...", epicId: "ep-001", featureType: "workflow" }, ... ]
 */
export function generateIndustryFeatures(domainName, epics) {
  if (!domainName || !epics || !Array.isArray(epics) || epics.length === 0) {
    return [];
  }

  const domain = getDomain(domainName);
  const domainFeatures = domain?.coreFeatures || {};
  const allFeatures = [];

  for (const epic of epics) {
    const { id: epicId, title: epicTitle } = epic;

    // Look up domain-specific features for this epic title
    const featureNames = domainFeatures[epicTitle];

    if (featureNames && Array.isArray(featureNames) && featureNames.length > 0) {
      // Domain-specific features
      for (const name of featureNames) {
        allFeatures.push({
          id: nextFeatureId(),
          title: name,
          description: buildFeatureDescription(name, epicTitle, domain),
          epicId,
          featureType: detectFeatureType(name, epicTitle),
        });
      }
    } else {
      // Fallback: generate generic features for this epic
      const generic = generateGenericFeaturesForEpic(epicTitle, epicId, domain);
      allFeatures.push(...generic);
    }
  }

  return allFeatures;
}

// ══════════════════════════════════════════════════════════
// Internal helpers
// ══════════════════════════════════════════════════════════

/**
 * Build a meaningful description for a domain-specific feature.
 *
 * @param {string} featureName - Feature name
 * @param {string} epicTitle - Parent epic title
 * @param {object|null} domain - Domain definition (may be null)
 * @returns {string}
 */
function buildFeatureDescription(featureName, epicTitle, domain) {
  const domainLabel = domain
    ? `${domain.displayName} (${domain.name})`
    : "系统";
  return `${domainLabel} — ${epicTitle} 模块下的「${featureName}」功能，支持相关业务操作与数据管理。`;
}

/**
 * Generate generic features for an epic when no domain-specific features exist.
 *
 * @param {string} epicTitle - Epic title
 * @param {string} epicId - Epic ID
 * @param {object|null} domain - Domain definition (may be null)
 * @returns {object[]}
 */
function generateGenericFeaturesForEpic(epicTitle, epicId, domain) {
  const domainLabel = domain
    ? `${domain.displayName} (${domain.name})`
    : "系统";

  // Build generic CRUD + basic features
  const genericNames = detectGenericFeatures(epicTitle);

  return genericNames.map((name) => {
    const type = detectFeatureType(name, epicTitle);
    return {
      id: nextFeatureId(),
      title: name,
      description: `${domainLabel} — ${epicTitle} 模块提供「${name}」功能，支持相关业务数据的维护与管理。`,
      epicId,
      featureType: type,
    };
  });
}

/**
 * Detect sensible generic feature names for an epic based on its title.
 *
 * @param {string} epicTitle - Epic title
 * @returns {string[]}
 */
function detectGenericFeatures(epicTitle) {
  const titleLower = epicTitle.toLowerCase();

  const featureMap = {
    // Match based on common patterns
    default: [
      `${epicTitle}数据维护`,
      `${epicTitle}配置管理`,
      `${epicTitle}报表`,
    ],
  };

  // Add analytics for most epics
  const hasAnalytics = /分析|报表|统计|看板|dashboard|report/i.test(titleLower);
  if (hasAnalytics) {
    return [
      `${epicTitle}配置`,
      `${epicTitle}监控`,
      `${epicTitle}趋势分析`,
      `${epicTitle}导出`,
    ];
  }

  return featureMap.default;
}

/**
 * Add domain-specific features for an epic by keyword matching.
 * This is a fallback enrichment when coreFeatures doesn't have a direct entry
 * but the epic title matches domain terminology.
 *
 * @param {string} title - Epic title
 * @param {object} domain - Domain definition
 * @returns {string[]|null} Matched feature names or null
 */
export function matchDomainFeaturesByKeyword(title, domain) {
  if (!domain || !domain.coreFeatures) return null;

  // Try partial title matching against registered epic titles
  const matchedEpicKey = Object.keys(domain.coreFeatures).find((key) =>
    title.toLowerCase().includes(key.toLowerCase()) ||
    key.toLowerCase().includes(title.toLowerCase())
  );

  if (matchedEpicKey) {
    return domain.coreFeatures[matchedEpicKey];
  }

  return null;
}
