var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
import { ToolBubble } from '../../../../types/tool-bubble-class.js';
import { AIFallbackStep } from '../_shared/ai/ai-fallback-step.js';
import { BrowserBaseBubble, } from '../../../service-bubble/browserbase/index.js';
import { CredentialType } from '@bubblelab/shared-schemas';
import { z } from 'zod';
import { parseBrowserSessionData, buildProxyConfig } from '../_shared/utils.js';
import { LinkedInSentInvitationsToolParamsSchema, LinkedInSentInvitationsToolResultSchema, SentInvitationInfoSchema, } from './schema.js';
let LinkedInSentInvitationsTool = (() => {
    let _classSuper = ToolBubble;
    let _instanceExtraInitializers = [];
    let _stepNavigateToSentInvitations_decorators;
    let _stepWaitForInvitationsPage_decorators;
    let _stepExtractInvitations_decorators;
    return class LinkedInSentInvitationsTool extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _stepNavigateToSentInvitations_decorators = [AIFallbackStep('Navigate to sent invitations', {
                    taskDescription: 'Navigate to the LinkedIn sent invitations page',
                })];
            _stepWaitForInvitationsPage_decorators = [AIFallbackStep('Wait for invitations to load', {
                    taskDescription: 'Wait for the sent invitations list to load',
                })];
            _stepExtractInvitations_decorators = [AIFallbackStep('Extract sent invitations', {
                    taskDescription: 'Extract all sent connection invitations',
                    extractionSchema: z.array(SentInvitationInfoSchema),
                })];
            __esDecorate(this, null, _stepNavigateToSentInvitations_decorators, { kind: "method", name: "stepNavigateToSentInvitations", static: false, private: false, access: { has: obj => "stepNavigateToSentInvitations" in obj, get: obj => obj.stepNavigateToSentInvitations }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _stepWaitForInvitationsPage_decorators, { kind: "method", name: "stepWaitForInvitationsPage", static: false, private: false, access: { has: obj => "stepWaitForInvitationsPage" in obj, get: obj => obj.stepWaitForInvitationsPage }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _stepExtractInvitations_decorators, { kind: "method", name: "stepExtractInvitations", static: false, private: false, access: { has: obj => "stepExtractInvitations" in obj, get: obj => obj.stepExtractInvitations }, metadata: _metadata }, null, _instanceExtraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static bubbleName = 'linkedin-sent-invitations-tool';
        static schema = LinkedInSentInvitationsToolParamsSchema;
        static resultSchema = LinkedInSentInvitationsToolResultSchema;
        static shortDescription = 'Extract sent LinkedIn connection invitations';
        static longDescription = 'Recordable LinkedIn Sent Invitations Tool for extracting pending sent connection requests.';
        static alias = 'linkedin-sent-invitations';
        static type = 'tool';
        sessionId = (__runInitializers(this, _instanceExtraInitializers), null);
        contextId = null;
        cookies = null;
        constructor(params = { operation: 'get_sent_invitations' }, context) {
            super(params, context);
        }
        chooseCredential() {
            const { credentials } = this.params;
            return credentials?.[CredentialType.LINKEDIN_CRED];
        }
        async stepStartBrowserSession() {
            if (this.sessionId)
                return;
            const sessionData = parseBrowserSessionData(this.chooseCredential());
            if (sessionData) {
                this.contextId = sessionData.contextId;
                this.cookies = sessionData.cookies;
            }
            const proxyConfig = buildProxyConfig(this.params.proxy);
            const browserbase = new BrowserBaseBubble({
                operation: 'start_session',
                context_id: this.contextId || undefined,
                cookies: this.cookies || undefined,
                credentials: this.params.credentials,
                stealth: { solveCaptchas: true },
                ...proxyConfig,
            }, this.context, 'startsession');
            const result = await browserbase.action();
            if (!result.data.success || !result.data.session_id) {
                throw new Error(result.data.error || 'Failed to start browser session');
            }
            this.sessionId = result.data.session_id;
            if (result.data.context_id)
                this.contextId = result.data.context_id;
            console.log(`[RecordableSentInvitations] Session started: ${this.sessionId}`);
            const ip = await this.detectIPAddress();
            if (ip)
                console.log(`[RecordableSentInvitations] Browser IP: ${ip}`);
        }
        async stepNavigateToSentInvitations() {
            if (!this.sessionId)
                throw new Error('No active session');
            const browserbase = new BrowserBaseBubble({
                operation: 'navigate',
                session_id: this.sessionId,
                url: 'https://www.linkedin.com/mynetwork/invitation-manager/sent/',
                wait_until: 'domcontentloaded',
                timeout: 30000,
            }, this.context, 'navigate');
            const result = await browserbase.action();
            if (!result.data.success)
                throw new Error(result.data.error || 'Navigation failed');
        }
        async stepWaitForInvitationsPage() {
            const checkScript = `(() => {
      const buttons = document.querySelectorAll('button');
      let sentTabFound = false, hasInvitations = false;
      for (const btn of buttons) {
        const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
        if (text === 'sent') sentTabFound = true;
        if (text === 'withdraw') hasInvitations = true;
      }
      const peopleLabel = document.body.innerText.match(/People\\s*\\(\\d+\\)/i);
      return sentTabFound && (hasInvitations || peopleLabel);
    })()`;
            for (let attempt = 1; attempt <= 15; attempt++) {
                const found = await this.evaluate(checkScript);
                if (found)
                    return true;
                await new Promise((r) => setTimeout(r, 1000));
            }
            return false;
        }
        async stepExtractInvitations() {
            const result = (await this.evaluate(`
      (() => {
        const invitations = [];
        const withdrawButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
          (btn.innerText || btn.textContent || '').trim().toLowerCase() === 'withdraw'
        );
        for (const withdrawBtn of withdrawButtons) {
          let container = withdrawBtn.parentElement;
          for (let i = 0; i < 10 && container; i++) {
            const text = container.innerText || '';
            if (text.includes('Sent') && container.querySelector('a[href*="/in/"]')) break;
            container = container.parentElement;
          }
          if (!container) continue;
          let name = '';
          const links = container.querySelectorAll('a[href*="/in/"]');
          for (const link of links) {
            const linkText = (link.innerText || link.textContent || '').trim();
            if (linkText && linkText.length > 1 && linkText.length < 100 && !linkText.includes('Sent')) {
              name = linkText;
              break;
            }
          }
          if (!name) {
            const spans = container.querySelectorAll('span');
            for (const span of spans) {
              const spanText = (span.innerText || span.textContent || '').trim();
              if (spanText && spanText.length > 2 && spanText.length < 50 &&
                  !spanText.includes('Sent') && !spanText.includes('Withdraw') &&
                  !spanText.includes('|') && !spanText.includes('-')) {
                name = spanText;
                break;
              }
            }
          }
          const containerText = container.innerText || '';
          const lines = containerText.split('\\n').map(l => l.trim()).filter(l => l);
          let headline = '';
          let nameLineIdx = -1, sentLineIdx = -1;
          for (let i = 0; i < lines.length; i++) {
            if (lines[i] === name) nameLineIdx = i;
            if (lines[i].match(/^Sent\\s+\\d+/i)) sentLineIdx = i;
          }
          if (nameLineIdx >= 0 && sentLineIdx > nameLineIdx + 1) {
            headline = lines.slice(nameLineIdx + 1, sentLineIdx)
              .filter(l => l.toLowerCase() !== 'withdraw' && l.length > 5)
              .join(' ').trim();
          }
          if (!headline) {
            for (const line of lines) {
              if (line === name || line.toLowerCase() === 'withdraw' ||
                  line.match(/^Sent\\s+\\d+/i) || line.match(/^People\\s*\\(/i)) continue;
              if (line.length > 10 && line.length < 300) { headline = line; break; }
            }
          }
          const sentMatch = containerText.match(/Sent\\s+\\d+\\s+\\w+\\s+ago/i);
          let profile_url = '';
          for (const link of links) {
            const href = link.getAttribute('href') || '';
            if (href.includes('/in/')) {
              profile_url = href.startsWith('http') ? href : 'https://www.linkedin.com' + href;
              break;
            }
          }
          if (name) {
            invitations.push({
              name,
              headline: headline || undefined,
              sent_date: sentMatch ? sentMatch[0] : 'Unknown',
              profile_url: profile_url || undefined,
            });
          }
        }
        let total = invitations.length;
        const peopleMatch = document.body.innerText.match(/People\\s*\\((\\d+)\\)/i);
        if (peopleMatch) total = parseInt(peopleMatch[1], 10);
        return { invitations, total };
      })()
    `));
            return result;
        }
        async stepEndBrowserSession() {
            if (!this.sessionId)
                return;
            const browserbase = new BrowserBaseBubble({ operation: 'end_session', session_id: this.sessionId }, this.context, 'endsession');
            await browserbase.action();
            console.log(`[RecordableSentInvitations] Session ended: ${this.sessionId}`);
            this.sessionId = null;
        }
        async evaluate(script) {
            if (!this.sessionId)
                throw new Error('No active session');
            const browserbase = new BrowserBaseBubble({ operation: 'evaluate', session_id: this.sessionId, script }, this.context, 'evaluate');
            const result = await browserbase.action();
            if (!result.data.success)
                throw new Error(result.data.error || 'Evaluation failed');
            return result.data.result;
        }
        async detectIPAddress() {
            if (!this.sessionId)
                return null;
            try {
                return (await this.evaluate(`
        (async () => {
          try {
            const r = await fetch('https://api.ipify.org?format=json');
            const d = await r.json();
            return d.ip;
          } catch { return null; }
        })()
      `));
            }
            catch {
                return null;
            }
        }
        async performAction() {
            try {
                await this.stepStartBrowserSession();
                await this.stepNavigateToSentInvitations();
                const pageReady = await this.stepWaitForInvitationsPage();
                if (!pageReady)
                    console.log('[RecordableSentInvitations] Page slow to load, continuing');
                const { invitations, total } = await this.stepExtractInvitations();
                return {
                    operation: 'get_sent_invitations',
                    success: true,
                    invitations,
                    total_count: total,
                    message: `Found ${invitations.length} sent invitations`,
                    error: '',
                };
            }
            catch (error) {
                return {
                    operation: 'get_sent_invitations',
                    success: false,
                    error: error instanceof Error ? error.message : 'Unknown error',
                };
            }
            finally {
                await this.stepEndBrowserSession();
            }
        }
    };
})();
export { LinkedInSentInvitationsTool };
//# sourceMappingURL=tool.js.map