import type { AsukaObjectSummary } from './renderEngine';

export type AsukaLayerCategory =
  | 'text'
  | 'image'
  | 'design'
  | 'shape'
  | 'group'
  | 'object';

const normalizeToken = (value: unknown): string =>
  String(value ?? '')
    .trim()
    .toLowerCase()
    .replace(/[\s_]+/g, '-');

const SHAPE_KINDS = new Set([
  'circle',
  'ellipse',
  'line',
  'path',
  'polygon',
  'polyline',
  'rect',
  'rectangle',
  'star',
  'svg',
  'triangle',
]);

const TECHNICAL_KINDS = new Set([
  'active-selection',
  'activeselection',
  'drawing-area',
  'mesh',
  'print-area',
  'product-3d',
  'screen-box',
]);

/**
 * Returns the user-facing layer category for an engine object.
 *
 * The renderer may expose a Fabric type (`rect`, `polygon`, ...), an Asuka
 * module id (`designs`) or restored metadata. Keeping that normalization here
 * prevents individual modules from silently disappearing after an import.
 */
export function getAsukaLayerCategory(
  object: AsukaObjectSummary | null | undefined,
): AsukaLayerCategory | null {
  if (!object) return null;

  const metadata = ((object as any).metadata ?? {}) as Record<string, unknown>;
  const kind = normalizeToken(object.kind || metadata.type || 'object');
  const itemGroup = normalizeToken(metadata.itemGroup);
  const sourceModule = normalizeToken(metadata.sourceModule);
  const role = normalizeToken(metadata.role);
  const shapeKind = normalizeToken(metadata.shapeKind);

  if (!kind || TECHNICAL_KINDS.has(kind)) return null;
  if (['product', 'tools', 'elements'].includes(itemGroup)) return null;
  if (role && role !== 'user' && role !== 'layer') return null;

  if (
    metadata.textLike === true ||
    ['text', 'texts'].includes(sourceModule) ||
    ['text', 'textbox', 'i-text', 'itext'].includes(kind)
  ) {
    return 'text';
  }

  if (
    metadata.designLike === true ||
    ['design', 'designs'].includes(sourceModule) ||
    ['design', 'designs'].includes(kind) ||
    itemGroup === 'designs'
  ) {
    return 'design';
  }

  if (
    metadata.imageLike === true ||
    ['image', 'images', 'upload-image'].includes(sourceModule) ||
    ['image', 'images'].includes(kind) ||
    itemGroup === 'images'
  ) {
    return 'image';
  }

  if (
    shapeKind ||
    ['shape', 'shapes'].includes(sourceModule) ||
    ['shape', 'shapes'].includes(kind) ||
    itemGroup === 'shapes' ||
    SHAPE_KINDS.has(kind)
  ) {
    return 'shape';
  }

  if (kind === 'group') return 'group';

  // Objects reaching the public registry have already passed the renderer's
  // technical-object filter. Keeping unknown user objects visible makes the
  // Layers module forward-compatible with new creative object types.
  return 'object';
}

export function isAsukaLayerObject(
  object: AsukaObjectSummary | null | undefined,
): boolean {
  return getAsukaLayerCategory(object) !== null;
}

export function getAsukaLayerTypeLabel(category: AsukaLayerCategory): string {
  switch (category) {
    case 'text':
      return 'Text';
    case 'image':
      return 'Image';
    case 'design':
      return 'Design';
    case 'shape':
      return 'Shape';
    case 'group':
      return 'Group';
    default:
      return 'Object';
  }
}
