import { BaseSocialMediaAction, SocialPost, SocialAnalytics, MediaFile } from '../../base/base-social.action.js';
import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
export type BufferPostStatus = 'draft' | 'buffer' | 'sent' | 'failed' | 'canceled' | 'approved' | 'rejected';
export type BufferShareMode = 'addToQueue' | 'shareNext' | 'shareNow' | 'customScheduled';
export interface BufferChannel {
    id: string;
    name: string;
    service: string;
    displayName: string;
    avatar: string;
    isDisconnected: boolean;
    type: string;
    timezone: string;
    organizationId: string;
    createdAt: string;
    updatedAt: string;
    isQueuePaused: boolean;
    serviceId: string;
}
export interface BufferAssets {
    images?: Array<{
        url: string;
        thumbnailUrl?: string;
    }>;
    videos?: Array<{
        url: string;
        thumbnailUrl?: string;
    }>;
    documents?: Array<{
        url: string;
        title?: string;
    }>;
    link?: {
        url: string;
        title?: string;
        description?: string;
        thumbnailUrl?: string;
    };
}
export interface BufferPost {
    id: string;
    text: string;
    status: BufferPostStatus;
    dueAt: string | null;
    sentAt: string | null;
    createdAt: string;
    updatedAt: string;
    channelId: string;
    channelService: string;
    schedulingType: string;
    via: string;
    assets: BufferAssets | null;
    tags: Array<{
        id: string;
        name: string;
    }>;
}
interface BufferPageInfo {
    hasNextPage: boolean;
    endCursor: string | null;
}
interface BufferPostsConnection {
    edges: Array<{
        node: BufferPost;
    }>;
    pageInfo: BufferPageInfo;
    totalCount: number;
}
export declare class BufferGraphQLError extends Error {
    readonly Extensions?: Record<string, unknown>;
    constructor(message: string, extensions?: Record<string, unknown>);
}
/**
 * Base class for all Buffer social media actions.
 * Uses Buffer's GraphQL API at https://api.buffer.com.
 *
 * Migration note: replaces the deprecated v1 REST API at api.bufferapp.com/1.
 * Key concept renames: profiles → channels, updates → posts.
 */
export declare abstract class BufferBaseAction extends BaseSocialMediaAction {
    protected get platformName(): string;
    protected get apiBaseUrl(): string;
    /** Common params shared by all Buffer actions. */
    protected get bufferCommonParams(): ActionParam[];
    /**
     * Validate CompanyIntegrationID and initialize OAuth.
     *
     * Pass the full `RunActionParams` so the per-request provider on `params.Provider` is
     * threaded into `initializeOAuth` (multi-tenant correctness — every entity load/save
     * inside the OAuth flow binds to the request's connection, not the global default).
     *
     * Returns null on success, or an error result.
     */
    protected ensureAuthenticated(params: RunActionParams): Promise<ActionResultSimple | null>;
    /** Set an output parameter value by name. */
    protected setOutputParam(params: ActionParam[], name: string, value: unknown): void;
    /** Build a standardized error result from a caught exception. */
    protected buildErrorResult(error: unknown, verb: string, params: ActionParam[]): ActionResultSimple;
    /** Group posts by day using a date accessor. */
    protected groupPostsByDay(posts: SocialPost[], dateField: 'publishedAt' | 'scheduledFor'): Record<string, number>;
    /** Execute a GraphQL query or mutation against the Buffer API. */
    protected executeGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
    private throwOnGraphQLErrors;
    private handleExecutionError;
    /** Resolve org ID from params or by fetching the account's first org. */
    protected resolveOrganizationId(params: ActionParam[]): Promise<string>;
    /** Fetch all channels for an organization. */
    protected fetchChannels(organizationId: string): Promise<BufferChannel[]>;
    /** Fetch posts with optional filters and cursor-based pagination. */
    protected fetchPosts(organizationId: string, filters?: {
        channelIds?: string[];
        status?: BufferPostStatus;
        startDate?: string;
        endDate?: string;
        tags?: string[];
    }, first?: number, after?: string): Promise<BufferPostsConnection>;
    private buildPostsInput;
    /** Create a post via the createPost mutation. */
    protected createBufferPost(input: {
        channelId: string;
        text: string;
        mode?: BufferShareMode;
        dueAt?: string;
        schedulingType?: string;
        assets?: BufferAssets;
        tagIds?: string[];
    }): Promise<BufferPost>;
    /** Delete a post via the deletePost mutation. */
    protected deleteBufferPost(postId: string): Promise<boolean>;
    protected refreshAccessToken(): Promise<void>;
    protected uploadSingleMedia(_file: MediaFile): Promise<string>;
    protected searchPosts(params: {
        query?: string;
        hashtags?: string[];
        startDate?: Date;
        endDate?: Date;
        limit?: number;
        offset?: number;
        channelIds?: string[];
        organizationId?: string;
    }): Promise<SocialPost[]>;
    private buildSearchFilters;
    private collectSearchResults;
    /** Apply text/hashtag filters the GraphQL API doesn't support natively. */
    private applyClientSideFilters;
    protected normalizePost(bufferPost: BufferPost): SocialPost;
    private extractAssetUrls;
    protected normalizeAnalytics(bufferStats: Record<string, number>): SocialAnalytics;
    protected extractHashtags(content: string): string[];
    protected mapBufferError(error: unknown): string;
    private mapGraphQLErrorCode;
    private mapHttpStatusCode;
}
export {};
//# sourceMappingURL=buffer-base.action.d.ts.map