/**
 * packages/extract/src/token-source/categorize.ts — shared category + color helpers.
 * Exports: inferCategory, isColorValue, normalizeColorValue.
 * Used by parse.ts, detect-hardcoded.ts, and index.ts.
 */

const CATEGORY_PATTERNS: Array<{ pattern: RegExp; category: string }> = [
  {
    pattern: /color|bg|background|border-color|fill|stroke/i,
    category: 'color',
  },
  { pattern: /spacing|margin|padding|gap|space|inset/i, category: 'spacing' },
  {
    pattern: /font|text|line-height|letter-spacing|typography/i,
    category: 'typography',
  },
  { pattern: /radius|rounded|corner/i, category: 'radius' },
  { pattern: /shadow|elevation/i, category: 'shadow' },
  { pattern: /size|width|height|min|max/i, category: 'sizing' },
  { pattern: /border(?!-color)|stroke-width|outline/i, category: 'border' },
  {
    pattern: /animation|transition|duration|timing|delay/i,
    category: 'animation',
  },
  { pattern: /z-index|layer|stack/i, category: 'z-index' },
];

const COLOR_VALUE_RE = /^(?:oklch|hsl[a]?|rgb[a]?|lch|lab|color)\s*\(/i;

const NON_COLOR_CATEGORIES = new Set([
  'spacing',
  'typography',
  'radius',
  'shadow',
  'sizing',
  'border',
  'animation',
  'z-index',
]);

export function isColorValue(value: string): boolean {
  if (value.startsWith('#')) return true;
  if (COLOR_VALUE_RE.test(value)) return true;
  return false;
}

export function inferCategory(name: string, value?: string) {
  for (const { pattern, category } of CATEGORY_PATTERNS) {
    if (pattern.test(name)) {
      if (NON_COLOR_CATEGORIES.has(category) && value && isColorValue(value)) {
        return 'color';
      }
      return category;
    }
  }
  if (value && isColorValue(value)) return 'color';
  return 'other';
}

export function normalizeColorValue(value: string) {
  const trimmed = value.trim();
  const hex3 = trimmed.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i);
  if (hex3) {
    return `#${hex3[1]}${hex3[1]}${hex3[2]}${hex3[2]}${hex3[3]}${hex3[3]}`.toLowerCase();
  }
  const fnMatch = trimmed.match(
    /^(oklch|hsl[a]?|rgb[a]?|lch|lab|color)\s*\(\s*(.+?)\s*\)$/i,
  );
  if (fnMatch) {
    const fn = fnMatch[1].toLowerCase();
    const args = fnMatch[2]
      .replace(/\s*,\s*/g, ' ')
      .replace(/\s+/g, ' ')
      .trim();
    return `${fn}(${args})`;
  }
  return trimmed.toLowerCase();
}
