const path = require('node:path');

// Source template — bundled inside the package at cli/templates/firebase/
const CORE_SOURCE_DIR = path.resolve(__dirname, '../../templates/firebase');

// Patches por backend: cli/lib/scaffold/backends/{backend}/patch/
const BACKENDS_PATCH_DIR = path.resolve(__dirname, 'backends');

// Patches por feature: cli/lib/scaffold/features/{feature}/
const FEATURES_PATCH_DIR = path.resolve(__dirname, 'features');

const AVAILABLE_BACKENDS = [
  { id: 'firebase', aliases: ['firebase'] },
  { id: 'supabase', aliases: ['supabase'] },
  { id: 'api', aliases: ['api', 'restapi', 'rest_api', 'restApi'] }
];

/**
 * Feature catalog — single source of truth for all selectable modules.
 *
 * status:
 *   public   — visible to all users in the CLI wizard and presets
 *   internal — visible only when KASY_INTERNAL=1; shown with [beta] badge
 *   hidden   — never shown in the CLI (can still be passed via --with)
 *
 * availableIn: backends that support this feature
 * defaultInPresets: which named presets include this feature by default
 * displayName:    user-facing label shown in CLI listings (Title Case, English)
 * tag:            optional restriction tag — `firebaseOnly` or `requiresDb` —
 *                 rendered as a colored badge in CLI listings
 * enhances:       id of a base feature this optional feature activates real
 *                 functionality for. Example: `revenuecat` enhances
 *                 `subscription` — the Subscriptions screen exists in the base
 *                 project but only sells real plans once RevenueCat is added.
 *
 * Note on id vs folder name (intentional, not a bug):
 *   - id `local_notifications` → folder `lib/features/local_reminder/`
 *   - id `feedback`            → folder `lib/features/feedbacks/`
 *   The id describes the user-facing capability; the folder describes the
 *   Dart component. The generator (see generator-utils.js writeRouter and
 *   the cleanup step around feature dirs) removes these folders when the
 *   feature is not selected.
 */
const FEATURE_CATALOG = [
  // integrations
  { id: 'sentry',              displayName: 'Crash Reports (Sentry)', status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['starter', 'saas', 'content', 'full'] },
  { id: 'analytics',           displayName: 'Analytics',              status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['starter', 'saas', 'content', 'full'] },
  { id: 'facebook',            displayName: 'Facebook (Login + Ads)', status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['full'] },
  // monetization
  { id: 'revenuecat',          displayName: 'RevenueCat',             status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['saas', 'full'], enhances: 'subscription' },
  // features
  { id: 'onboarding',          displayName: 'Onboarding',             status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['starter', 'saas', 'content', 'full'] },
  { id: 'web',                 displayName: 'Web Support (PWA)',      status: 'public',   availableIn: ['firebase'],                    defaultInPresets: [], tag: 'firebaseOnly' },
  { id: 'widget',              displayName: 'Home Widget',            status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['full'] },
  { id: 'llm_chat',            displayName: 'AI Chat',                status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['content', 'full'] },
  { id: 'local_notifications', displayName: 'Local Reminders',        status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: [] },
  // feedback (Firebase/Supabase only)
  { id: 'feedback',            displayName: 'Feature Requests',       status: 'public',   availableIn: ['firebase', 'supabase'],        defaultInPresets: ['saas', 'full'], tag: 'requiresDb' },
  // ci/cd
  { id: 'ci',                  displayName: 'CI/CD',                  status: 'public',   availableIn: ['firebase', 'supabase', 'api'], defaultInPresets: ['full'] },
];

/**
 * Base features — always present in every generated project.
 * These cannot be added or removed via `kasy add` / `kasy remove`.
 * Listed in the CLI so users understand what ships with every project.
 */
const BASE_FEATURES = [
  { id: 'authentication', displayName: 'Auth' },
  { id: 'home',           displayName: 'Home Screen' },
  { id: 'settings',       displayName: 'Settings Screen' },
  { id: 'notifications',  displayName: 'Push Notifications' },
  { id: 'subscription',   displayName: 'Subscriptions' },
];

function getBaseFeatures() {
  return BASE_FEATURES;
}

/**
 * Returns features visible to the given audience, optionally filtered by backend.
 *
 * @param {object} opts
 * @param {'public'|'internal'} opts.audience - 'internal' reveals beta features
 * @param {string|null} opts.backend - filter by backend id, or null for all
 */
function getVisibleFeatures({ audience = 'public', backend = null } = {}) {
  return FEATURE_CATALOG.filter((f) => {
    if (f.status === 'hidden') return false;
    if (f.status === 'internal' && audience !== 'internal') return false;
    if (backend && !f.availableIn.includes(backend)) return false;
    return true;
  });
}

// Flat list kept for backward-compatibility with code that uses feature ids as strings.
const AVAILABLE_FEATURES = FEATURE_CATALOG.map((f) => f.id);

const DEFAULT_FEATURES = [...AVAILABLE_FEATURES];

/**
 * Base component files that can be updated independently from optional features.
 * Paths are relative to CORE_SOURCE_DIR.
 *
 * Includes `lib/core/...` only when kit components depend on those APIs (tokens,
 * shared widgets); keep this list in sync with `Firebase/lib/components/` and
 * the home component catalog.
 */
const CORE_FILES = [
  // Dev tools
  'lib/core/web_device_preview/web_device_preview.dart',
  'lib/core/dev_inspector/dev_inspector.dart',
  'lib/core/dev_inspector/dev_inspector_highlight.dart',
  'lib/core/dev_inspector/dev_inspector_info.dart',
  'lib/core/dev_inspector/dev_inspector_panel.dart',
  'lib/core/dev_inspector/dev_inspector_service.dart',
  'lib/core/keyboard_fix/keyboard_flicker_fix.dart',
  // Animations
  'lib/core/animations/bottomfade_anim.dart',
  'lib/core/animations/movefade_anim.dart',
  'lib/core/animations/slideright_anim.dart',
  // Core widgets (pure utilities, never user-modified)
  'lib/core/widgets/debouncer.dart',
  'lib/core/widgets/kasy_hover.dart',
  'lib/core/widgets/kasy_pressable.dart',
  'lib/core/widgets/kasy_scroll_behavior.dart',
  'lib/core/widgets/keyboard_visibility.dart',
  'lib/core/widgets/page_background.dart',
  'lib/core/widgets/page_not_found.dart',
  'lib/core/widgets/responsive_layout.dart',
  'lib/core/widgets/update_bottom_sheet.dart',
  // Page transitions (pure utilities)
  'lib/core/navigation/kasy_fade_page_transitions_builder.dart',
  'lib/core/navigation/kasy_material_page_route.dart',
  'lib/core/navigation/kasy_page_transition.dart',
  'lib/core/navigation/kasy_route_transition.dart',
  'lib/core/navigation/kasy_transition_kind.dart',
  // Utilities
  'lib/core/toast/toast_service.dart',
  'lib/core/ui/app_dialog.dart',
  'lib/core/icons/kasy_icons.dart',
  'lib/core/haptics/kasy_haptics.dart',
  'lib/core/haptics/haptic_feedback_notifier.dart',
  // Theme (colors.dart and shadows.dart are in BASE_COMPONENT_FILES)
  'lib/core/theme/spacing.dart',
  'lib/core/theme/texts.dart',
  'lib/core/theme/radius.dart',
  'lib/core/theme/theme.dart',
  'lib/core/theme/theme_data/theme_data.dart',
  'lib/core/theme/theme_data/theme_data_factory.dart',
  'lib/core/theme/extensions/theme_extension.dart',
  'lib/core/theme/providers/kasy_theme.dart',
  'lib/core/theme/providers/theme_provider.dart',
  'lib/core/theme/universal_theme.dart',
];

const BASE_COMPONENT_FILES = [
  'lib/core/theme/colors.dart',
  'lib/core/theme/shadows.dart',
  'lib/core/widgets/kasy_pressable_depth.dart',
  'lib/components/components.dart',
  'lib/components/kasy_accordion.dart',
  'lib/components/kasy_alert.dart',
  'lib/components/kasy_app_bar.dart',
  'lib/components/kasy_avatar.dart',
  'lib/components/kasy_button.dart',
  'lib/components/kasy_card.dart',
  'lib/components/kasy_chip.dart',
  'lib/components/kasy_input.dart',
  'lib/components/kasy_text_field.dart',
  'lib/features/home/home_components_page.dart',
  'lib/features/home/home_components_preview_page.dart',
  'lib/features/home/home_components_preview_registry.dart',
];

function normalizeBackend(value) {
  if (!value) {
    return null;
  }

  const raw = String(value).trim();
  if (!raw) {
    return null;
  }

  const lowered = raw.toLowerCase().replace(/[-\s]/g, '');

  const found = AVAILABLE_BACKENDS.find((backend) =>
    backend.aliases.some((alias) => alias.toLowerCase().replace(/[-\s]/g, '') === lowered)
  );

  return found ? found.id : null;
}

function normalizeFeature(value) {
  if (!value) {
    return null;
  }

  const lowered = String(value).trim().toLowerCase().replace(/[-\s]/g, '_');
  if (!lowered) {
    return null;
  }

  const aliases = {
    llm: 'llm_chat',
    llmchat: 'llm_chat',
    llm_chat: 'llm_chat',
    rc: 'revenuecat',
    revenue: 'revenuecat',
    onboard: 'onboarding',
    fb: 'facebook',
  };

  if (aliases[lowered]) {
    return aliases[lowered];
  }

  return AVAILABLE_FEATURES.includes(lowered) ? lowered : null;
}

function parseFeatureList(value) {
  if (!value) {
    return [];
  }

  const rawItems = Array.isArray(value) ? value : [value];
  const tokens = rawItems
    .flatMap((item) => String(item).split(','))
    .map((item) => item.trim())
    .filter(Boolean);

  const normalized = [];
  for (const token of tokens) {
    const feature = normalizeFeature(token);
    if (feature && !normalized.includes(feature)) {
      normalized.push(feature);
    }
  }

  return normalized;
}

module.exports = {
  CORE_SOURCE_DIR,
  BACKENDS_PATCH_DIR,
  FEATURES_PATCH_DIR,
  AVAILABLE_BACKENDS,
  FEATURE_CATALOG,
  BASE_FEATURES,
  AVAILABLE_FEATURES,
  DEFAULT_FEATURES,
  BASE_COMPONENT_FILES,
  CORE_FILES,
  normalizeBackend,
  normalizeFeature,
  parseFeatureList,
  getVisibleFeatures,
  getBaseFeatures,
};
