/**
 * Search scope definitions for the command palette.
 * Users type `@prefix:query` to restrict results to a specific domain.
 */

export interface ScopeDefinition {
  /** The prefix users type, e.g. "user" for `@user:` */
  prefix: string;
  /** Human-readable label shown in the scope list */
  label: string;
  /** Command registry groups to include */
  groups: string[];
  /** Entity types to include (from useEntitySearch configs) */
  entityTypes?: string[];
}

export const SCOPE_DEFINITIONS: ScopeDefinition[] = [
  { prefix: 'user', label: 'People & Access', groups: ['People & Access'], entityTypes: ['User', 'Person'] },
  { prefix: 'campaign', label: 'Campaigns', groups: ['Advocacy'], entityTypes: ['Campaign'] },
  { prefix: 'sms', label: 'Broadcast (SMS)', groups: ['Broadcast'] },
  { prefix: 'settings', label: 'Settings', groups: ['Settings'] },
  { prefix: 'media', label: 'Media', groups: ['Media'] },
  { prefix: 'map', label: 'Map & Locations', groups: ['Map'], entityTypes: ['Location', 'Shift'] },
  { prefix: 'web', label: 'Web & Docs', groups: ['Web'], entityTypes: ['Landing Page', 'Email Template', 'Doc File'] },
  { prefix: 'service', label: 'Services', groups: ['Services'] },
  { prefix: 'payment', label: 'Payments', groups: ['Payments'], entityTypes: ['Product', 'Donation Page', 'Plan'] },
  { prefix: 'social', label: 'Social', groups: ['Social'] },
];

const SCOPE_MAP = new Map(SCOPE_DEFINITIONS.map((s) => [s.prefix, s]));

export interface ParsedQuery {
  /** The active scope, or null if no valid scope prefix */
  scope: ScopeDefinition | null;
  /** The query string with scope prefix stripped */
  strippedQuery: string;
  /** Whether the user typed a bare `@` (show scope list) */
  showScopeList: boolean;
}

/**
 * Parse a raw query string for scope prefixes.
 *
 * - `@user:john`  → scope=user, strippedQuery="john"
 * - `@user:`      → scope=user, strippedQuery=""
 * - `@`           → showScopeList=true
 * - `@foo:bar`    → invalid prefix, treated as normal search
 * - `hello`       → no scope, strippedQuery="hello"
 */
export function parseQuery(raw: string): ParsedQuery {
  const trimmed = raw.trim();

  // Bare `@` — show scope selector
  if (trimmed === '@') {
    return { scope: null, strippedQuery: '', showScopeList: true };
  }

  // Match `@prefix:rest`
  const match = trimmed.match(/^@(\w+):(.*)$/);
  if (match) {
    const scope = SCOPE_MAP.get(match[1]!.toLowerCase()) ?? null;
    if (scope) {
      return { scope, strippedQuery: match[2]!.trimStart(), showScopeList: false };
    }
    // Invalid prefix — fall through to normal search
  }

  return { scope: null, strippedQuery: trimmed, showScopeList: false };
}
