import * as React from 'react';

type $MergeBy<T, K> = Omit<T, keyof K> & K;

type $PreservedValue<Value, Fallback> = [Value] extends [never] ? Fallback : Value;

/**
 * This interface can be augmented by users to add types to `i18next` default TypeOptions.
 *
 * Usage:
 * ```ts
 * // i18next.d.ts
 * import 'i18next';
 * declare module 'i18next' {
 *   interface CustomTypeOptions {
 *     defaultNS: 'custom';
 *     returnNull: false;
 *     returnObjects: false;
 *     nsSeparator: ':';
 *     keySeparator: '.';
 *     compatibilityJSON: 'v4';
 *     allowObjectInHTMLChildren: false;
 *     resources: {
 *       custom: {
 *         foo: 'foo';
 *       };
 *     };
 *   }
 * }
 * ```
 */
interface CustomTypeOptions {}

type TypeOptions = $MergeBy<
  {
    /** @see {InitOptions.returnNull} */
    returnNull: false;

    /** @see {InitOptions.returnEmptyString} */
    returnEmptyString: true;

    /** @see {InitOptions.returnObjects} */
    returnObjects: false;

    /** @see {InitOptions.keySeparator} */
    keySeparator: '.';

    /** @see {InitOptions.nsSeparator} */
    nsSeparator: ':';

    /** @see {InitOptions.pluralSeparator} */
    pluralSeparator: '_';

    /** @see {InitOptions.contextSeparator} */
    contextSeparator: '_';

    /** @see {InitOptions.defaultNS} */
    defaultNS: 'translation';

    /** @see {InitOptions.fallbackNS} */
    fallbackNS: false;

    /** @see {InitOptions.compatibilityJSON} */
    compatibilityJSON: 'v4';

    /** @see {InitOptions.resources} */
    resources: object;

    /**
     * Flag that allows HTML elements to receive objects. This is only useful for React applications
     * where you pass objects to HTML elements so they can be replaced to their respective interpolation
     * values (mostly with Trans component)
     */
    allowObjectInHTMLChildren: false;

    /**
     * Flag that enables strict key checking even if a `defaultValue` has been provided.
     * This ensures all calls of `t` function don't accidentally use implicitly missing keys.
     */
    strictKeyChecks: false;

    /**
     * Prefix for interpolation
     */
    interpolationPrefix: '{{';

    /**
     * Suffix for interpolation
     */
    interpolationSuffix: '}}';

    /** @see {InterpolationOptions.unescapePrefix} */
    unescapePrefix: '-';

    /** @see {InterpolationOptions.unescapeSuffix} */
    unescapeSuffix: '';

    /**
     * Use a proxy-based selector to select a translation.
     *
     * Enables features like go-to definition, and better DX/faster autocompletion
     * for TypeScript developers.
     *
     * If you're working with an especially large set of translations and aren't
     * using context, you set `enableSelector` to `"optimize"` and i18next won't do
     * any type-level processing of your translations at all.
     *
     * With `enableSelector` set to `"optimize"`, i18next is capable of supporting
     * arbitrarily large/deep translation sets without causing any IDE slowdown
     * whatsoever.
     *
     * @default false
     */
    enableSelector: false;
  },
  CustomTypeOptions
>;

type FlatNamespace = $PreservedValue<keyof TypeOptions['resources'], string>;
type Namespace<T = FlatNamespace> = T | readonly T[];

interface ReportNamespaces {
  addUsedNamespaces(namespaces: Namespace): void;
  getUsedNamespaces(): string[];
}

declare module 'i18next' {
  // interface i18n {
  //   reportNamespaces?: ReportNamespaces;
  // }
  interface CustomInstanceExtensions {
    reportNamespaces?: ReportNamespaces;
  }
}

type ObjectOrNever = TypeOptions['allowObjectInHTMLChildren'] extends true
  ? Record<string, unknown>
  : never;

type ReactI18NextChildren = React.ReactNode | ObjectOrNever;

declare module 'react' {
  namespace JSX {
    interface IntrinsicAttributes {
      i18nIsDynamicList?: boolean;
    }
  }

  interface HTMLAttributes<T> {
    // This union is inspired by the typings for React.ReactNode. We do this to fix "This JSX tag's 'children' prop
    // expects a single child of type 'ReactI18NextChildren', but multiple children were provided":
    // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5a1e9f91ed0143adede394adb3f540e650455f71/types/react/index.d.ts#L268
    children?: ReactI18NextChildren | Iterable<ReactI18NextChildren>;
  }
}

// packages/core/types/src/layout/layoutTypes.ts



/**
 * App metadata and branding configuration
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AppMetadata {
  /** Application name */
  name?: string;

  /** Short application name for mobile/compact displays (defaults to name if not set) */
  shortName?: string;

  /** Application description */
  description?: string;

  /** Social and external links */
  links?: {
    /** GitHub repository URL */
    github?: string;
    /** Twitter/X profile URL */
    twitter?: string;
    /** LinkedIn profile URL */
    linkedin?: string;
    /** Support/contact URL */
    support?: string;
    /** Documentation URL */
    docs?: string;
    /** Blog URL */
    blog?: string;
  };

  /** Footer configuration
   * - `null`: Explicitly hide footer
   * - `undefined`: Use framework default footer
   * - `{ copyright?: ..., legalLinks?: ... }`: Custom footer configuration
   */
  footer?: {
    /** Copyright configuration
     * - `null`: Hide copyright
     * - `undefined`: Use default (© YEAR appName. All rights reserved)
     * - `string`: Custom copyright text
     */
    copyright?: null | string;
    /** Legal links configuration
     * - `null`: Hide legal links
     * - `Array<{ path, label }>`: Custom legal links (labels can be i18n keys via maybeTranslate)
     * - `undefined`: Use framework defaults (Privacy Policy, Terms of Service with i18n labels)
     */
    legalLinks?: null | Array<{
      path: string;
      label: string;
    }>;
  } | null;

  /** Additional application metadata */
  metadata?: Record<string, any>;
}

/**
 * Authentication route configuration
 *
 * Configure redirect routes for authentication and authorization failures.
 * Also configures AuthHeader UI behavior (login page, user menu, etc.).
 * All routes are optional with security-first defaults.
 *
 * @example
 * ```typescript
 * const authConfig: AuthConfig = {
 *   authRoute: '/signin',
 *   roleRoute: '/403',
 *   tierRoute: '/pricing',
 *   loginPath: '/login',  // Optional: links to login page (undefined = show providers in header)
 *   profilePath: '/account',
 *   authMenuPaths: ['/dashboard', '/settings']
 * };
 * ```
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthConfig {
  /** Route to redirect when authentication required (default: '/login') */
  authRoute: string;
  /** Route to redirect when role insufficient (default: '/404') */
  roleRoute: string;
  /** Route to redirect when tier insufficient (default: '/404') */
  tierRoute: string;
  /** Optional: Path to login page. If provided, AuthHeader links to login page. If undefined (default), shows providers in header */
  loginPath?: string;
  /** Optional: Path to profile page (default: '/profile') */
  profilePath?: string;
  /**
   * Optional: Custom menu items for authenticated user menu dropdown.
   * Supports route-based items with paths (auto-creates Link).
   * Icons are auto-resolved from route discovery (PageMeta.icon) if not provided.
   * For items with onClick handlers, use AuthMenu customItems prop instead.
   *
   * @example
   * ```typescript
   * authMenuItems: [
   *   { path: '/dashboard' }, // icon auto-resolved from route
   *   { path: '/settings', label: 'Settings' }, // override label, icon from route
   *   { path: '/billing', icon: 'CreditCard' } // override icon
   * ]
   * ```
   */
  authMenuItems?: Array<{
    /** Route path (creates Link automatically) */
    path: string;
    /** Optional label (falls back to navigation item label or path segment) */
    label?: string;
    /** Optional Lucide icon name (string) - overrides route discovery icon */
    icon?: string;
  }>;
  /**
   * Optional function to handle custom data deletion before account removal
   * Framework will try/catch this - failures won't block account deletion
   *
   * @example
   * ```typescript
   * deleteUserFunction: async (userId: string) => {
   *   // Cancel Stripe subscriptions
   *   await fetch('/api/billing/cancel', { method: 'POST' });
   *
   *   // Delete Firestore user data
   *   await deleteDoc(doc(db, 'users', userId));
   *
   *   // Custom cleanup
   *   await myCustomCleanup(userId);
   * }
   * ```
   */
  deleteUserFunction?: (userId: string) => Promise<void>;
}

/**
 * SEO configuration
 *
 * Configure automatic SEO meta tags and social sharing.
 *
 * @example
 * ```typescript
 * const seoConfig: SEOConfig = {
 *   baseUrl: 'https://example.com',
 *   defaultImage: '/og-image.png',
 *   twitterHandle: 'mycompany'
 * };
 * ```
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SEOConfig {
  /** Enable automatic SEO (default: true) */
  enabled?: boolean;
  /** Base URL for SEO files (robots.txt, sitemap.xml) - reads from VITE_APP_URL/NEXT_PUBLIC_APP_URL env var */
  baseUrl?: string;
  /** Site name for SEO - defaults to APP_NAME from app.ts */
  siteName?: string;
  /** Crawl delay for robots.txt (default: 1) */
  crawlDelay?: number;
  /** Generate robots.txt (default: true) */
  generateRobotsTxt?: boolean;
  /** Generate sitemap.xml (default: true) */
  generateSitemap?: boolean;
  /** Default namespace for i18n translations (default: 'home') */
  defaultNamespace?: string;
  /** Default image for social sharing */
  defaultImage?: string;
  /** Twitter handle (without @) */
  twitterHandle?: string;
  /** Additional static meta tags */
  staticTags?: Record<string, string>;
}

/**
 * Favicon and PWA configuration
 *
 * Configure automatic favicon generation and PWA manifest icons.
 *
 * @example
 * ```typescript
 * const faviconConfig: FaviconConfig = {
 *   appName: 'My App',
 *   themeColor: '#000000',
 *   backgroundColor: '#ffffff'
 * };
 * ```
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FaviconConfig {
  /** Enable automatic favicon system (default: true) */
  enabled?: boolean;
  /** App name for PWA manifest */
  appName?: string;
  /** Theme color for mobile browsers */
  themeColor?: string;
  /** Background color for splash screens */
  backgroundColor?: string;
  /** Include PWA manifest icons */
  includeManifestIcons?: boolean;
  /** Include Microsoft tile icons */
  includeMSIcons?: boolean;
}

/**
 * Feature flags and debug configuration
 *
 * Controls app behavior and GDPR compliance.
 * Feature availability is auto-detected via env vars/packages.
 *
 * @example
 * ```typescript
 * const featuresConfig: FeaturesConfig = {
 *   debug: true,
 *   offlineTrustEnabled: true,
 *   requiredCookies: ['necessary', 'analytics']
 * };
 * ```
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FeaturesConfig {
  /** Enable debug tools (default: false in production, true in development) */
  debug?: boolean;

  /**
   * Enable offline trust for cached claims (default: false)
   *
   * When true:
   * - Online: Always verify with server (don't trust cache)
   * - Offline: Use cached claims (graceful degradation)
   *
   * When false:
   * - Online: Always verify with server
   * - Offline: Reject (throw error, require network)
   *
   * @default false
   */
  offlineTrustEnabled?: boolean;

  /**
   * Cookie consent categories to display in GDPR banner
   *
   * Controls which cookie categories users can consent to.
   * Framework always includes 'necessary' (cannot be disabled).
   *
   * @example
   * ```typescript
   * features: {
   *   requiredCookies: ['necessary', 'functional', 'analytics']
   * }
   * ```
   *
   * @default ['necessary']
   */
  requiredCookies?: string[];
}

/**
 * Complete application configuration
 *
 * Consolidates all app-level configuration with smart defaults.
 * Pass only what you need to override - everything has sensible defaults.
 *
 * @example
 * ```typescript
 * // Minimal configuration
 * const config: AppConfig = {
 *   app: { name: 'My App' }
 * };
 *
 * // Full configuration
 * const config: AppConfig = {
 *   app: {
 *     name: 'My App',
 *     description: 'Professional app'
 *   },
 *   auth: {
 *     authRoute: '/signin',
 *     roleRoute: '/403',
 *     tierRoute: '/pricing'
 *   },
 *   seo: {
 *     defaultImage: '/og.png'
 *   },
 *   preset: 'landing',
 *   features: {
 *     debug: true
 *   }
 * };
 * ```
 *
 * @version 0.0.2
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Query cache configuration
 *
 * Configure default TanStack Query cache behavior for your app.
 * These settings apply to all queries unless overridden per-query.
 *
 * **Framework Defaults (Infinite Cache):**
 * - `staleTime: Infinity` (data never becomes stale)
 * - `refetchOnWindowFocus: false` (manual refresh only)
 * - `refetchOnReconnect: false` (manual refresh only)
 *
 * This default strategy minimizes API costs and is ideal for:
 * - Single-admin apps
 * - Apps with manual refresh buttons
 * - Cost-optimized scenarios
 *
 * @example
 * ```typescript
 * // Use framework defaults (infinite cache, no auto-refetch)
 * // No query config needed - defaults are optimal
 * ```
 *
 * @example
 * ```typescript
 * // Override to short cache with auto-refetch
 * query: {
 *   staleTime: 1000 * 60 * 5,  // 5 minutes
 *   refetchOnWindowFocus: true,
 *   refetchOnReconnect: true,
 * }
 * ```
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface QueryConfig {
  /** Time until data is considered stale (default: Infinity = never stale) */
  staleTime?: number;
  /** Time until inactive data is garbage collected (default: 30 minutes) */
  gcTime?: number;
  /** Number of retry attempts for failed queries (default: 1) */
  retry?: number;
  /** Whether to refetch when window regains focus (default: false = manual refresh only) */
  refetchOnWindowFocus?: boolean;
  /** Whether to refetch on reconnect (default: false = manual refresh only) */
  refetchOnReconnect?: boolean;
  /** Mutation retry attempts (default: 1) */
  mutationRetry?: number;
  /** Mutation retry delay function (default: exponential backoff) */
  mutationRetryDelay?: (attemptIndex: number) => number;
}

interface AppConfig {
  /** App metadata and branding */
  app?: AppMetadata;
  /** Authentication routes - partial override of defaults */
  auth?: Partial<AuthConfig> | false;
  /** SEO configuration (set to false to disable) */
  seo?: SEOConfig | false;
  /** Favicon configuration (set to false to disable) */
  favicon?: FaviconConfig | false;
  /** Layout preset for store initialization (defaults to 'landing' if invalid/empty) */
  preset?: string;
  /** Feature flags */
  features?: FeaturesConfig;
  /** Query cache configuration (defaults: 5min staleTime, refetch on focus/reconnect) */
  query?: QueryConfig;
}

/**
 * I18n virtual mapping options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface I18nVirtualMappingOptions {
  virtualModuleId?: string;
  eagerNamespaces?: string[];
}

/**
 * Base discovery options - DRY type for code, not a config level
 * HMR options are internal framework concerns (in DEFAULT_OPTIONS only, not user-configurable)
 * Plugins are always enabled (part of framework) - no enabled option
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseDiscoveryOptions {
  /** Debug logging (default: false) - cascades from global debug */
  debug?: boolean;
  /** Verbose logging (default: true) - cascades from global verbose */
  verbose?: boolean;
}

/**
 * Theme detection options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ThemeDetectionOptions extends BaseDiscoveryOptions {
  /** Theme manifest file name (default: 'theme-manifest.json') */
  manifestFileName?: string;
  /** Auto-generate safelist (default: true) */
  autoSafelist?: boolean;
}

/**
 * Route discovery options with virtual module support
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RouteDiscoveryOptions extends BaseDiscoveryOptions {
  /** Disable route discovery (default: false) - set to true if using custom router */
  disabled?: boolean;
  /** Path to manual routes file relative to vite.config.ts (default: './src/routes.ts') */
  manualPath?: string;
  /** Additional patterns to scan beyond centralized patterns */
  additionalPatterns?: string[];
}

/**
 * I18n options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface I18nOptions extends BaseDiscoveryOptions {
  useVirtualMapping?: boolean;
  fallbackLanguage?: string;
  namespaces?: string[];
  virtualMapping?: I18nVirtualMappingOptions;
  /** Additional locale paths from workspace packages (e.g., shared entities) */
  /** Paths are relative to app root. Useful for custom shared translation locations. */
  /** Example: ['../../packages/shared/locales'] */
  /** Note: '../../entities/locales' is auto-detected by default, no config needed */
  additionalPaths?: string[];
}

/**
 * Asset options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AssetOptions extends BaseDiscoveryOptions {
  /** Asset fallback configuration */
  fallback?: AssetFallbackOptions | false;
}

/**
 * Progressive Web App options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PWAOptions {
  /** Enable PWA in production builds (default: false) */
  enabled?: boolean;
  /** Enable PWA in development (default: false) */
  devEnabled?: boolean;
  /** Service worker registration: 'autoUpdate' = update in background, 'prompt' = ask user (default: 'prompt') */
  registerType?: 'autoUpdate' | 'prompt';
  /** Debug logging (default: false) */
  debug?: boolean;
  /** Override manifest values (auto-discovered from app.ts by default) */
  manifest?: Record<string, any>;
  /** Discover build assets for precache (Next.js only, default: true) */
  discoverBuildAssets?: boolean;
  /** Override workbox configuration (smart defaults provided) */
  workbox?: {
    /** Maximum file size to cache in bytes (default: 5MB) */
    maximumFileSizeToCacheInBytes?: number;
    /** Glob patterns for precaching (default: all js, css, html, icons, and fonts) */
    globPatterns?: string[];
    /** Glob patterns to ignore */
    globIgnores?: string[];
    /** Clean up outdated caches (default: true) */
    cleanupOutdatedCaches?: boolean;
    /** Skip waiting for service worker activation (default: true) */
    skipWaiting?: boolean;
    /** Claim clients immediately (default: true) */
    clientsClaim?: boolean;
    /** Runtime caching strategies (smart defaults provided) */
    runtimeCaching?: Array<{
      urlPattern: RegExp | ((options: { request: Request }) => boolean);
      handler:
        | 'CacheFirst'
        | 'NetworkFirst'
        | 'StaleWhileRevalidate'
        | 'NetworkOnly'
        | 'CacheOnly';
      options?: Record<string, any>;
    }>;
    /** Navigation fallback URL (default: '/') */
    navigateFallback?: string;
    /** URLs to exclude from navigation fallback */
    navigateFallbackDenylist?: RegExp[];
    /** Transform precache manifest (allows custom filtering/modification) */
    manifestTransforms?: Array<
      (manifest: Array<{ url: string; revision: string | null }>) => {
        manifest: Array<{ url: string; revision: string | null }>;
        warnings?: string[];
      }
    >;
    /** Background sync configuration for offline actions */
    backgroundSync?:
      | {
          /** Queue name for background sync (default: 'background-sync-queue') */
          queueName?: string;
          /** Maximum retention time in minutes (default: 24 * 60) */
          maxRetentionTime?: number;
          /** URL pattern for background sync routes (default: matches /api/ routes) */
          urlPattern?: RegExp | ((options: { request: Request }) => boolean);
        }
      | false;
    [key: string]: any; // Allow other workbox options
  };
}

/**
 * Asset fallback options
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AssetFallbackOptions {
  /** Enable asset fallback (default: true) */
  enabled?: boolean;
  /** Assets to copy (default: from centralized patterns) */
  assets?: string[];
  /** Asset patterns to scan (default: from centralized patterns) */
  assetPatterns?: string[];
  /** Framework package name (default: '@donotdev/ui') */
  frameworkPackage?: string;
  /** Assets path within framework package (default: 'assets') */
  assetsPath?: string;
  /** Debug logging (default: false) */
  debug?: boolean;
}

/**
 * Server shim options for blocking server-only imports
 * Note: serverShim cannot be disabled - framework would crash without it
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ServerShimOptions {
  /** Additional imports to block beyond defaults */
  blockedImports?: string[];
  /** Debug logging (default: false) */
  debug?: boolean;
}

// Next.js Configuration

/**
 * Next.js configuration options for DNDev applications
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface NextConfigOptions {
  /** App config from app.ts - features and SEO will be extracted automatically (required) */
  appConfig: AppConfig;
  /** Debug mode - enables detailed debug logging */
  debug?: boolean;
  /** Verbose logging - shows config/search paths (opt-out, auto-disabled in CI) */
  verbose?: boolean;
  /** Route discovery configuration (uses DRY RouteDiscoveryOptions) */
  routes?: RouteDiscoveryOptions & {
    /** Generate app/** page files (Site template) (default: true) */
    generateAppPages?: boolean;
    /** Routing mode for Next.js */
    routingMode?: 'pages' | 'app';
    /** Generate authentication middleware */
    generateMiddleware?: boolean;
  };
  /** Internationalization configuration (uses DRY I18nOptions) */
  i18n?: I18nOptions;
  /** Theme configuration (uses DRY ThemeDetectionOptions) */
  themes?: ThemeDetectionOptions;
  /** Asset configuration (uses DRY AssetOptions) */
  assets?: AssetOptions;
  /** Generate route manifest */
  generateManifest?: boolean;
  /** PWA configuration */
  pwa?: PWAOptions;
  /** Server shim options */
  serverShim?: ServerShimOptions;
  /** Standard Next.js config options (webpack, rewrites, headers, etc.) - passed through as-is */
  [key: string]: any;
}

/**
 * Creates a Next.js configuration optimized for DNDev applications
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function defineNextConfig(options?: NextConfigOptions): any;

export { defineNextConfig };
export type { NextConfigOptions };
