/**
 * actionLexicon — R6UXS-007
 *
 * Single source of truth for action vocabulary and CTA labels across all
 * analytical surfaces. Eliminates ad-hoc strings and synonym drift.
 *
 * Usage:
 *   import { ACTION_LABELS, FEATURE_NAMES } from '@/lib/actionLexicon';
 *   <Button>{ACTION_LABELS.bulkRewrite}</Button>
 */

// ── Per-action CTA labels ─────────────────────────────────────────────────────

export const ACTION_LABELS = {
  /** Open the ScopeCostModal to dispatch a bulk AI rewrite batch. */
  bulkRewrite: 'Rewrite with AI',
  /** Open ScopeCostModal seeded with a single item (per-row rewrite). */
  rewriteSingle: 'Rewrite with AI',
  /** Navigate to or open the Content Briefs flow (brief creation). */
  createBrief: 'Create brief',
  /** Navigate to Content Briefs with a single item pre-filled. */
  briefSingle: 'Create brief',
  /** Multi-item variant shown in bulk action bars. */
  createBriefs: 'Create briefs',
  /** @deprecated PD-001: use bulkRewrite for the CI bulk-bar primary entry CTA.
   *  sendToRecovery is retained for Recovery Run confirmation copy (modal confirmLabel)
   *  and any non-entry usage that refers specifically to the Recovery Run journey noun. */
  sendToRecovery: 'Send to Recovery Run',
  /** View an existing draft. */
  viewDraft: 'View draft',
  /** Generate a single AI draft (direct, non-batch). */
  generateDraft: 'Generate draft',
  /** Navigate to the Briefs index (no single-item keyword pre-fill). Semantically
   *  distinct from createBriefs (multi-item batch creation) — use only for
   *  plain navigation CTAs; use createBriefs for batch-creation bulk actions. */
  goToBriefs: 'Open Briefs',
} as const;

export type ActionLabel = (typeof ACTION_LABELS)[keyof typeof ACTION_LABELS];

// ── Feature / page names ──────────────────────────────────────────────────────

export const FEATURE_NAMES = {
  contentInventory: 'Content Inventory',
  freshness: 'Freshness Watchlist',
  cannibalization: 'Cannibalization',
  topicClusters: 'Topic Clusters',
  contentBriefs: 'Content Briefs',
  opportunitiesHub: 'Opportunities',
  recommendations: 'Recommendations',
  recoveryRun: 'Recovery Run',
} as const;

export type FeatureName = (typeof FEATURE_NAMES)[keyof typeof FEATURE_NAMES];

// ── Run / queue noun registry — R8UX-011 ─────────────────────────────────────
//
// Canonical noun-per-concept table so "Recovery Run" resolves to exactly one
// thing across all surfaces. Grep for RUN_NOUNS usages to find every consumer.
//
// CANONICAL GLOSSARY (from INDEX.txt):
//   Recovery Run       = the manual dispatch → review → publish journey
//   Recovery Runs page = batch-ai.index (H1; its rows ARE manual recovery runs)
//   Autopilot History  = sites.recovery-runs.index (AutopilotRun rows only)

export const RUN_NOUNS = {
  /** The manual batch journey: hero label, modal titles, CTA summaries. */
  manualRun: 'Recovery Run',
  /** H1 for batch-ai.index — its rows are manual recovery runs. */
  manualRunPage: 'Recovery Runs',
  /** H1 / nav label for sites.recovery-runs.index — AutopilotRun rows only. */
  autopilotPage: 'Autopilot History',
  /** Link copy on RecoveryRunHero pointing to batch-ai.index run history. */
  heroHistoryLink: 'View past runs',
} as const;

export type RunNoun = (typeof RUN_NOUNS)[keyof typeof RUN_NOUNS];

// ── Modal titles / descriptions per surface ──────────────────────────────────

export const MODAL_COPY = {
  contentInventory: {
    title: 'Start a Recovery Run',
    /** R11UX-101: co-located with title so paid-commit button verb cannot drift. */
    confirmLabel: 'Start a Recovery Run',
    description: (count: number, plural: string) =>
      `Send ${count} page${plural} to a Recovery Run for AI rewrite.`,
  },
  freshness: {
    title: 'Rewrite stale pages',
    /** R11UX-101: co-located with title so paid-commit button verb cannot drift. */
    confirmLabel: 'Rewrite stale pages',
    /** plural is '' or 's' — matches ScopeCostModal's description callback signature. */
    description: (count: number, plural: string) =>
      `Generate AI rewrites for ${count} stale page${plural} in the Freshness Watchlist.`,
  },
  cannibalization: {
    title: 'Rewrite cannibalizing pages',
    /** R11UX-101: co-located with title so paid-commit button verb cannot drift. */
    confirmLabel: 'Rewrite cannibalizing pages',
    description: (count: number, plural: string) =>
      `Generate AI rewrites for ${count} cannibalizing page${plural}.`,
  },
  topicClusters: {
    title: 'Rewrite hub pages',
    /** R11UX-101: co-located with title so paid-commit button verb cannot drift. */
    confirmLabel: 'Rewrite hub pages',
    description: (count: number, plural: string) =>
      `Generate AI rewrites for ${count} cluster hub page${plural}.`,
  },
  recommendations: {
    title: 'Rewrite selected pages',
    /** R11UX-101: co-located with title so paid-commit button verb cannot drift. */
    confirmLabel: 'Rewrite selected pages',
    /** Preserves the "sorted by click loss" nuance from Recommendations/Index. */
    description: (count: number, plural: string) =>
      `Generate AI rewrite drafts for ${count} recommendation${plural} — sorted by click loss.`,
  },
} as const;

// ── Shared utility ────────────────────────────────────────────────────────────

/**
 * Derive the best keyword for pre-seeding a Content Brief from structured
 * evidence. Prefers the first lost_query from evidence.refresh_targets over
 * the post title — the lost query is a concrete SEO signal the persona should
 * recover, not just the page's marketing title.
 *
 * R6UXS-009: thread top-lost-query into brief seeds.
 */
export function deriveBriefKeyword(
  evidence: Record<string, unknown> | null | undefined,
  fallbackTitle: string,
): string {
  if (evidence) {
    const targets = evidence['refresh_targets'];
    if (Array.isArray(targets)) {
      for (const target of targets) {
        if (
          target &&
          typeof target === 'object' &&
          (target as Record<string, unknown>)['type'] === 'lost_query' &&
          typeof (target as Record<string, unknown>)['query'] === 'string' &&
          ((target as Record<string, unknown>)['query'] as string).trim() !== ''
        ) {
          return (target as Record<string, unknown>)['query'] as string;
        }
      }
    }
  }
  return fallbackTitle;
}
