import type { LayoutConfig } from './layout';
import type { AsukaPermissions } from './permissions';
import type { ListenerOptions } from './listeners';
import type {
  AsukaLicenseRefreshOptions,
  AsukaLicenseTokenInput,
} from '../core/license/license.types';
import type { AsukaAgencyOptions } from '../core/agency';
import type { AsukaAiOptions } from '../core/ai';
import type { AsukaExportsOptions } from '../core/exports';
import type { AsukaResponsiveConfig } from '../core/responsive';
import type { AsukaUiOptions } from '../core/uiOptions';
import type { Asuka3DSceneState, AsukaRenderEngineKind, AsukaRenderEngineOptions, AsukaRenderEngineOptionsByKind } from '../core/renderEngine';
import type { AsukaPhysicalSize } from '../core/physicalMeasurement';
export type { AsukaUiOptions, AsukaViewsPaginationOptions, AsukaViewsPaginationMode } from '../core/uiOptions';
export type { Asuka3DDecoration, Asuka3DCameraOptions, Asuka3DEngineOptions, Asuka3DProductOptions, Asuka3DPrintArea, Asuka3DSceneState, AsukaRenderEngine, AsukaRenderEngineKind, AsukaRenderEngineOptions, AsukaRenderEngineOptionsByKind } from '../core/renderEngine';
export type { AsukaCameraView, AsukaCameraLimits, AsukaCameraMoveOptions } from './camera';

export type AsukaMode = 'dev' | 'prod';

/** Icon override accepted by layout items and runtime module buttons. */
export type AsukaIconOverride =
  | string
  | {
      /** Registered icon name. */
      name?: string;
      /** External icon URL. */
      url?: string;
      /** Inline SVG string. */
      svg?: string;
    };

/** Where a runtime font definition comes from. */
export type AsukaFontSource = 'system' | 'google' | 'custom';

/** One system font family exposed in the runtime font registry. */
export interface AsukaSystemFontConfig {
  /** Optional stable font id. */
  id?: string;
  /** CSS font-family name. */
  family: string;
}

/** One Google Font family exposed in the runtime font registry. */
export interface AsukaGoogleFontConfig {
  /** Optional stable font id. */
  id?: string;
  /** Google Font family name. */
  family: string;
  /** Optional prebuilt stylesheet URL. */
  cssUrl?: string;
  /** Supported font weights. */
  weights?: Array<string | number>;
  /** Supported font styles. */
  styles?: Array<'normal' | 'italic'>;
}

/** One self-hosted custom font exposed in the runtime font registry. */
export interface AsukaCustomFontConfig {
  /** Optional stable font id. */
  id?: string;
  /** CSS font-family name. */
  family: string;
  /** Direct font file URL. */
  url?: string;
  /** Optional stylesheet URL when the font is defined through CSS. */
  cssUrl?: string;
  /** Font file format used by {@link AsukaCustomFontConfig.url}. */
  format?: 'woff2' | 'woff' | 'ttf' | 'otf';
  /** Default weight advertised by the font. */
  weight?: string | number;
  /** Default style advertised by the font. */
  style?: 'normal' | 'italic';
}

/** One normalized entry stored in the runtime font registry. */
export interface AsukaRegisteredFont {
  /** Stable registry id. */
  id: string;
  /** CSS font-family name. */
  family: string;
  /** Font origin. */
  source: AsukaFontSource;
  /** Optional stylesheet URL. */
  cssUrl?: string;
  /** Optional direct font file URL. */
  url?: string;
  /** Font file format. */
  format?: 'woff2' | 'woff' | 'ttf' | 'otf';
  /** Default weight advertised by the font. */
  weight?: string | number;
  /** Default style advertised by the font. */
  style?: 'normal' | 'italic';
  /** Supported font weights. */
  weights?: Array<string | number>;
  /** Supported font styles. */
  styles?: Array<'normal' | 'italic'>;
  /** Whether the font has already been loaded. */
  loaded?: boolean;
  /** Whether the font is currently loading. */
  loading?: boolean;
  /** Optional load error message. */
  error?: string;
}

/** Font registry payload accepted at initialization. */
export interface AsukaFontsConfig {
  /** Built-in/system font families. */
  system?: Array<string | AsukaSystemFontConfig>;
  /** Google Fonts to register at boot. */
  google?: Array<string | AsukaGoogleFontConfig>;
  /** Self-hosted custom fonts to register at boot. */
  custom?: AsukaCustomFontConfig[];
}

/** One item displayed by the built-in Designs module. */
export interface AsukaDesignCatalogItem {
  /** Direct URL to the SVG or raster asset. */
  url: string;
  /** Human-readable item label. */
  name: string;
  /** Optional display price. */
  price?: number | string;
  /** Optional grouping/category label. */
  category?: string;
}

/** One SVG asset displayed by the built-in Shapes module. */
export interface AsukaShapeSvgAssetConfig {
  /** Optional stable asset id. */
  id?: string;
  /** Human-readable asset name. */
  name: string;
  /** Inline SVG markup used to recreate the shape. */
  svgText: string;
}

/** Default style applied to newly created built-in shapes. */
export interface AsukaShapeStyleConfig {
  fill?: string;
  stroke?: string;
  strokeWidth?: number;
  opacity?: number;
}

/** Extra edit defaults used by shape-specific editors. */
export interface AsukaShapeEditDefaultsConfig {
  rectRadius?: number;
  starSpikes?: number;
  starInnerRatio?: number;
}

/** Supported image upload strategies for the built-in Upload module and media inputs. */
export type AsukaUploadStrategy = 'objectUrl' | 'base64' | 'remote';

/** Default file persistence strategy when no upload policy is configured. */
export const DEFAULT_ASUKA_UPLOAD_STRATEGY: AsukaUploadStrategy = 'base64';

/** Result accepted from a custom upload handler. */
export type AsukaUploadHandlerResult = string | { url?: string; dataUrl?: string; src?: string; value?: string; fileUrl?: string; downloadUrl?: string; data?: unknown; result?: unknown };

/** A media item selected by a host-controlled picker or media library. */
export type AsukaUploadSelectionItem =
  | File
  | string
  | {
      id?: string;
      file?: File;
      url?: string;
      dataUrl?: string;
      dataURL?: string;
      src?: string;
      value?: string;
      fileUrl?: string;
      downloadUrl?: string;
      previewUrl?: string;
      name?: string;
      filename?: string;
      mimeType?: string;
      type?: string;
      size?: number;
      lastModified?: number;
      source?: string;
      mode?: string;
      strategy?: string;
      mediaId?: string | number;
      attachmentId?: string | number;
      metadata?: unknown;
      data?: unknown;
      result?: unknown;
    };

/** Container accepted from a host-controlled media picker. */
export type AsukaUploadSelectionPayload =
  | AsukaUploadSelectionItem
  | AsukaUploadSelectionItem[]
  | {
      items?: AsukaUploadSelectionPayload;
      media?: AsukaUploadSelectionPayload;
      attachments?: AsukaUploadSelectionPayload;
      selection?: AsukaUploadSelectionPayload;
      files?: AsukaUploadSelectionPayload;
      assets?: AsukaUploadSelectionPayload;
      data?: AsukaUploadSelectionPayload;
      result?: AsukaUploadSelectionPayload;
    };

/** Result accepted from a host-controlled media picker. */
export type AsukaUploadSelectHandlerResult = AsukaUploadSelectionPayload | null | undefined | void;

/** Context passed to a custom upload handler. */
export interface AsukaUploadHandlerContext {
  /** Effective upload config after merging boot config and one-off overrides. */
  config: AsukaUploadModuleConfig;
  /** Upload caller, for example `canvas`, `remote-image`, or `media-input`. */
  source?: string;
  /** Media input mode when the upload comes from an input field. */
  mode?: string;
}

/** Context passed to a custom media picker. */
export interface AsukaUploadSelectHandlerContext extends AsukaUploadHandlerContext {
  /** Accepted MIME/extensions requested by the current UI, for example `image/*`. */
  accept?: string;
  /** Whether the current upload field accepts several files/media items. */
  multiple?: boolean;
  /** Upload UI kind, for example `canvas-upload` or `media-input`. */
  kind?: 'canvas-upload' | 'media-input' | string;
}

/** Upload module boot-time configuration. */
export interface AsukaUploadModuleConfig {
  /** Allow selecting multiple files in the upload dropzone. */
  multiple?: boolean;
  /** In single mode, add the uploaded image immediately. */
  autoAddOnSingle?: boolean;
  /**
   * File-to-image strategy used when a file is added to the canvas.
   *
   * - `objectUrl`: create a temporary local blob URL and add it immediately.
   * - `base64`: convert the file to a data URL before adding it.
   * - `remote`: upload the file to an HTTP endpoint, then add the returned URL.
   *
   * Defaults to `base64` when neither a strategy nor a remote target is configured.
   */
  strategy?: AsukaUploadStrategy;
  /**
   * Optional media picker mode.
   *
   * - `native`: keep the browser file input.
   *
   * Host integrations such as WordPress media library should use `selectHandler`.
   * AsukaDesigner awaits the returned promise, normalizes its result, registers the
   * upload asset, then applies it to the right target automatically.
   */
  picker?: 'native';
  /** Optional title forwarded to host-controlled pickers through `selectHandler` context. */
  pickerTitle?: string;
  /** Optional button label forwarded to host-controlled pickers through `selectHandler` context. */
  pickerButtonText?: string;
  /** Optional host-controlled media picker. It may return File objects, URL strings, media objects, arrays, or `{ items/data/result }` containers. */
  selectHandler?: (context: AsukaUploadSelectHandlerContext) => AsukaUploadSelectHandlerResult | Promise<AsukaUploadSelectHandlerResult>;
  /**
   * Optional custom upload handler.
   *
   * When provided, the handler is used before `endpoint` for the `remote` strategy
   * and can return either a URL string or an object containing `url`, `dataUrl`,
   * `src`, or `value`. This is useful for WordPress/Symfony/custom backends.
   */
  handler?: (file: File, context: AsukaUploadHandlerContext) => AsukaUploadHandlerResult | Promise<AsukaUploadHandlerResult>;
  /** Remote upload endpoint used by the `remote` strategy. */
  endpoint?: string;
  /** HTTP method used when `endpoint` is provided. Defaults to `POST`. */
  method?: string;
  /** Optional request headers sent with the remote upload request. */
  headers?: Record<string, string>;
  /** Fetch credentials mode used by the remote upload request. */
  credentials?: RequestCredentials;
  /** Multipart form field name used for the uploaded file. Defaults to `file`. */
  fieldName?: string;
  /**
   * Maps the remote upload response to a final image URL.
   *
   * Example: `(json) => json.url`
   */
  mapResponseToUrl?: (payload: unknown) => string;
}

/** Designs module boot-time configuration. */
export interface AsukaDesignsModuleConfig {
  /** Static designs displayed by the module. */
  items?: AsukaDesignCatalogItem[];
}

/** Shapes module boot-time configuration. */
export interface AsukaShapesModuleConfig {
  /** Boot-time SVG assets shown in the picker. */
  svgAssets?: AsukaShapeSvgAssetConfig[];
  /** Default shape style. */
  style?: AsukaShapeStyleConfig;
  /** Shape editor defaults. */
  editDefaults?: AsukaShapeEditDefaultsConfig;
}

/** Premium server-backed GLB optimization module configuration. */
export interface AsukaModelOptimizerModuleConfig {
  /** Protected HTTP endpoint receiving a raw `model/gltf-binary` request body. */
  endpoint?: string;
  /** Optional request headers added before license authorization headers. */
  headers?: Record<string, string>;
  /** Fetch credentials mode used for the optimization request. */
  credentials?: RequestCredentials;
  /** Client-side upload limit in megabytes. Defaults to 256. */
  maxFileSizeMb?: number;
}

/** Spatial Assembly module boot-time configuration. */
export interface AsukaAssemblyModuleConfig {
  /** Expose the developer-only guided example action. Defaults to false. */
  showGuidedExample?: boolean;
}

/** Grouped per-module configuration accepted at initialization. */
export interface AsukaModuleConfig {
  upload?: AsukaUploadModuleConfig;
  designs?: AsukaDesignsModuleConfig;
  shapes?: AsukaShapesModuleConfig;
  modelOptimizer?: AsukaModelOptimizerModuleConfig;
  assembly?: AsukaAssemblyModuleConfig;
}

/** PDF export support configuration. */
export interface AsukaPdfOptions {
  /** Set to false to disable PDF export UI entirely. */
  enabled?: boolean;
  /** External script URL for jsPDF. Defaults to https://cdn.jsdelivr.net/npm/jspdf@4.2.1/dist/jspdf.umd.min.js. */
  scriptUrl?: string;
  /** Auto-load the script the first time PDF export is requested. Defaults to true. */
  autoLoad?: boolean;
}

/** Pixabay integration settings. */
export interface AsukaPixabayIntegrationConfig {
  apiKey?: string;
}

/** Pexels integration settings. */
export interface AsukaPexelsIntegrationConfig {
  apiKey?: string;
}

/** Facebook integration settings. */
export interface AsukaFacebookIntegrationConfig {
  appId?: string;
  accessToken?: string;
}

/** Third-party integrations accepted at initialization. */
export interface AsukaIntegrationsConfig {
  pixabay?: AsukaPixabayIntegrationConfig;
  pexels?: AsukaPexelsIntegrationConfig;
  facebook?: AsukaFacebookIntegrationConfig;
}

/** One global color entry stored in the designer store. */
export interface AsukaColorItem {
  [key: string]: unknown;
}

/** Designer-level colors configuration. */
export interface AsukaColorsConfig {
  /** Target scope when the colors module opens. */
  scope?: 'object' | 'canvas' | 'document';
  /** Initial global colors list. */
  items?: AsukaColorItem[];
}

/** Designer-level printing method entry stored in the global store. */
export interface AsukaPrintingMethod {
  [key: string]: unknown;
}

/** One dynamic pricing rule stored in the pricing engine. */
export interface AsukaPricingRule {
  [key: string]: unknown;
}

/** Currency/price formatting configuration. */
export interface AsukaPriceFormatConfig {
  code?: string;
  symbol?: string;
  priceFormat?: string;
  decimalSeparator?: string;
  thousandSeparator?: string;
  precision?: number;
  trimZeros?: boolean;
}

/** Internationalization boot-time configuration. */
export interface AsukaI18nOptions {
  /** Active locale used at startup. */
  locale?: string;
  /** Fallback locale used when a key is missing. */
  fallbackLocale?: string;
  /** Locale bundles injected at startup. */
  translations?: Record<string, Record<string, unknown>>;
}

/** Theme initialization payload forwarded to the theme runtime. */
export interface AsukaThemeOptions {
  /** Optional bundled preset id. */
  preset?: string;
  /** Token overrides keyed by theme token name. */
  colors?: Record<string, string>;
}

/** Commercial branding and Pro+/Agency feature configuration. These options become active when the matching license entitlements are available. */
export interface AsukaAgencyFeatureOptions extends AsukaAgencyOptions {}

export interface AsukaAiFeatureOptions extends AsukaAiOptions {}

export interface AsukaExportsFeatureOptions extends AsukaExportsOptions {}


/** Canvas UI scaling options used to keep controls and helpers readable when the canvas is visually shrunk. */
export interface AsukaUiScalingOptions {
  /** Keep Fabric controls readable when the canvas is visually shrunk with CSS. */
  keepControlsReadable?: boolean;
  /** Keep helper lines and technical overlays readable when the canvas is visually shrunk with CSS. */
  keepHelpersReadable?: boolean;
  /** Base custom control size before visual compensation. */
  baseControlSize?: number;
  /** Base touch target size before visual compensation. */
  baseTouchControlSize?: number;
  /** Minimum helper stroke width after compensation. */
  minHelperStrokeWidth?: number;
  /** Maximum multiplier applied when the canvas becomes very small. */
  maxCompensationMultiplier?: number;
}

/** Optional outer shell sizing applied to the root designer card. */

export type AsukaBootMode = 'initialState' | 'replace-product';

/** Structured boot-time restoration options. */
export interface AsukaBootOptions {
  /** Explicit boot strategy used to decide which payload wins and when it is restored. */
  mode?: AsukaBootMode;
  /** Canonical full-state payload used for complete product/session replacement. */
  state?: unknown;
}

export interface AsukaLicenseOptions {
  /** Set to `false` to force free mode and skip all remote license resolution. */
  enabled?: boolean;
  /** Raw commercial license key. This is the main public activation input. */
  key?: string;
  /** Signed entitlement token injected directly by a host integration. Accepts either a structured object or a compact signed token string. */
  token?: AsukaLicenseTokenInput;
  /** Optional explicit site/domain used during remote resolution. Defaults to `window.location.hostname`. */
  domain?: string;
  /** Optional stable instance id used during remote resolution. Defaults to a generated local id persisted in localStorage. */
  instanceId?: string;
  /** Optional integration channel sent to the backend. Defaults to `js`. */
  channel?: string;
  /** Optional explicit expected audience claim. Defaults to `asuka-designer`. */
  audience?: string;
  /** Optional auto-refresh behavior for remotely resolved licenses. */
  refresh?: AsukaLicenseRefreshOptions;
  /** Enable verbose client-side license logs. */
  debug?: boolean;
}

/** Optional debug switches for integrations and state boot flows. */
export interface AsukaDebugOptions {
  /** Log boot strategy resolution and payload selection. */
  boot?: boolean;
  /** Log state import/export operations. */
  state?: boolean;
  /** Log layout normalization, runtime extraction and layout imports. */
  layout?: boolean;
}

export interface AsukaObservabilityErrorRecord {
  type: 'error' | 'unhandledrejection' | 'manual';
  message: string;
  stack?: string;
  timestamp: string;
  context?: Record<string, unknown>;
}

/** Host-controlled production error reporting. No remote endpoint is enabled implicitly. */
export interface AsukaObservabilityOptions {
  /** Disable all reporting while keeping the configuration in place. Defaults to true when `onError` is provided. */
  enabled?: boolean;
  /** Capture uncaught window errors and unhandled promise rejections. Defaults to true. */
  captureGlobalErrors?: boolean;
  /** Forward one sanitized error record to the host application (Sentry, Datadog, custom API, etc.). */
  onError?: (record: AsukaObservabilityErrorRecord) => void;
  /** Static non-sensitive metadata attached to every record. */
  context?: Record<string, unknown>;
}

/** Initial view accepted directly by createAsukaDesigner({ views: [...] }). */
export interface AsukaInitialViewConfig {
  /** Stable view id. When omitted, AsukaDesigner generates one. */
  id?: string;
  /** Human-readable view name. */
  name?: string;
  /** Rendering engine used by this view. Defaults to the root `engine` option. */
  engine?: AsukaRenderEngineKind;
  /** Initial 3D scene state used when `engine: '3d'`. */
  scene3d?: Asuka3DSceneState;
  /** Export/canvas width. */
  width?: number;
  /** Export/canvas height. */
  height?: number;
  /** Dots per inch metadata used by exports and size conversions. */
  dpi?: number;
  /** Unit used by the view dimensions. */
  unit?: 'px' | 'cm' | 'mm' | 'in';
  /** Real-world extent represented by this view when no drawing-area calibration is available. */
  physicalSize?: AsukaPhysicalSize;
}

export interface AsukaShellOptions {
  /** Explicit shell width (for example `1200px`, `90vw`, or `100%`). */
  width?: string | null;
  /** Explicit shell height (for example `800px`, `80vh`, or `100%`). */
  height?: string | null;
  /** Maximum shell width. `null` keeps it unconstrained. */
  maxWidth?: string | null;
  /** Maximum shell height. `null` keeps it unconstrained. */
  maxHeight?: string | null;
}

/** Options accepted by `createAsukaDesigner(...)`. */
export interface AsukaDesignerOptions {
  /** Custom role presets merged on top of the built-in defaults. */
  roles?: Record<string, Partial<AsukaPermissions>>;
  /** Default role applied at boot. */
  defaultRole?: string;
  /** Global mode. In prod, some permissions default to stricter values. */
  mode?: AsukaMode;
  /** Default rendering engine. Fabric remains the default 2D engine; 3D is intended for addon-backed views. */
  engine?: AsukaRenderEngineKind | AsukaRenderEngineOptions;
  /** Optional per-engine loaders/configuration. Use this to lazy-load Fabric/Babylon by active view engine. */
  engines?: AsukaRenderEngineOptionsByKind;
  /** Optional initial views. Each view can override the root engine. */
  views?: AsukaInitialViewConfig[];
  /** Layout, menus and selection menu presets. */
  layout?: LayoutConfig;
  /** Runtime icon overrides for menu/module buttons. */
  icons?: Record<string, AsukaIconOverride>;
  /**
   * Permission overrides merged on top of the selected role defaults.
   * Example: `{ canMovePanels: true, canCollapsePanels: true }` enables menu drag & drop
   * and zone/panel collapse controls even in `mode: 'prod'`.
   * Assembly editing is enabled by default in `mode: 'dev'` and read-only in
   * `mode: 'prod'`; set `canEditAssembly: true` only on a trusted editor.
   */
  permissions?: Partial<AsukaPermissions>;
  /** Per-module configuration (UI defaults, feature toggles). */
  moduleConfig?: AsukaModuleConfig;
  /** Optional PDF export support. */
  pdf?: AsukaPdfOptions;
  /** Third-party integrations (API keys, endpoints, ...). */
  integrations?: AsukaIntegrationsConfig;
  /** Global font registry loaded at boot. */
  fonts?: AsukaFontsConfig;
  /** Designer-level colors configuration. */
  colors?: AsukaColorsConfig;
  /** Initial printing methods list. */
  printingMethods?: AsukaPrintingMethod[];
  /** Optional external/base price included by computed totals. */
  price?: number | string;
  /** Dynamic pricing rules evaluated by the pricing engine. */
  pricingRules?: AsukaPricingRule[];
  /** Default price formatting settings. */
  priceFormat?: AsukaPriceFormatConfig;
  /** Enable/disable individual listeners at boot. */
  listeners?: ListenerOptions;
  /** Theme initialization payload. */
  theme?: AsukaThemeOptions;
  /** Agency-only features such as white-label branding, advanced permissions and export/import helpers. */
  agency?: AsukaAgencyFeatureOptions;
  /** AI helpers such as text-to-image and background removal adapters. */
  ai?: AsukaAiFeatureOptions;
  /** Paid export helpers such as PDF credit consumption and server-side HD rendering. */
  exports?: AsukaExportsFeatureOptions;
  /** Optional runtime licensing configuration. */
  license?: AsukaLicenseOptions;
  /** Optional root shell sizing overrides. */
  shell?: AsukaShellOptions;
  /** UI behavior overrides such as the view pagination bar. */
  ui?: AsukaUiOptions;
  /** Responsive shell/layout behavior for mobile and tablet containers. */
  responsive?: AsukaResponsiveConfig;
  /** Keeps editor controls and helper overlays readable when the canvas is visually shrunk. */
  uiScaling?: AsukaUiScalingOptions;
  /** Serialized full state restored automatically right after initialization. */
  initialState?: unknown;
  /** Explicit boot strategy used to replace a product/session at startup. */
  boot?: AsukaBootOptions;
  /** Optional debug switches for boot/state/layout logs. */
  debug?: AsukaDebugOptions;
  /** Optional host-controlled production error reporting. */
  observability?: AsukaObservabilityOptions;
  /** Internationalization initialization payload. */
  i18n?: AsukaI18nOptions;
}
