"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ALL_TOOL_NAMES = exports.BUILTIN_TOOLS = void 0;
exports.resolveTools = resolveTools;
// ── Helpers ────────────────────────────────────────────────────────────────────
function fmtDate(d) {
    return d.toISOString().split('T')[0];
}
// ── Tools ──────────────────────────────────────────────────────────────────────
exports.BUILTIN_TOOLS = [
    // ── listar_horarios ──────────────────────────────────────────────────────────
    {
        name: 'listar_horarios',
        description: 'Lista os horários disponíveis na agenda para agendamento. ' +
            'Use antes de propor datas ao cliente. ' +
            'Se não informar a data, retorna os próximos 7 dias.',
        parameters: {
            type: 'object',
            properties: {
                data: {
                    type: 'string',
                    description: 'Data no formato YYYY-MM-DD. Opcional — padrão: próximos 7 dias.',
                },
            },
        },
        async execute(args, ctx) {
            const from = args['data'] ?? fmtDate(new Date());
            const to = args['data'] ?? fmtDate(new Date(Date.now() + 7 * 86400000));
            const slots = await ctx.db('sec_calendar')
                .where('status', 'available')
                .whereBetween('date', [from, to])
                .orderBy('date').orderBy('time_start')
                .limit(20);
            if (!slots.length) {
                return { disponivel: false, mensagem: 'Nenhum horário disponível no período informado.' };
            }
            return {
                disponivel: true,
                horarios: slots.map(s => ({
                    id: s.id,
                    data: s.date,
                    inicio: String(s.time_start).slice(0, 5),
                    fim: String(s.time_end).slice(0, 5),
                    titulo: s.title,
                })),
            };
        },
    },
    // ── agendar_horario ──────────────────────────────────────────────────────────
    {
        name: 'agendar_horario',
        description: 'Reserva um horário disponível na agenda para o cliente. ' +
            'Use listar_horarios primeiro para obter o slot_id correto.',
        parameters: {
            type: 'object',
            properties: {
                slot_id: { type: 'string', description: 'ID do horário retornado por listar_horarios.' },
                nome_cliente: { type: 'string', description: 'Nome completo do cliente.' },
                telefone_cliente: { type: 'string', description: 'Telefone do cliente (opcional).' },
            },
            required: ['slot_id', 'nome_cliente'],
        },
        async execute(args, ctx) {
            const slot = await ctx.db('sec_calendar')
                .where({ id: args['slot_id'], status: 'available' })
                .first();
            if (!slot) {
                return { ok: false, erro: 'Horário não encontrado ou já reservado. Chame listar_horarios novamente.' };
            }
            await ctx.db('sec_calendar').where({ id: args['slot_id'] }).update({
                status: 'booked',
                attendee_name: args['nome_cliente'],
                attendee_phone: args['telefone_cliente'] ?? null,
                updated_at: new Date(),
            });
            return {
                ok: true,
                confirmacao: {
                    data: slot.date,
                    inicio: String(slot.time_start).slice(0, 5),
                    fim: String(slot.time_end).slice(0, 5),
                    titulo: slot.title,
                    nome: args['nome_cliente'],
                },
            };
        },
    },
    // ── escalar_humano ───────────────────────────────────────────────────────────
    {
        name: 'escalar_humano',
        description: 'Transfere o atendimento para um atendente humano quando a situação exige. ' +
            'Use quando: cliente pede explicitamente, problema financeiro sensível, raiva intensa, ' +
            'ou quando você não consegue resolver após tentativas honestas.',
        parameters: {
            type: 'object',
            properties: {
                motivo: {
                    type: 'string',
                    description: 'Motivo da transferência (ex: "cliente insatisfeito com cobrança").',
                },
            },
        },
        async execute(args, ctx) {
            await ctx.db('sec_conversations').where({ id: ctx.conversationId }).update({
                handoff_mode: 'humano',
                handoff_human_at: new Date(),
                status: 'escalated',
            });
            const conv = await ctx.db('sec_conversations').where({ id: ctx.conversationId }).first();
            if (ctx.hooks && ctx.tenantId && ctx.extChatId) {
                const chatId = ctx.extChatId.includes(':')
                    ? ctx.extChatId.split(':').slice(1).join(':')
                    : ctx.extChatId;
                const payload = {
                    tenantId: ctx.tenantId,
                    conversationId: ctx.conversationId,
                    chatId,
                    protocolNumber: conv?.protocol_number ?? '',
                    motivo: args['motivo'] ?? '',
                };
                ctx.hooks.emit('ext:handoff', { ...payload, mode: 'humano', reason: 'escalation' }).catch(() => { });
                ctx.hooks.emit('ext:escalated', payload).catch(() => { });
            }
            return { ok: true, escalado: true, motivo: args['motivo'] ?? 'Solicitado pelo sistema' };
        },
    },
    // ── encerrar_protocolo ───────────────────────────────────────────────────────
    {
        name: 'encerrar_protocolo',
        description: 'Encerra o protocolo de atendimento após resolver o problema do cliente. ' +
            'Use apenas quando tiver certeza de que tudo foi resolvido.',
        parameters: {
            type: 'object',
            properties: {
                resumo: {
                    type: 'string',
                    description: 'Breve resumo do que foi tratado e resolvido neste atendimento.',
                },
            },
            required: ['resumo'],
        },
        async execute(args, ctx) {
            const summary = args['resumo'] ?? 'Atendimento encerrado.';
            const conv = await ctx.db('sec_conversations').where({ id: ctx.conversationId }).first();
            await ctx.db('sec_conversations').where({ id: ctx.conversationId }).update({
                status: 'closed',
                summary,
                updated_at: new Date(),
            });
            await ctx.db('sec_messages').where({ conversation_id: ctx.conversationId }).delete();
            return { ok: true, protocolo: conv?.protocol_number ?? '', resumo: summary };
        },
    },
];
function resolveTools(names) {
    return names
        .map(n => exports.BUILTIN_TOOLS.find(t => t.name === n))
        .filter((t) => t !== undefined);
}
exports.ALL_TOOL_NAMES = exports.BUILTIN_TOOLS.map(t => t.name);
