import { CredentialType } from '@bubblelab/shared-schemas';
import { ServiceBubble } from '../../../types/service-bubble-class.js';
import { PosthogParamsSchema, PosthogResultSchema, } from './posthog.schema.js';
/**
 * PosthogBubble - Integration with PostHog product analytics
 *
 * Provides read operations for retrieving analytics data from PostHog:
 * - List events with filtering by event type, person, and date range
 * - Execute HogQL queries for custom analytics
 * - Look up person profiles and properties
 * - Retrieve saved insight results
 *
 * @example
 * ```typescript
 * // List recent pageview events
 * const result = await new PosthogBubble({
 *   operation: 'list_events',
 *   project_id: '12345',
 *   event: '$pageview',
 *   limit: 50,
 * }).action();
 *
 * // Execute a HogQL query
 * const queryResult = await new PosthogBubble({
 *   operation: 'query',
 *   project_id: '12345',
 *   query: 'SELECT event, count() FROM events GROUP BY event ORDER BY count() DESC LIMIT 10',
 * }).action();
 *
 * // Look up a person by distinct ID
 * const person = await new PosthogBubble({
 *   operation: 'get_person',
 *   project_id: '12345',
 *   distinct_id: 'user_123',
 * }).action();
 * ```
 */
export class PosthogBubble extends ServiceBubble {
    // REQUIRED: Static metadata for BubbleFactory
    static service = 'posthog';
    static authType = 'apikey';
    static bubbleName = 'posthog';
    static type = 'service';
    static schema = PosthogParamsSchema;
    static resultSchema = PosthogResultSchema;
    static shortDescription = 'PostHog product analytics for events, persons, and insights';
    static longDescription = `
    PostHog is an open-source product analytics platform.
    This bubble provides read operations for retrieving analytics data:
    - List and filter captured events (pageviews, custom events, etc.)
    - Execute HogQL queries for advanced custom analytics
    - Look up person profiles and their properties
    - Retrieve saved insight results

    Authentication:
    - Uses a Personal API Key via Bearer token
    - Supports US Cloud, EU Cloud, and self-hosted instances via configurable host URL

    Use Cases:
    - Pull analytics data into automated workflows
    - Query event data with HogQL for custom reports
    - Look up user profiles and their properties
    - Retrieve computed insight results for dashboards
  `;
    static alias = 'posthog-analytics';
    constructor(params = {
        operation: 'list_events',
        project_id: '',
        limit: 100,
    }, context) {
        super(params, context);
    }
    /**
     * Choose the appropriate credential for PostHog API
     */
    chooseCredential() {
        const params = this.params;
        const credentials = params.credentials;
        if (!credentials || typeof credentials !== 'object') {
            return undefined;
        }
        return credentials[CredentialType.POSTHOG_API_KEY];
    }
    /**
     * Test if the credential is valid by listing projects
     */
    async testCredential() {
        const apiKey = this.chooseCredential();
        if (!apiKey) {
            return false;
        }
        const params = this.params;
        const host = params.host || 'https://us.posthog.com';
        // Use the /api/users/@me endpoint to validate the key
        const response = await fetch(`${host}/api/users/@me/`, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${apiKey}`,
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorText = await response.text().catch(() => '');
            throw new Error(`PostHog API key validation failed (${response.status}): ${errorText}`);
        }
        return true;
    }
    /**
     * Perform the PostHog operation
     */
    async performAction(context) {
        void context;
        const params = this.params;
        const { operation } = params;
        try {
            switch (operation) {
                case 'list_projects':
                    return (await this.listProjects(params));
                case 'list_events':
                    return (await this.listEvents(params));
                case 'query':
                    return (await this.executeQuery(params));
                case 'get_person':
                    return (await this.getPerson(params));
                case 'get_insight':
                    return (await this.getInsight(params));
                default:
                    throw new Error(`Unknown operation: ${operation}`);
            }
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
            return {
                operation,
                success: false,
                error: errorMessage,
            };
        }
    }
    /**
     * Make an authenticated GET request to the PostHog API
     */
    async makePosthogGetRequest(host, path, queryParams) {
        const apiKey = this.chooseCredential();
        if (!apiKey) {
            throw new Error('PostHog Personal API Key is required');
        }
        const url = new URL(`${host}${path}`);
        if (queryParams) {
            for (const [key, value] of Object.entries(queryParams)) {
                if (value !== undefined && value !== '') {
                    url.searchParams.set(key, value);
                }
            }
        }
        const response = await fetch(url.toString(), {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${apiKey}`,
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorText = await response.text();
            let errorMessage;
            try {
                const errorData = JSON.parse(errorText);
                errorMessage =
                    errorData.detail || errorData.error || errorData.message || errorText;
            }
            catch {
                errorMessage = errorText;
            }
            throw new Error(`PostHog API error (HTTP ${response.status}): ${errorMessage}`);
        }
        return (await response.json());
    }
    /**
     * Make an authenticated POST request to the PostHog API
     */
    async makePosthogPostRequest(host, path, body) {
        const apiKey = this.chooseCredential();
        if (!apiKey) {
            throw new Error('PostHog Personal API Key is required');
        }
        const response = await fetch(`${host}${path}`, {
            method: 'POST',
            headers: {
                Authorization: `Bearer ${apiKey}`,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(body),
        });
        if (!response.ok) {
            const errorText = await response.text();
            let errorMessage;
            try {
                const errorData = JSON.parse(errorText);
                errorMessage =
                    errorData.detail || errorData.error || errorData.message || errorText;
            }
            catch {
                errorMessage = errorText;
            }
            throw new Error(`PostHog API error (HTTP ${response.status}): ${errorMessage}`);
        }
        return (await response.json());
    }
    /**
     * List all projects accessible with the API key
     */
    async listProjects(params) {
        const queryParams = {};
        if (params.limit !== undefined)
            queryParams.limit = String(params.limit);
        const response = await this.makePosthogGetRequest(params.host, '/api/projects/', queryParams);
        return {
            operation: 'list_projects',
            success: true,
            projects: response.results,
            next: response.next,
            error: '',
        };
    }
    /**
     * List events with optional filtering
     */
    async listEvents(params) {
        const queryParams = {};
        if (params.event)
            queryParams.event = params.event;
        if (params.person_id)
            queryParams.person_id = params.person_id;
        if (params.distinct_id)
            queryParams.distinct_id = params.distinct_id;
        if (params.after)
            queryParams.after = params.after;
        if (params.before)
            queryParams.before = params.before;
        if (params.properties)
            queryParams.properties = params.properties;
        if (params.limit !== undefined)
            queryParams.limit = String(params.limit);
        const response = await this.makePosthogGetRequest(params.host, `/api/projects/${params.project_id}/events/`, queryParams);
        return {
            operation: 'list_events',
            success: true,
            events: response.results,
            next: response.next,
            error: '',
        };
    }
    /**
     * Execute a HogQL query
     */
    async executeQuery(params) {
        const response = await this.makePosthogPostRequest(params.host, `/api/projects/${params.project_id}/query/`, {
            query: {
                kind: 'HogQLQuery',
                query: params.query,
            },
        });
        // The response may have nested results structure
        const results = response.results;
        return {
            operation: 'query',
            success: true,
            columns: (results?.columns || response.columns),
            results: (results?.results || response.results),
            types: (results?.types || response.types),
            hasMore: (results?.hasMore || response.hasMore),
            error: '',
        };
    }
    /**
     * Get person profiles
     */
    async getPerson(params) {
        const queryParams = {};
        if (params.distinct_id)
            queryParams.distinct_id = params.distinct_id;
        if (params.search)
            queryParams.search = params.search;
        if (params.limit !== undefined)
            queryParams.limit = String(params.limit);
        const response = await this.makePosthogGetRequest(params.host, `/api/projects/${params.project_id}/persons/`, queryParams);
        return {
            operation: 'get_person',
            success: true,
            persons: response.results,
            next: response.next,
            error: '',
        };
    }
    /**
     * Get a saved insight's results
     */
    async getInsight(params) {
        const response = await this.makePosthogGetRequest(params.host, `/api/projects/${params.project_id}/insights/${params.insight_id}/`);
        return {
            operation: 'get_insight',
            success: true,
            insight: response,
            error: '',
        };
    }
}
//# sourceMappingURL=posthog.js.map