"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var AiService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AiService = void 0;
const api_prisma_1 = require("@hed-hog/api-prisma");
const common_1 = require("@nestjs/common");
const axios_1 = __importDefault(require("axios"));
const crypto_1 = require("crypto");
const pdf_parse_1 = __importDefault(require("pdf-parse"));
const file_service_1 = require("../file/file.service");
const integration_developer_api_service_1 = require("../integration/services/integration-developer-api.service");
const setting_service_1 = require("../setting/setting.service");
let AiService = AiService_1 = class AiService {
    constructor(prismaService, settingService, fileService, integrationApi) {
        this.prismaService = prismaService;
        this.settingService = settingService;
        this.fileService = fileService;
        this.integrationApi = integrationApi;
        this.logger = new common_1.Logger(AiService_1.name);
    }
    onModuleInit() {
        this.integrationApi.subscribe({
            eventName: 'core.setting.changed',
            consumerName: 'core.ai-provider-key-validator',
            priority: 0,
            handler: async (event) => {
                var _a;
                const slug = String(((_a = event.payload) === null || _a === void 0 ? void 0 : _a.slug) || '').trim();
                if (!this.isAiProviderKeySlug(slug)) {
                    return;
                }
                await this.syncProviderEnabledFlag(slug);
            },
        });
        void this.syncAllProviderEnabledFlags();
    }
    async chat(data, file) {
        const provider = data.provider || 'openai';
        const attachment = await this.resolveAttachment(file, data.file_id);
        if (provider === 'openai') {
            const model = data.model || 'gpt-4o-mini';
            const content = await this.chatWithOpenAi({
                message: data.message,
                model,
                systemPrompt: data.systemPrompt,
                attachment,
            });
            return {
                provider,
                model,
                content,
            };
        }
        const model = data.model || 'gemini-1.5-flash';
        const content = await this.chatWithGemini({
            message: data.message,
            model,
            systemPrompt: data.systemPrompt,
            attachment,
        });
        return {
            provider,
            model,
            content,
        };
    }
    async createAgent(data) {
        var _a;
        const slug = data.slug.trim();
        const provider = data.provider || 'openai';
        const model = data.model || this.getDefaultModel(provider);
        const instructions = ((_a = data.instructions) === null || _a === void 0 ? void 0 : _a.trim()) || null;
        const existing = await this.findAgentBySlug(slug);
        if (existing) {
            return existing;
        }
        let externalAgentId = null;
        if (provider === 'openai') {
            externalAgentId = await this.createOpenAiAssistant({
                slug,
                model,
                instructions,
            });
        }
        await this.prismaService.$executeRaw `
      INSERT INTO ai_agent (slug, provider, model, instructions, external_agent_id)
      VALUES (
        ${slug},
        CAST(${provider} AS ai_agent_provider_enum),
        ${model},
        ${instructions},
        ${externalAgentId}
      )
    `;
        return this.findAgentBySlug(slug);
    }
    async listAgents(paginationParams) {
        var _a;
        const page = Math.max(Number((paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.page) || 1), 1);
        const pageSize = Math.min(Math.max(Number((paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.pageSize) || 10), 1), 100);
        const offset = (page - 1) * pageSize;
        const search = String((paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.search) || '').trim();
        const whereClause = search
            ? api_prisma_1.Prisma.sql `WHERE LOWER(slug) LIKE LOWER(${`%${search}%`})`
            : api_prisma_1.Prisma.empty;
        const data = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
      SELECT id, slug, provider, model, instructions, external_agent_id, created_at, updated_at
      FROM ai_agent
      ${whereClause}
      ORDER BY id DESC
      LIMIT ${pageSize}
      OFFSET ${offset}
    `);
        const totalResult = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
      SELECT COUNT(*) AS total
      FROM ai_agent
      ${whereClause}
    `);
        const total = Number(((_a = totalResult === null || totalResult === void 0 ? void 0 : totalResult[0]) === null || _a === void 0 ? void 0 : _a.total) || 0);
        return {
            data,
            total,
            page,
            pageSize,
            totalPages: Math.ceil(total / pageSize),
        };
    }
    async getAgentById(agentId) {
        const agent = await this.findAgentById(agentId);
        if (!agent) {
            throw new common_1.NotFoundException(`AI agent with id "${agentId}" was not found.`);
        }
        return agent;
    }
    async updateAgent(agentId, data) {
        var _a, _b, _c, _d, _e, _f;
        const currentAgent = await this.findAgentById(agentId);
        if (!currentAgent) {
            throw new common_1.NotFoundException(`AI agent with id "${agentId}" was not found.`);
        }
        const slug = (_b = (_a = data.slug) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : currentAgent.slug;
        const provider = (_c = data.provider) !== null && _c !== void 0 ? _c : currentAgent.provider;
        const model = (_e = (_d = data.model) !== null && _d !== void 0 ? _d : currentAgent.model) !== null && _e !== void 0 ? _e : this.getDefaultModel(provider);
        const instructions = (_f = data.instructions) !== null && _f !== void 0 ? _f : currentAgent.instructions;
        if (slug !== currentAgent.slug) {
            const existingSlug = await this.findAgentBySlug(slug);
            if (existingSlug && existingSlug.id !== agentId) {
                throw new common_1.BadRequestException(`AI agent with slug "${slug}" already exists.`);
            }
        }
        let externalAgentId = currentAgent.external_agent_id;
        if (provider !== 'openai') {
            externalAgentId = null;
        }
        else if (!externalAgentId) {
            externalAgentId = await this.createOpenAiAssistant({
                slug,
                model,
                instructions,
            });
        }
        await this.prismaService.$executeRaw `
      UPDATE ai_agent
      SET slug = ${slug},
          provider = CAST(${provider} AS ai_agent_provider_enum),
          model = ${model},
          instructions = ${instructions},
          external_agent_id = ${externalAgentId},
          updated_at = NOW()
      WHERE id = ${agentId}
    `;
        return this.getAgentById(agentId);
    }
    async deleteAgents({ ids }) {
        const existing = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
      SELECT id
      FROM ai_agent
      WHERE id IN (${api_prisma_1.Prisma.join(ids)})
    `);
        if (existing.length !== ids.length) {
            const existingIds = existing.map((item) => item.id);
            const missingIds = ids.filter((id) => !existingIds.includes(id));
            throw new common_1.NotFoundException(`AI agents with ids "${missingIds.join(', ')}" were not found.`);
        }
        const deletedCount = await this.prismaService.$executeRaw `
      DELETE FROM ai_agent
      WHERE id IN (${api_prisma_1.Prisma.join(ids)})
    `;
        return {
            count: Number(deletedCount || 0),
        };
    }
    async chatWithAgent(slug, data, file) {
        const agent = await this.findAgentBySlug(slug);
        const attachment = await this.resolveAttachment(file, data.file_id);
        if (!agent) {
            throw new common_1.NotFoundException(`AI agent with slug "${slug}" was not found.`);
        }
        if (agent.provider === 'openai') {
            if (agent.external_agent_id && !attachment) {
                const content = await this.chatWithOpenAiAssistant(agent.external_agent_id, data.message);
                return {
                    slug: agent.slug,
                    provider: agent.provider,
                    model: agent.model,
                    content,
                };
            }
            const content = await this.chatWithOpenAi({
                message: data.message,
                model: agent.model || this.getDefaultModel('openai'),
                systemPrompt: agent.instructions || undefined,
                attachment,
            });
            return {
                slug: agent.slug,
                provider: agent.provider,
                model: agent.model,
                content,
            };
        }
        const content = await this.chatWithGemini({
            message: data.message,
            model: agent.model || this.getDefaultModel('gemini'),
            systemPrompt: agent.instructions || undefined,
            attachment,
        });
        return {
            slug: agent.slug,
            provider: agent.provider,
            model: agent.model,
            content,
        };
    }
    async getAgentBySlug(slug) {
        const agent = await this.findAgentBySlug(slug);
        if (!agent) {
            throw new common_1.NotFoundException(`AI agent with slug "${slug}" was not found.`);
        }
        return agent;
    }
    async extractAttachmentText(file, fileId) {
        const attachment = await this.resolveAttachment(file, fileId);
        if (!attachment) {
            return '';
        }
        if (this.isPdfMime(attachment.mimeType)) {
            return this.extractPdfText(attachment.buffer);
        }
        if (this.isTextMime(attachment.mimeType)) {
            return this.toUtf8Text(attachment.buffer);
        }
        return '';
    }
    async debugAttachmentForLlm(file, fileId) {
        const attachment = await this.resolveAttachment(file, fileId);
        if (!attachment) {
            return {
                hasAttachment: false,
                filename: '',
                mimeType: '',
                bytes: 0,
                mode: 'binary',
                textLength: 0,
                textSample: '',
                sha256: '',
            };
        }
        let mode = 'binary';
        let extractedText = '';
        if (this.isImageMime(attachment.mimeType)) {
            mode = 'image';
        }
        else if (this.isPdfMime(attachment.mimeType)) {
            mode = 'pdf-text';
            extractedText = await this.extractPdfText(attachment.buffer);
        }
        else if (this.isTextMime(attachment.mimeType)) {
            mode = 'text';
            extractedText = this.toUtf8Text(attachment.buffer);
        }
        const result = {
            hasAttachment: true,
            filename: attachment.filename,
            mimeType: attachment.mimeType,
            bytes: attachment.buffer.length,
            mode,
            textLength: extractedText.length,
            textSample: extractedText.slice(0, 600),
            sha256: (0, crypto_1.createHash)('sha256').update(attachment.buffer).digest('hex'),
        };
        this.logger.warn(`[AI-ATTACHMENT-DEBUG] fileId=${fileId || 'upload'} filename="${result.filename}" mime=${result.mimeType} mode=${result.mode} bytes=${result.bytes} textLength=${result.textLength}`);
        return result;
    }
    async findAgentBySlug(slug) {
        const result = await this.prismaService.$queryRaw `
      SELECT id, slug, provider, model, instructions, external_agent_id, created_at, updated_at
      FROM ai_agent
      WHERE slug = ${slug}
      LIMIT 1
    `;
        return (result === null || result === void 0 ? void 0 : result[0]) || null;
    }
    async findAgentById(id) {
        const result = await this.prismaService.$queryRaw `
      SELECT id, slug, provider, model, instructions, external_agent_id, created_at, updated_at
      FROM ai_agent
      WHERE id = ${id}
      LIMIT 1
    `;
        return (result === null || result === void 0 ? void 0 : result[0]) || null;
    }
    getDefaultModel(provider) {
        if (provider === 'openai') {
            return 'gpt-4o-mini';
        }
        return 'gemini-1.5-flash';
    }
    isAiProviderKeySlug(slug) {
        return slug === 'ai-openai-api-key' || slug === 'ai-gemini-api-key';
    }
    getEnabledSlugFromProviderKey(slug) {
        return slug === 'ai-openai-api-key'
            ? 'ai-openai-api-key-enabled'
            : 'ai-gemini-api-key-enabled';
    }
    async syncAllProviderEnabledFlags() {
        const results = await Promise.allSettled([
            this.syncProviderEnabledFlag('ai-openai-api-key'),
            this.syncProviderEnabledFlag('ai-gemini-api-key'),
        ]);
        results.forEach((result, index) => {
            if (result.status === 'rejected') {
                const slug = index === 0 ? 'ai-openai-api-key' : 'ai-gemini-api-key';
                this.logger.warn(`Failed to sync provider availability for ${slug}: ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`);
            }
        });
    }
    async syncProviderEnabledFlag(slug) {
        const values = await this.settingService.getSettingValues(slug);
        const apiKey = String((values === null || values === void 0 ? void 0 : values[slug]) || '').trim();
        const enabledSlug = this.getEnabledSlugFromProviderKey(slug);
        const isValid = slug === 'ai-openai-api-key'
            ? await this.validateOpenAiKey(apiKey)
            : await this.validateGeminiKey(apiKey);
        await this.settingService.setValue(enabledSlug, isValid ? 'true' : 'false');
    }
    getValidationErrorMessage(error) {
        var _a, _b, _c, _d, _e, _f;
        if (axios_1.default.isAxiosError(error)) {
            const providerMessage = ((_c = (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message) ||
                ((_e = (_d = error.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.message) ||
                error.message;
            const status = ((_f = error.response) === null || _f === void 0 ? void 0 : _f.status) || 'network';
            return `${status}: ${providerMessage}`;
        }
        return error instanceof Error ? error.message : String(error);
    }
    async validateOpenAiKey(apiKey) {
        const normalizedKey = String(apiKey || '').trim();
        if (!normalizedKey) {
            return false;
        }
        try {
            await axios_1.default.get('https://api.openai.com/v1/models', {
                headers: {
                    Authorization: `Bearer ${normalizedKey}`,
                },
                params: {
                    limit: 1,
                },
                timeout: 5000,
            });
            return true;
        }
        catch (error) {
            this.logger.warn(`OpenAI key validation failed: ${this.getValidationErrorMessage(error)}`);
            return false;
        }
    }
    async validateGeminiKey(apiKey) {
        const normalizedKey = String(apiKey || '').trim();
        if (!normalizedKey) {
            return false;
        }
        try {
            await axios_1.default.get('https://generativelanguage.googleapis.com/v1beta/models', {
                params: {
                    key: normalizedKey,
                    pageSize: 1,
                },
                timeout: 5000,
            });
            return true;
        }
        catch (error) {
            this.logger.warn(`Gemini key validation failed: ${this.getValidationErrorMessage(error)}`);
            return false;
        }
    }
    async getApiKeys() {
        const settings = await this.settingService.getSettingValues([
            'ai-openai-api-key',
            'ai-gemini-api-key',
        ]);
        return {
            openai: settings['ai-openai-api-key'],
            gemini: settings['ai-gemini-api-key'],
        };
    }
    async chatWithOpenAi({ message, model, systemPrompt, attachment, }) {
        var _a, _b, _c, _d;
        const { openai } = await this.getApiKeys();
        if (!openai) {
            throw new common_1.BadRequestException('OpenAI API key is not configured (setting "ai-openai-api-key").');
        }
        const messages = [];
        if (systemPrompt) {
            messages.push({ role: 'system', content: systemPrompt });
        }
        const userContent = await this.buildOpenAiUserContent(message, attachment);
        messages.push({ role: 'user', content: userContent });
        const response = await axios_1.default.post('https://api.openai.com/v1/chat/completions', {
            model,
            messages,
        }, {
            headers: {
                Authorization: `Bearer ${openai}`,
                'Content-Type': 'application/json',
            },
        });
        return ((_d = (_c = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.choices) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) === null || _d === void 0 ? void 0 : _d.content) || '';
    }
    async createOpenAiAssistant({ slug, model, instructions, }) {
        var _a;
        const { openai } = await this.getApiKeys();
        if (!openai) {
            throw new common_1.BadRequestException('OpenAI API key is not configured (setting "ai-openai-api-key").');
        }
        const response = await axios_1.default.post('https://api.openai.com/v1/assistants', {
            name: slug,
            model,
            instructions: instructions || `You are the assistant identified by slug ${slug}.`,
        }, {
            headers: {
                Authorization: `Bearer ${openai}`,
                'Content-Type': 'application/json',
                'OpenAI-Beta': 'assistants=v2',
            },
        });
        const assistantId = (_a = response.data) === null || _a === void 0 ? void 0 : _a.id;
        if (!assistantId) {
            throw new common_1.BadRequestException('OpenAI assistant creation failed.');
        }
        return assistantId;
    }
    async chatWithOpenAiAssistant(assistantId, message) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        const { openai } = await this.getApiKeys();
        if (!openai) {
            throw new common_1.BadRequestException('OpenAI API key is not configured (setting "ai-openai-api-key").');
        }
        const threadResponse = await axios_1.default.post('https://api.openai.com/v1/threads', {
            messages: [{ role: 'user', content: message }],
        }, {
            headers: {
                Authorization: `Bearer ${openai}`,
                'Content-Type': 'application/json',
                'OpenAI-Beta': 'assistants=v2',
            },
        });
        const threadId = (_a = threadResponse.data) === null || _a === void 0 ? void 0 : _a.id;
        if (!threadId) {
            throw new common_1.BadRequestException('OpenAI thread creation failed.');
        }
        const runResponse = await axios_1.default.post(`https://api.openai.com/v1/threads/${threadId}/runs`, {
            assistant_id: assistantId,
        }, {
            headers: {
                Authorization: `Bearer ${openai}`,
                'Content-Type': 'application/json',
                'OpenAI-Beta': 'assistants=v2',
            },
        });
        const runId = (_b = runResponse.data) === null || _b === void 0 ? void 0 : _b.id;
        if (!runId) {
            throw new common_1.BadRequestException('OpenAI assistant run failed to start.');
        }
        for (let i = 0; i < 30; i++) {
            const runStatusResponse = await axios_1.default.get(`https://api.openai.com/v1/threads/${threadId}/runs/${runId}`, {
                headers: {
                    Authorization: `Bearer ${openai}`,
                    'OpenAI-Beta': 'assistants=v2',
                },
            });
            const status = (_c = runStatusResponse.data) === null || _c === void 0 ? void 0 : _c.status;
            if (status === 'completed') {
                break;
            }
            if (['cancelled', 'failed', 'expired'].includes(status)) {
                throw new common_1.BadRequestException(`OpenAI assistant run did not complete successfully (status: ${status}).`);
            }
            await this.sleep(1000);
        }
        const messagesResponse = await axios_1.default.get(`https://api.openai.com/v1/threads/${threadId}/messages`, {
            headers: {
                Authorization: `Bearer ${openai}`,
                'OpenAI-Beta': 'assistants=v2',
            },
        });
        const assistantMessage = (_e = (_d = messagesResponse.data) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.find((item) => item.role === 'assistant');
        const output = (_h = (_g = (_f = assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.content) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.text) === null || _h === void 0 ? void 0 : _h.value;
        return output || '';
    }
    async chatWithGemini({ message, model, systemPrompt, attachment, }) {
        var _a, _b, _c, _d;
        const { gemini } = await this.getApiKeys();
        if (!gemini) {
            throw new common_1.BadRequestException('Gemini API key is not configured (setting "ai-gemini-api-key").');
        }
        const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${gemini}`;
        const userParts = [{ text: message }];
        if (attachment) {
            if (this.isTextMime(attachment.mimeType)) {
                userParts.push({
                    text: `\n\n[Attached file: ${attachment.filename}]\n${this.toUtf8Text(attachment.buffer)}`,
                });
            }
            else if (this.isPdfMime(attachment.mimeType)) {
                const pdfText = await this.extractPdfText(attachment.buffer);
                if (pdfText) {
                    userParts.push({
                        text: `\n\n[Attached file: ${attachment.filename}]\n${pdfText}`,
                    });
                }
                else {
                    userParts.push({
                        inline_data: {
                            mime_type: attachment.mimeType,
                            data: attachment.buffer.toString('base64'),
                        },
                    });
                }
            }
            else {
                userParts.push({
                    inline_data: {
                        mime_type: attachment.mimeType,
                        data: attachment.buffer.toString('base64'),
                    },
                });
            }
        }
        const payload = {
            contents: [{ parts: userParts }],
        };
        if (systemPrompt) {
            payload.systemInstruction = {
                parts: [{ text: systemPrompt }],
            };
        }
        const response = await axios_1.default.post(url, payload, {
            headers: {
                'Content-Type': 'application/json',
            },
        });
        const parts = ((_d = (_c = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.candidates) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.parts) || [];
        return parts.map((part) => part.text || '').join('');
    }
    async sleep(ms) {
        await new Promise((resolve) => setTimeout(resolve, ms));
    }
    async resolveAttachment(uploadFile, fileId) {
        var _a;
        if (uploadFile) {
            const mimeType = this.normalizeAttachmentMimeType(uploadFile.mimetype, uploadFile.originalname);
            return {
                filename: uploadFile.originalname,
                mimeType,
                buffer: uploadFile.buffer,
            };
        }
        if (fileId) {
            const { file, buffer } = await this.fileService.getBuffer(fileId);
            const mimeType = this.normalizeAttachmentMimeType(((_a = file.file_mimetype) === null || _a === void 0 ? void 0 : _a.name) || 'application/octet-stream', file.filename);
            return {
                filename: file.filename,
                mimeType,
                buffer,
            };
        }
        return null;
    }
    async buildOpenAiUserContent(message, attachment) {
        if (!attachment) {
            return message;
        }
        if (this.isImageMime(attachment.mimeType)) {
            const dataUri = `data:${attachment.mimeType};base64,${attachment.buffer.toString('base64')}`;
            return [
                { type: 'text', text: message },
                { type: 'image_url', image_url: { url: dataUri } },
            ];
        }
        let text;
        if (this.isTextMime(attachment.mimeType)) {
            text = this.toUtf8Text(attachment.buffer);
        }
        else if (this.isPdfMime(attachment.mimeType)) {
            text =
                (await this.extractPdfText(attachment.buffer)) ||
                    `[PDF attachment with unreadable text: ${attachment.filename}]`;
        }
        else {
            text = `[Binary attachment: ${attachment.filename} | ${attachment.mimeType} | ${attachment.buffer.length} bytes]`;
        }
        return `${message}\n\n[Attached file: ${attachment.filename}]\n${text}`;
    }
    isImageMime(mimeType) {
        return mimeType.startsWith('image/');
    }
    isTextMime(mimeType) {
        return (mimeType.startsWith('text/') ||
            mimeType === 'application/json' ||
            mimeType === 'application/xml');
    }
    isPdfMime(mimeType) {
        return (mimeType === 'application/pdf' ||
            mimeType === 'application/x-pdf' ||
            mimeType.endsWith('/pdf'));
    }
    normalizeAttachmentMimeType(mimeType, filename) {
        const current = (mimeType || '').toLowerCase();
        if (current && current !== 'application/octet-stream') {
            return current;
        }
        const name = (filename || '').toLowerCase();
        if (name.endsWith('.pdf'))
            return 'application/pdf';
        if (name.endsWith('.json'))
            return 'application/json';
        if (name.endsWith('.xml'))
            return 'application/xml';
        if (name.endsWith('.txt') || name.endsWith('.csv'))
            return 'text/plain';
        if (name.endsWith('.png'))
            return 'image/png';
        if (name.endsWith('.jpg') || name.endsWith('.jpeg'))
            return 'image/jpeg';
        if (name.endsWith('.webp'))
            return 'image/webp';
        return current || 'application/octet-stream';
    }
    async extractPdfText(buffer) {
        try {
            const result = await (0, pdf_parse_1.default)(buffer);
            const text = ((result === null || result === void 0 ? void 0 : result.text) || '')
                .replace(/\r/g, '')
                .replace(/[ \t]+\n/g, '\n')
                .replace(/\n{3,}/g, '\n\n')
                .trim();
            if (!text) {
                return '';
            }
            return text.slice(0, 60000);
        }
        catch (_a) {
            return '';
        }
    }
    toUtf8Text(buffer) {
        return buffer.toString('utf8');
    }
};
exports.AiService = AiService;
exports.AiService = AiService = AiService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),
    __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => setting_service_1.SettingService))),
    __param(2, (0, common_1.Inject)((0, common_1.forwardRef)(() => file_service_1.FileService))),
    __param(3, (0, common_1.Inject)((0, common_1.forwardRef)(() => integration_developer_api_service_1.IntegrationDeveloperApiService))),
    __metadata("design:paramtypes", [api_prisma_1.PrismaService,
        setting_service_1.SettingService,
        file_service_1.FileService,
        integration_developer_api_service_1.IntegrationDeveloperApiService])
], AiService);
//# sourceMappingURL=ai.service.js.map