import type { AiConfig } from '@templatical/types';
import { BlockDefaults } from '@templatical/types';
import type { CollaborationConfig } from '@templatical/types';
import type { CommentEvent } from '@templatical/types';
import { ComputedRef } from 'vue';
import type { CustomBlock } from '@templatical/types';
import { CustomBlockDefinition } from '@templatical/types';
import { CustomFont } from '@templatical/types';
import { DisplayConditionsConfig } from '@templatical/types';
import { FontsConfig } from '@templatical/types';
import { LintOptions } from '@templatical/quality';
import type { McpConfig } from '@templatical/types';
import type { MediaItem } from '@templatical/media-library';
import type { MediaRequestContext } from '@templatical/media-library';
import type { MediaResult } from '@templatical/types';
import { MergeTagsConfig } from '@templatical/types';
import { Ref } from 'vue';
import { SaveResult } from '@templatical/types';
import { Template } from '@templatical/types';
import { TemplateContent } from '@templatical/types';
import { TemplateDefaults } from '@templatical/types';
import { ThemeOverrides } from '@templatical/types';
import { UiTheme } from '@templatical/types';
import { ViewportSize } from '@templatical/types';

export { BlockDefaults }

export { CustomBlockDefinition }

export { CustomFont }

export { DisplayConditionsConfig }

export declare interface EditorCapabilities {
    plan?: {
        hasFeature(feature: string): boolean;
    };
    ai?: {
        isFeatureEnabled(feature: string): boolean;
    };
    comments?: {
        getBlockCount(blockId: string): number;
        openForBlock(blockId: string): void;
    };
    savedModules?: {
        openSaveDialog(blockId: string): void;
        openBrowser(): void;
        moduleCount: ComputedRef<number>;
    };
}

export declare interface FontOption {
    value: string;
    label: string;
    isCustom?: boolean;
}

export { FontsConfig }

/**
 * Get the base language code from a locale string.
 * e.g., 'en-GB' -> 'en', 'de_DE' -> 'de'
 */
export declare function getBaseLocale(locale: string): string;

/** List of cloud-supported locales. May be a subset of OSS locales. */
export declare function getSupportedCloudLocales(): string[];

/** List of OSS-supported locales. */
export declare function getSupportedLocales(): string[];

export declare function init(config: TemplaticalEditorConfig): Promise<TemplaticalEditor>;

export declare function initCloud(config: TemplaticalCloudEditorConfig): Promise<TemplaticalCloudEditor>;

/** Check if a locale has cloud translations (matched by exact locale, then base). */
export declare function isCloudLocaleSupported(locale: string): boolean;

/** Check if a locale has OSS translations (matched by exact locale, then base). */
export declare function isLocaleSupported(locale: string): boolean;

export { MergeTagsConfig }

/** Function type for media browser requests, used by both OSS and Cloud editors. */
export declare type OnRequestMedia = (context?: MediaRequestContext) => Promise<MediaResult | null>;

export { SaveResult }

export { Template }

export { TemplateContent }

export { TemplateDefaults }

/**
 * Cloud editor does not expose `toMjml` or `renderCustomBlock`: the cloud
 * backend performs MJML conversion server-side with additional processing
 * (e.g., signed image URLs, attachment handling) that isn't available client
 * side. Use the cloud `save()` flow to persist content; the backend handles
 * MJML/HTML export from there.
 */
export declare interface TemplaticalCloudEditor extends TemplaticalEditorBase {
    create(content?: TemplateContent): Promise<Template>;
    load(templateId: string): Promise<Template>;
    save(): Promise<SaveResult>;
}

export declare interface TemplaticalCloudEditorConfig {
    container: string | HTMLElement;
    content?: TemplateContent;
    /**
     * Mount the editor inside a Shadow DOM (open mode) for CSS isolation
     * from the host page. Defaults to `true` — host stylesheets cannot
     * cascade past the shadow boundary into editor elements (`p`, `a`,
     * `input`, etc.), and editor utility classes never collide with host
     * class names.
     *
     * Set to `false` to mount in light DOM. Opt out when:
     *  - Your host integration uses `document.querySelector` to reach
     *    editor internals (with shadow DOM, use `container.shadowRoot
     *    .querySelector(...)` instead).
     *  - You need to support Firefox <101 or Safari <16.4, which lack the
     *    `adoptedStyleSheets` API the shadow path relies on.
     *
     * Light-mode consumers should keep this set to `false` explicitly so
     * future SDK changes don't silently flip the default again.
     *
     * @default true
     */
    shadowDom?: boolean;
    auth: {
        url: string;
        baseUrl?: string;
        requestOptions?: {
            method?: "GET" | "POST";
            headers?: Record<string, string>;
            body?: Record<string, unknown>;
            credentials?: RequestCredentials;
        };
    };
    theme?: ThemeOverrides;
    uiTheme?: UiTheme;
    locale?: string;
    /**
     * Show the "Powered by Templatical" footer. Defaults to `true`.
     * Set to `false` to hide the footer (no attribution required by the license).
     * Cloud white-label plans hide the footer regardless of this setting.
     */
    branding?: boolean;
    ai?: AiConfig | false;
    commenting?: boolean;
    collaboration?: CollaborationConfig;
    mcp?: McpConfig;
    blockDefaults?: BlockDefaults;
    templateDefaults?: TemplateDefaults;
    modules?: boolean;
    autoSave?: boolean;
    autoSaveDebounce?: number;
    mergeTags?: MergeTagsConfig;
    displayConditions?: DisplayConditionsConfig;
    customBlocks?: CustomBlockDefinition[];
    fonts?: FontsConfig;
    onChange?: (content: TemplateContent) => void;
    onSave?: (result: SaveResult) => void;
    onCreate?: (template: Template) => void;
    onLoad?: (template: Template) => void;
    onError?: (error: Error) => void;
    onComment?: (event: CommentEvent) => void;
    onUnmount?: () => void;
    onRequestMedia?: (context: MediaRequestContext) => Promise<MediaItem | null>;
    onBeforeTestEmail?: (html: string) => string | Promise<string>;
    /**
     * Template linter (`@templatical/quality`) configuration. Runs every
     * linter exported by the package (accessibility + structure). Cloud
     * additionally merges `planConfig.accessibility` from the server (server
     * policy wins on conflict) — this option sets the consumer-supplied baseline.
     */
    lint?: LintOptions;
}

export declare interface TemplaticalEditor extends TemplaticalEditorBase {
    /**
     * Render the current template to an MJML string. Resolves custom blocks
     * via the editor's internal block registry. Throws if the optional
     * `@templatical/renderer` package is not installed.
     */
    toMjml(): Promise<string>;
    /**
     * Render a single custom block to its HTML representation, using the
     * registered custom block definition's template and the block's current
     * field values. Exposed for headless callers that want to reuse the
     * editor's renderer (e.g., to drive `@templatical/renderer`'s
     * `renderCustomBlock` option from outside the editor instance).
     */
    renderCustomBlock(block: CustomBlock): Promise<string>;
}

declare interface TemplaticalEditorBase {
    getContent(): TemplateContent;
    setContent(content: TemplateContent): void;
    setTheme(theme: UiTheme): void;
    unmount(): void;
}

export declare interface TemplaticalEditorConfig {
    container: string | HTMLElement;
    content?: TemplateContent;
    /**
     * Mount the editor inside a Shadow DOM (open mode) for CSS isolation
     * from the host page. Defaults to `true` — host stylesheets cannot
     * cascade past the shadow boundary into editor elements (`p`, `a`,
     * `input`, etc.), and editor utility classes never collide with host
     * class names.
     *
     * Set to `false` to mount in light DOM. Opt out when:
     *  - Your host integration uses `document.querySelector` to reach
     *    editor internals (with shadow DOM, use `container.shadowRoot
     *    .querySelector(...)` instead).
     *  - You need to support Firefox <101 or Safari <16.4, which lack the
     *    `adoptedStyleSheets` API the shadow path relies on.
     *
     * Light-mode consumers should keep this set to `false` explicitly so
     * future SDK changes don't silently flip the default again.
     *
     * @default true
     */
    shadowDom?: boolean;
    onChange?: (content: TemplateContent) => void;
    onSave?: (content: TemplateContent) => void;
    onError?: (error: Error) => void;
    onRequestMedia?: OnRequestMedia;
    mergeTags?: MergeTagsConfig;
    displayConditions?: DisplayConditionsConfig;
    customBlocks?: CustomBlockDefinition[];
    fonts?: FontsConfig;
    blockDefaults?: BlockDefaults;
    templateDefaults?: TemplateDefaults;
    theme?: ThemeOverrides;
    uiTheme?: UiTheme;
    locale?: string;
    /**
     * Show the "Powered by Templatical" footer. Defaults to `true`.
     * Set to `false` to hide the footer (no attribution required by the license).
     */
    branding?: boolean;
    /**
     * Template linter (`@templatical/quality`) configuration. Runs every
     * linter exported by the package (accessibility + structure).
     *
     * - When unset, the linter loads on demand once the user opens the panel.
     * - When `disabled: true`, the optional peer is never imported (saves the
     *   chunk download) and the sidebar tab + inline badges are suppressed.
     * - `rules`/`thresholds` follow the shape exported by `@templatical/quality`.
     */
    lint?: LintOptions;
}

export { ThemeOverrides }

export { UiTheme }

/**
 * Unmount the most-recently-created OSS editor. Single-instance legacy
 * API — callers managing multiple editors should use `instance.unmount()`
 * from each returned object, which targets the specific container.
 */
export declare function unmount(): void;

export declare function useFonts(config?: FontsConfig): UseFontsReturn;

export declare interface UseFontsReturn {
    fonts: ComputedRef<FontOption[]>;
    defaultFont: ComputedRef<string>;
    defaultFallback: ComputedRef<string>;
    customFonts: Ref<CustomFont[]>;
    customFontsEnabled: Ref<boolean>;
    isLoaded: Ref<boolean>;
    setCustomFontsEnabled: (enabled: boolean) => void;
    loadCustomFonts: () => Promise<void>;
    cleanupFontLinks: () => void;
    getFontWithFallback: (fontName: string) => string;
    getDefaultFont: () => string;
}

export { ViewportSize }

export { }
