/**
 * The editor bootstrap (`window.nexwordxEditor`, CONTRACT §7.1): the `GET /document/{id}`
 * payload (§6.2) plus the shell data the admin handler prints inline. Everything the
 * editor knows about the site arrives here; nothing else is read from wp-admin.
 */

import type {
  Breakpoints,
  ConditionRule,
  Document,
  Kit,
  MenuItem,
  PageSettings,
  PostLock,
  Rendered,
  ResolvedElement,
  TemplateBundle,
  TemplateType,
  WidgetCategory,
  WidgetDefs,
} from '@nexwordx/renderer';

export interface BootstrapPost {
  id: number;
  type: string;
  title: string;
  status: string;
  slug: string;
  link: string;
  editLink: string;
  modified: string;
}

export interface BootstrapUser {
  id: number;
  name: string;
  canPublish: boolean;
  unfilteredHtml: boolean;
  canEditCss: boolean;
  canManageKit: boolean;
  /**
   * The Role Manager level (CONTRACT §12, added by the role-manager module through
   * `nexwordx_editor_bootstrap`): 'content' limits the editor to the Content tab (§7.5).
   * Missing = 'full' (no role manager, or an older server).
   */
  access?: 'full' | 'content' | 'none';
}

/** `bootstrap.template` (CONTRACT §16.4): the edited post is a library template. */
export interface BootstrapTemplate {
  type: TemplateType;
  /** header, footer, single, archive, search-results, error-404 (they have display conditions). */
  isTheme: boolean;
  conditions: ConditionRule[];
  /** A human-readable summary of the conditions ("Entire site"). */
  summary: string;
  /** The type's first "Preview with" path; '' for types without a preview. */
  previewPath: string;
}

/** What a condition's `subId` picks: a post (of `postType`), a term (of `taxonomy`), a user. */
export type ConditionNeeds = '' | 'post' | 'term' | 'user';

/** One sub of `conditionOptions` (= `Nexwordx_Conditions::options()`). */
export interface ConditionSubOption {
  sub: string;
  label: string;
  needs: ConditionNeeds;
  postType?: string;
  taxonomy?: string;
}

/** One group of `conditionOptions`: general / singular / archive with its subs. */
export interface ConditionGroupOption {
  name: ConditionRule['name'];
  label: string;
  subs: ConditionSubOption[];
}

/** `bootstrap.layout` (CONTRACT §7.5): the site header and footer shown around the canvas. */
export interface BootstrapLayout {
  header: TemplateBundle | null;
  footer: TemplateBundle | null;
}

/** `GET /theme/preview-options` row. */
export interface PreviewOption {
  path: string;
  label: string;
}

/** `GET|POST /library/{id}/conditions` answers (CONTRACT §16.4). */
export interface ConditionsResponse {
  ok?: boolean;
  conditions: ConditionRule[];
  summary: string;
  options?: ConditionGroupOption[];
}

export interface BootstrapFrontend {
  url: string;
  connected: boolean;
  origin: string;
}

export interface BootstrapUrls {
  admin: string;
  exit: string;
  dashboard: string;
  settings: string;
  library: string;
  siteHome: string;
  adminAjax: string;
  previewBase: string;
  wpPreview: string;
}

export interface BootstrapFonts {
  system: string[];
  google: Array<{ f: string; c: string }>;
}

export interface RevisionSummary {
  id: number;
  time: string;
  author: string;
}

export interface EditorBootstrap {
  /* ---- §6.2 GET /document/{id} ---- */
  post: BootstrapPost;
  document: Document;
  pageSettings: PageSettings;
  autosave: { time: number; user: number } | null;
  lock: PostLock | null;
  revisions: RevisionSummary[];
  resolved: Record<string, ResolvedElement>;
  rendered: Record<string, Rendered>;
  menus: Record<string, MenuItem[]>;
  icons: Record<string, string>;
  kit: Kit;
  widgetsHash: string;

  /* ---- §7.1 shell data ---- */
  version: string;
  restUrl: string;
  wpRestUrl: string;
  nonce: string;
  widgets: WidgetDefs;
  categories: WidgetCategory[];
  breakpoints: Breakpoints;
  previewWidths: Record<string, number>;
  heartbeatInterval: number;
  user: BootstrapUser;
  frontend: BootstrapFrontend;
  urls: BootstrapUrls;
  i18n: Record<string, string>;
  /**
   * §7.1 names this `fonts` (the catalog) while §6.2 names the page's Google families
   * `fonts` too; the editor accepts the catalog shape and recomputes the used families
   * itself with `collectFonts`.
   */
  fonts: BootstrapFonts | string[];
  fontsSource: 'google' | 'none';
  imageSizes: string[];
  postTypes: Array<{ slug: string; label: string }>;
  locale: string;
  rtl: boolean;
  structurePresets: number[][];

  /* ---- §7.5 / §16.4 (theme-builder module) ---- */
  /** Header and footer of the post's own context; both null for header/footer templates. */
  layout?: BootstrapLayout;
  /** Present when the edited post is a library template. */
  template?: BootstrapTemplate | null;
  /** The conditions catalogue; present for theme templates. */
  conditionOptions?: ConditionGroupOption[];
}

/** `POST /document/{id}` answer (§6.2). */
export interface SaveResponse {
  ok: boolean;
  status: string;
  modified: string;
  link: string;
  revalidated?: boolean;
}

export type SaveAction = 'autosave' | 'draft' | 'publish' | 'update';

/** `GET /library` row (§6.2); without `?type=` only page and section templates are listed. */
export interface LibraryTemplate {
  id: number;
  title: string;
  type: TemplateType;
  thumbnail: string;
  modified: string;
}

/** Minimal typings of the WordPress globals the shell enqueues (heartbeat, media, jQuery). */
export interface WpHeartbeat {
  interval(seconds?: number | 'fast' | 'standard' | 'slow'): number;
  enqueue(handle: string, data: unknown, noOverride?: boolean): boolean;
  connectNow(): void;
}

export interface WpGlobals {
  heartbeat?: WpHeartbeat;
  media?: unknown;
  i18n?: { __?(text: string, domain?: string): string };
}

declare global {
  interface Window {
    nexwordxEditor?: EditorBootstrap;
    wp?: WpGlobals;
    jQuery?: {
      (target: globalThis.Document | Window | string | HTMLElement): {
        on(event: string, handler: (...args: unknown[]) => void): unknown;
        off(event: string, handler?: (...args: unknown[]) => void): unknown;
        trigger(event: string, data?: unknown): unknown;
      };
    };
  }
}
