/**
 * Dhwani Plugin SDK Declaration File
 * Provides auto-suggestions, typings, and intellisense in VS Code for Dhwani plugins.
 */

declare namespace DhwaniEditorSDK {
    /**
     * Base Tiptap Node class for building custom editor blocks.
     */
    export class Node {
        name: string;
        static create(config: {
            name: string;
            group?: "block" | "inline";
            content?: string;
            defining?: boolean;
            inline?: boolean;
            draggable?: boolean;
            parseHTML?(): { tag: string; getAttrs?: (node: any) => any }[];
            renderHTML?(props: { HTMLAttributes: Record<string, any> }): [string, any, ...any[]];
            addNodeView?(): any;
            addAttributes?(): Record<string, { default?: any; parseHTML?: (element: any) => any }>;
            addCommands?(): Record<string, (...args: any[]) => any>;
            [key: string]: any;
        }): any;
    }

    /**
     * Base Tiptap Mark class for styling text (e.g. bold, highlight).
     */
    export class Mark {
        name: string;
        static create(config: {
            name: string;
            parseHTML?(): { tag: string }[];
            renderHTML?(props: { HTMLAttributes: Record<string, any> }): [string, any, ...any[]];
            [key: string]: any;
        }): any;
    }

    /**
     * Base Tiptap Extension class for adding custom behaviors and commands.
     */
    export class Extension {
        name: string;
        static create(config: {
            name: string;
            addOptions?(): Record<string, any>;
            addCommands?(): Record<string, (...args: any[]) => any>;
            [key: string]: any;
        }): any;
    }

    /**
     * Merges HTML attributes safely during Tiptap rendering.
     */
    export function mergeAttributes(...attributes: Record<string, any>[]): Record<string, any>;

    /**
     * Renderer to map custom React components as Tiptap interactive node views.
     */
    export function ReactNodeViewRenderer(component: any, options?: { stopPropagation?: boolean }): any;

    /**
     * React component wrapper for custom Node Views (holds outer container bindings).
     */
    export const NodeViewWrapper: React.ComponentType<{
        className?: string;
        style?: React.CSSProperties;
        children?: React.ReactNode;
        [key: string]: any;
    }>;

    /**
     * React component placeholder for editable nested text blocks inside a custom Node View.
     */
    export const NodeViewContent: React.ComponentType<{
        className?: string;
        style?: React.CSSProperties;
        [key: string]: any;
    }>;
}

/**
 * Tiptap Editor interface wrapper.
 */
interface DhwaniTiptapEditor {
    /**
     * Starts a command chain transaction (e.g., editor.chain().focus().insertContent(...).run()).
     */
    chain(): DhwaniTiptapEditorChain;
    
    /**
     * Direct commands register.
     */
    commands: {
        /**
         * Sets text selection cursor at document index.
         */
        setTextSelection(position: number): boolean;
        [key: string]: any;
    };

    /**
     * Current editor ProseMirror state.
     */
    state: {
        selection: {
            from: number;
            to: number;
        };
    };
}

/**
 * Tiptap Command Chain Helper.
 */
interface DhwaniTiptapEditorChain {
    /**
     * Directs keyboard focus to the editor.
     */
    focus(): DhwaniTiptapEditorChain;

    /**
     * Inserts content (HTML markup, markdown, or node objects) at the cursor.
     */
    insertContent(content: string | Record<string, any>): DhwaniTiptapEditorChain;

    /**
     * Runs and executes the chained transactions.
     */
    run(): boolean;

    [key: string]: any;
}

/**
 * Registry configuration structure for custom Page Extensions.
 */
interface PageExtensionConfig {
    /**
     * Unique identifier matching the Tiptap node view name.
     */
    name: string;

    /**
     * Tiptap Node extension instance.
     */
    tiptapExtension: import("@tiptap/core").AnyExtension;

    /**
     * Slash commands registry configuration.
     */
    slashCommand: {
        /**
         * Heading title inside the dropdown.
         */
        title: string;

        /**
         * Sub-text details describing the action.
         */
        description: string;

        /**
         * Inline SVG markup string for the command icon.
         */
        icon: string;

        /**
         * Callback fired when selected from the dropdown list.
         */
        command: (editor: DhwaniTiptapEditor, range?: { from: number; to: number }) => void;
    };
}

/**
 * Response structure returned by makeHttpCall.
 */
interface DhwaniHttpResponse {
    status: number;
    statusText: string;
    headers: Record<string, string>;
    data: any;
}

/**
 * Scoped, pre-bound SDK instance returned to a plugin upon registration.
 */
interface DhwaniSDKInstance {
    api: {
        /**
         * Saves a file as a page attachment.
         * Requires the 'save_attachment' permission.
         * 
         * @param contentId ID of the current page/content
         * @param buffer File content as an ArrayBuffer
         * @param fileName Original name of the file
         * @returns Promise resolving to the saved attachment object
         */
        saveAttachment(
            contentId: string,
            buffer: ArrayBuffer,
            fileName: string
        ): Promise<{
            id: string;
            file_path: string;
            title: string;
            content_id: string;
        }>;

        /**
         * Deletes a saved page attachment.
         * Requires the 'delete_attachment' permission.
         * 
         * @param id ID of the attachment to delete
         */
        deleteAttachment(id: string): Promise<void>;

        /**
         * Retrieves the ID of the currently active page/content.
         * Does not require any permissions.
         * 
         * @returns The active content ID, or null if not in an active page context
         */
        getCurrentContentId(): string | null;

        /**
         * Retrieves the ID of the currently active notebook.
         * Does not require any permissions.
         * 
         * @returns The active note ID, or null if not in an active notebook context
         */
        getCurrentNoteId(): string | null;

        /**
         * Generates an HTML anchor link pointing to a project timeline.
         * Does not require any permissions.
         */
        getHTMLLinkForProjectId(title: string, projectId: string): string;

        /**
         * Generates an HTML anchor link pointing to a notebook.
         * Does not require any permissions.
         */
        getHTMLLinkForNoteId(title: string, noteId: string): string;

        /**
         * Generates an HTML anchor link pointing to a specific page or content within a notebook.
         * Does not require any permissions.
         */
        getHTMLLinkForNoteIdContentId(title: string, noteId: string, contentId: string): string;

        // ---- Note & Notebook Operations ----
        getAllNotes(): Promise<Array<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string }>>;
        getNoteById(noteId: string): Promise<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string } | null>;
        createNote(title: string, description: string): Promise<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string }>;
        updateNote(id: string, title: string, description: string): Promise<void>;
        updateNoteIcon(id: string, icon: string): Promise<void>;
        searchNoteByTitle(title: string): Promise<Array<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string }>>;
        deleteNoteById(noteId: string): Promise<void>;

        // ---- Content & Page Hierarchy Operations ----
        createContent(contentType: "page" | "chat" | "board" | "interact", title: string, noteId: string, parentContentId: string | null): Promise<{ id: string; noteId: string; title: string; type: "page"|"chat"|"board"|"interact"; parentId?: string; createdAt: string; updatedAt: string }>;
        updateContent(contentId: string, title: string): Promise<void>;
        deleteContent(contentId: string, noteId: string): Promise<void>;
        getContentTree(noteId: string): Promise<Array<any>>;
        searchContentByTitle(noteId: string, title: string): Promise<Array<{ id: string; type: string; title: string }>>;
        searchContentGlobally(title: string): Promise<Array<{ id: string; type: string; title: string; noteId: string; noteTitle: string }>>;
        getContentById(contentId: string): Promise<{ id: string; noteId: string; title: string; type: "page"|"chat"|"board"|"interact"; parentId?: string; createdAt: string; updatedAt: string } | null>;
        getAllContentsForNote(noteId: string): Promise<Array<{ id: string; noteId: string; title: string; type: "page"|"chat"|"board"|"interact"; parentId?: string; createdAt: string; updatedAt: string }>>;

        // ---- Content Body & Storage Operations ----
        getContentBody(contentId: string, type: "text" | "markdown" | "json" | "html"): Promise<{ contentId: string; type: string; body: string } | null>;
        createOrUpdateContentBody(contentId: string, type: "text" | "markdown" | "json" | "html", body: string): Promise<{ contentId: string; type: string; body: string }>;
        isContentBodyExists(contentId: string, type: "text" | "markdown" | "json" | "html"): Promise<boolean>;

        // ---- Custom Interact Key-Value Data Operations ----
        getInteractData(contentId: string, key: string): Promise<{ id: string; contentId: string; key: string; value: string | null } | null>;
        setInteractData(contentId: string, key: string, value: string): Promise<{ id: string; contentId: string; key: string; value: string }>;
        deleteInteractData(contentId: string, key: string): Promise<void>;
        getAllInteractData(contentId: string): Promise<Array<{ id: string; contentId: string; key: string; value: string }>>;

        // ---- Discussion Comments Operations ----
        getCommentsByContentId(contentId: string): Promise<Array<{ id: string; contentId: string; body: string; isResolved: boolean; creatorType: "user" | "ai"; parentCommentId?: string; createdAt: string }>>;
        createComment(contentId: string, body: string, creatorType: "user" | "ai", parentCommentId?: string | null): Promise<{ id: string; contentId: string; body: string; isResolved: boolean; creatorType: "user" | "ai"; parentCommentId?: string; createdAt: string }>;

        // ---- Projects & Timelines Operations ----
        getAllProjects(): Promise<Array<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string }>>;
        getProjectById(projectId: string): Promise<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string } | null>;
        createProject(title: string, description: string): Promise<{ id: string; title: string; description: string; icon: string; createdAt: string; updatedAt: string }>;
        getTasksByProjectId(projectId: string): Promise<Array<{ id: string; projectId: string; title: string; description: string; status: "NOT_STARTED"|"TODO"|"IN_PROGRESS"|"BLOCKED"|"DONE"; startDatetime?: string; endDatetime?: string }>>;
        createTask(projectId: string, title: string, description: string, status: "NOT_STARTED"|"TODO"|"IN_PROGRESS"|"BLOCKED"|"DONE", startDatetime?: string, endDatetime?: string): Promise<{ id: string; projectId: string; title: string; description: string; status: "NOT_STARTED"|"TODO"|"IN_PROGRESS"|"BLOCKED"|"DONE"; startDatetime?: string; endDatetime?: string }>;
        updateTaskStatus(id: string, status: "NOT_STARTED"|"TODO"|"IN_PROGRESS"|"BLOCKED"|"DONE"): Promise<void>;
        createTaskContentLink(taskId: string, contentId: string): Promise<void>;
        
        // ---- Plugin Settings Operations ----
        getSettings(): Promise<Record<string, any>>;
        setSettings(settingsValues: Record<string, any>): Promise<{ isSuccess: boolean; message: string }>;

        /**
         * Makes an HTTP request to an external service.
         * Requires the 'make_http_calls' permission.
         * 
         * @param url The target URL
         * @param method The HTTP method (GET, POST, PUT, DELETE, etc.)
         * @param options Optional headers, body, and query parameters
         * @param config Optional connectionTimeout and requestTimeout configurations (in milliseconds)
         */
        makeHttpCall(
            url: string,
            method: 'GET' | 'POST' | 'PUT' | 'DELETE' | string,
            options?: {
                headers?: Record<string, string>;
                body?: string;
                query?: Record<string, string>;
            },
            config?: {
                connectionTimeout?: number;
                requestTimeout?: number;
            }
        ): Promise<DhwaniHttpResponse | null>;
    };
}

declare namespace Dhwani {
    /**
     * Registers a custom page extension and slash command in the Dhwani editor workspace.
     * Returns a scoped, pre-bound SDK instance for the calling plugin.
     */
    export function registerPageExtension(config: PageExtensionConfig): DhwaniSDKInstance;
}

interface Window {
    DhwaniEditorSDK: typeof DhwaniEditorSDK;
    Dhwani: typeof Dhwani;
    DhwaniSDK: DhwaniSDKInstance;
    React: typeof import("react");
    ReactDOM: typeof import("react-dom");
}
