import { ServiceBubble } from '../../../types/service-bubble-class.js';
import { CredentialType } from '@bubblelab/shared-schemas';
import { SendSafelyParamsSchema, SendSafelyResultSchema, } from './sendsafely.schema.js';
import { parseSendSafelyCredential, createClient, verifyCredentials, createPackage, addRecipients, encryptAndUploadFile, encryptMessage, saveMessage, finalizePackage, updatePackage, getPackageInfo, } from './sendsafely.utils.js';
/**
 * SendSafely Service Bubble
 *
 * Encrypted file transfer and secure messaging via SendSafely.
 * Uses the official @sendsafely/sendsafely SDK (v3).
 *
 * Features:
 * - Send encrypted files to recipients via secure links
 * - Send encrypted messages via secure links
 * - Retrieve package information
 *
 * Use cases:
 * - Share sensitive documents securely with external parties
 * - Send encrypted messages through automated workflows
 * - Integrate encrypted file transfer into BubbleFlow pipelines
 *
 * Security Features:
 * - End-to-end encryption via SendSafely SDK
 * - Multi-field credential storage (host + apiKey + apiSecret)
 * - Input validation with Zod schemas
 */
export class SendSafelyBubble extends ServiceBubble {
    static type = 'service';
    static service = 'sendsafely';
    static authType = 'apikey';
    static bubbleName = 'sendsafely';
    static schema = SendSafelyParamsSchema;
    static resultSchema = SendSafelyResultSchema;
    static shortDescription = 'Encrypted file transfer and secure messaging via SendSafely';
    static longDescription = `
    SendSafely integration for encrypted file transfer and secure messaging.
    Uses the official SendSafely SDK with end-to-end encryption.

    Features:
    - Send encrypted files to recipients via secure links
    - Send encrypted messages via secure links
    - Retrieve package information

    Use cases:
    - Share sensitive documents securely with external parties
    - Send encrypted messages through automated workflows
    - Integrate encrypted file transfer into BubbleFlow pipelines

    Security Features:
    - End-to-end encryption via SendSafely SDK
    - Multi-field credential (host + API key + API secret)
    - Input validation with Zod schemas
  `;
    static alias = 'encrypted-transfer';
    constructor(params = {
        operation: 'get_package',
        package_id: '',
    }, context) {
        super(params, context);
    }
    async testCredential() {
        const credential = this.chooseCredential();
        if (!credential) {
            return false;
        }
        try {
            const creds = parseSendSafelyCredential(credential);
            const client = createClient(creds);
            await verifyCredentials(client);
            return true;
        }
        catch {
            return false;
        }
    }
    async performAction(context) {
        void context;
        const { operation } = this.params;
        try {
            const result = await (async () => {
                const parsedParams = this.params;
                switch (operation) {
                    case 'send_file':
                        return await this.sendFile(parsedParams);
                    case 'send_message':
                        return await this.sendMessage(parsedParams);
                    case 'get_package':
                        return await this.getPackage(parsedParams);
                    default:
                        throw new Error(`Unsupported operation: ${operation}`);
                }
            })();
            return result;
        }
        catch (error) {
            return {
                operation,
                success: false,
                error: error instanceof Error ? error.message : 'Unknown error occurred',
            };
        }
    }
    // ============================================================================
    // SEND FILE
    // ============================================================================
    async sendFile(params) {
        const credential = this.chooseCredential();
        if (!credential) {
            throw new Error('SendSafely credentials are required');
        }
        const creds = parseSendSafelyCredential(credential);
        const client = createClient(creds);
        // 1. Verify credentials
        await verifyCredentials(client);
        // 2. Create a package
        const pkg = await createPackage(client);
        // 3. Set expiration if specified
        if (params.lifeDays !== undefined) {
            await updatePackage(client, pkg.packageId, { life: params.lifeDays });
        }
        // 4. Add recipient(s)
        await addRecipients(client, pkg.packageId, params.recipientEmail);
        // 5. Encrypt and upload file
        const fileBuffer = Buffer.from(params.fileData, 'base64');
        await encryptAndUploadFile(client, pkg.packageId, pkg.keyCode, pkg.serverSecret, params.fileName, fileBuffer);
        // 6. Optionally add a message
        if (params.message) {
            const encrypted = await encryptMessage(client, pkg.packageId, pkg.keyCode, pkg.serverSecret, params.message);
            await saveMessage(client, pkg.packageId, encrypted);
        }
        // 7. Finalize (encrypts keycodes for recipients and triggers notification)
        const secureLink = await finalizePackage(client, pkg.packageId, pkg.packageCode, pkg.keyCode);
        return {
            operation: 'send_file',
            success: true,
            packageId: pkg.packageId,
            secureLink,
            error: '',
        };
    }
    // ============================================================================
    // SEND MESSAGE
    // ============================================================================
    async sendMessage(params) {
        const credential = this.chooseCredential();
        if (!credential) {
            throw new Error('SendSafely credentials are required');
        }
        const creds = parseSendSafelyCredential(credential);
        const client = createClient(creds);
        // 1. Verify credentials
        await verifyCredentials(client);
        // 2. Create a package
        const pkg = await createPackage(client);
        // 3. Set expiration if specified
        if (params.lifeDays !== undefined) {
            await updatePackage(client, pkg.packageId, { life: params.lifeDays });
        }
        // 4. Add recipient(s)
        await addRecipients(client, pkg.packageId, params.recipientEmail);
        // 5. Encrypt message and save to server
        const encrypted = await encryptMessage(client, pkg.packageId, pkg.keyCode, pkg.serverSecret, params.message);
        await saveMessage(client, pkg.packageId, encrypted);
        // 6. Finalize (encrypts keycodes for recipients and triggers notification)
        const secureLink = await finalizePackage(client, pkg.packageId, pkg.packageCode, pkg.keyCode);
        return {
            operation: 'send_message',
            success: true,
            packageId: pkg.packageId,
            secureLink,
            error: '',
        };
    }
    // ============================================================================
    // GET PACKAGE
    // ============================================================================
    async getPackage(params) {
        const credential = this.chooseCredential();
        if (!credential) {
            throw new Error('SendSafely credentials are required');
        }
        const creds = parseSendSafelyCredential(credential);
        const client = createClient(creds);
        await verifyCredentials(client);
        const info = await getPackageInfo(client, params.package_id);
        return {
            operation: 'get_package',
            success: true,
            package: {
                packageId: info.packageId || params.package_id,
                packageCode: info.packageCode,
                serverSecret: info.serverSecret,
                recipients: info.recipients,
                files: Array.isArray(info.files)
                    ? info.files.map((f) => ({
                        fileId: String(f.fileId),
                        fileName: String(f.fileName),
                        fileSize: f.fileSize != null ? Number(f.fileSize) : undefined,
                    }))
                    : undefined,
                state: info.state,
                life: info.life,
                secureLink: info.secureLink,
            },
            error: '',
        };
    }
    // ============================================================================
    // CREDENTIAL MANAGEMENT
    // ============================================================================
    chooseCredential() {
        const { credentials } = this.params;
        if (!credentials || typeof credentials !== 'object') {
            return undefined;
        }
        return credentials[CredentialType.SENDSAFELY_CRED];
    }
}
//# sourceMappingURL=sendsafely.js.map