/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/lib/email/emailTemplateService.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
/**
 * Email Template Service — Multi-tenant
 *
 * Hierarquia de resolução:
 *   1. Override do terapeuta (owner_id + key, no schema do tenant)
 *   2. Override do tenant    (key, sem owner_id, no schema do tenant)
 *   3. Template global       (key, is_active = true)
 *
 * Merging inteligente: campos null no override herdam do global,
 * permitindo sobrescrever só o subject sem reescrever o body.
 */

import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { MOCK_DATA } from './emailTemplateConstants';

// ─────────────────────────────────────────────
// QUERIES SUPABASE
// ─────────────────────────────────────────────

async function _fetchGlobalTemplate(key) {
    const { data, error } = await supabase.from('email_templates_global').select('*').eq('key', key).eq('is_active', true).single();

    if (error && error.code !== 'PGRST116') {
        console.error('[EmailTemplates] Erro ao buscar global:', error);
    }
    return data ?? null;
}

async function _fetchAllGlobalTemplates() {
    const { data, error } = await supabase.from('email_templates_global').select('*').eq('is_active', true).order('domain');

    if (error) console.error('[EmailTemplates] Erro ao listar globais:', error);
    return data ?? [];
}

/**
 * Busca override de tenant/owner para uma key.
 * Se ownerId fornecido: prioriza override do owner; fallback para tenant geral.
 * Se não: busca só o override do tenant (owner_id IS NULL).
 */
async function _fetchTenantTemplate(tenantId, ownerId, key) {
    let query = tenantDb().from('email_templates_tenant').select('*').eq('template_key', key).eq('enabled', true);

    if (ownerId) {
        // Retorna até 2 linhas: a do owner e a do tenant geral
        // Ordena owner_id DESC NULLS LAST → owner primeiro
        query = query.or(`owner_id.eq.${ownerId},owner_id.is.null`).order('owner_id', { nullsFirst: false }).limit(1);
    } else {
        query = query.is('owner_id', null).limit(1);
    }

    const { data, error } = await query.maybeSingle();
    if (error) console.error('[EmailTemplates] Erro ao buscar tenant override:', error);
    return data ?? null;
}

// ─────────────────────────────────────────────
// MERGE & FALLBACK
// ─────────────────────────────────────────────

function _mergeTemplates(global, override) {
    return {
        ...global,
        subject: override.subject ?? global.subject,
        body_html: override.body_html ?? global.body_html,
        body_text: override.body_text ?? global.body_text,
        _source: override.subject || override.body_html ? 'tenant' : 'global',
        _synced_version: override.synced_version,
        _global_version: global.version,
        _needs_sync: override.synced_version !== null && override.synced_version < global.version
    };
}

function _fallbackTemplate(key) {
    return {
        id: null,
        key,
        domain: 'system',
        channel: 'email',
        subject: `[${key}] Notificação do sistema`,
        body_html: '<p>Você recebeu uma notificação do sistema.</p>',
        body_text: 'Você recebeu uma notificação do sistema.',
        version: 1,
        is_active: true,
        variables: {},
        _source: 'fallback'
    };
}

// ─────────────────────────────────────────────
// RENDERER
// ─────────────────────────────────────────────

/**
 * Resolve uma variável com suporte a notação de ponto (patient.name).
 */
function _resolveVariable(key, variables) {
    if (!key.includes('.')) return variables[key];
    return key.split('.').reduce((obj, part) => obj?.[part], variables);
}

/**
 * Renderiza um template substituindo {{variavel}} e blocos {{#if}}.
 *
 * @param {string} template
 * @param {Object} variables
 * @returns {string}
 */
export function renderTemplate(template, variables = {}) {
    if (!template) return '';

    let result = template;

    // Blocos condicionais {{#if var}}...{{/if}}
    result = result.replace(/\{\{#if\s+([\w.]+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, key, content) => (_resolveVariable(key, variables) ? content : ''));

    // Substituições simples {{variavel}}
    result = result.replace(/\{\{([\w.]+)\}\}/g, (_, key) => {
        const value = _resolveVariable(key, variables);
        return value !== undefined && value !== null ? String(value) : '';
    });

    return result;
}

function _stripHtml(html) {
    return html
        .replace(/<br\s*\/?>/gi, '\n')
        .replace(/<\/p>/gi, '\n')
        .replace(/<[^>]+>/g, '')
        .replace(/\n{3,}/g, '\n\n')
        .trim();
}

// ─────────────────────────────────────────────
// LAYOUT — Header / Footer gerado por config
// ─────────────────────────────────────────────

/**
 * Gera o HTML inline de header ou footer a partir da config do tenant.
 * Usa <table> para máxima compatibilidade com clientes de e-mail.
 *
 * @param {Object}  config   - { enabled, show_logo, logo_position, text, text_align }
 * @param {string|null} logoUrl
 * @param {boolean} isHeader - true = header, false = footer
 * @returns {string}
 */
export function generateLayoutSection(config, logoUrl, isHeader = true) {
    if (!config?.enabled) return '';

    const borderStyle = isHeader ? 'border-bottom:2px solid #e5e7eb;padding-bottom:16px;margin-bottom:20px;' : 'border-top:1px solid #e5e7eb;padding-top:16px;margin-top:20px;';

    const layout = config.layout || null;
    const text = config.content?.trim() || '';

    if (!layout && !text) return '';

    const logoImg = logoUrl ? `<img src="${logoUrl}" style="max-width:90px;max-height:56px;object-fit:contain;display:block;">` : '';

    let inner = '';

    if (layout === 'logo-left') {
        inner = `<table width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
      <tr>
        <td style="width:106px;vertical-align:middle;padding-right:16px;">${logoImg}</td>
        <td style="vertical-align:middle;">${text}</td>
      </tr>
    </table>`;
    } else if (layout === 'logo-right') {
        inner = `<table width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
      <tr>
        <td style="vertical-align:middle;">${text}</td>
        <td style="width:106px;vertical-align:middle;padding-left:16px;text-align:right;">${logoImg}</td>
      </tr>
    </table>`;
    } else if (layout === 'logo-center') {
        const centeredImg = logoUrl ? `<img src="${logoUrl}" style="max-width:90px;max-height:56px;object-fit:contain;display:inline-block;">` : '';
        inner = `<div style="text-align:center;">${centeredImg}<div style="margin-top:8px;">${text}</div></div>`;
    } else if (layout === 'text-left') {
        inner = `<div style="text-align:left;">${text}</div>`;
    } else if (layout === 'text-center') {
        inner = `<div style="text-align:center;">${text}</div>`;
    } else if (layout === 'text-right') {
        inner = `<div style="text-align:right;">${text}</div>`;
    } else {
        inner = text;
    }

    if (!inner.trim()) return '';
    return `<div style="${borderStyle}">${inner}</div>`;
}

/**
 * Renderiza subject e ambos os bodies de um template resolvido.
 *
 * @param {Object} resolvedTemplate
 * @param {Object} variables
 * @param {Object} [options]        - { headerConfig, footerConfig, logoUrl }
 * @returns {{ subject: string, body_html: string, body_text: string }}
 */
export function renderEmail(resolvedTemplate, variables = {}, options = {}) {
    const { headerConfig, footerConfig, logoUrl } = options;

    const headerHtml = generateLayoutSection(headerConfig, logoUrl, true);
    const footerHtml = generateLayoutSection(footerConfig, logoUrl, false);
    const body_html = renderTemplate(resolvedTemplate.body_html, variables);
    const full_html = headerHtml + body_html + footerHtml;

    return {
        subject: renderTemplate(resolvedTemplate.subject, variables),
        body_html: full_html,
        body_text: resolvedTemplate.body_text ? renderTemplate(resolvedTemplate.body_text, variables) : _stripHtml(full_html)
    };
}

// ─────────────────────────────────────────────
// API PÚBLICA
// ─────────────────────────────────────────────

/**
 * Resolve o template correto para um contexto de tenant/owner.
 *
 * @param {string} templateKey  - TEMPLATE_KEYS.*
 * @param {{ tenantId?: string, ownerId?: string }} [context]
 * @returns {Promise<Object>}
 */
export async function getEmailTemplate(templateKey, context = {}) {
    const { tenantId = null, ownerId = null } = context;

    const global = await _fetchGlobalTemplate(templateKey);

    if (!global) {
        console.warn(`[EmailTemplates] Template não encontrado: ${templateKey}`);
        return _fallbackTemplate(templateKey);
    }

    if (!tenantId) return { ...global, _source: 'global' };

    // Busca override (owner tem prioridade sobre tenant geral)
    const tenantOverride = await _fetchTenantTemplate(tenantId, ownerId, templateKey);

    if (!tenantOverride) return { ...global, _source: 'global' };

    return _mergeTemplates(global, tenantOverride);
}

/**
 * Retorna dados mock para um template key (baseado no domínio).
 */
function _getMockDataForKey(templateKey) {
    if (templateKey.startsWith('session') || templateKey.startsWith('scheduler')) return MOCK_DATA.session;
    if (templateKey.startsWith('intake')) return MOCK_DATA.intake;
    return MOCK_DATA.system;
}

/**
 * Gera preview renderizado com dados mockados.
 * Uso principal: tela de edição de templates na UI do terapeuta.
 *
 * @param {string} templateKey
 * @param {Object} [mockData]   - substitui campos do mock padrão
 * @param {Object} [context]    - { tenantId, ownerId }
 * @returns {Promise<{ subject, body_html, body_text, _meta }>}
 */
export async function previewTemplate(templateKey, mockData = {}, context = {}) {
    const template = await getEmailTemplate(templateKey, context);
    const variables = { ..._getMockDataForKey(templateKey), ...mockData };
    const rendered = renderEmail(template, variables);

    return {
        ...rendered,
        _meta: {
            key: templateKey,
            source: template._source || 'global',
            version: template.version,
            needs_sync: template._needs_sync || false,
            variables_used: Object.keys(variables)
        }
    };
}

/**
 * Lista todos os templates globais com status de override por contexto.
 * Útil para a tela de gerenciamento de templates na UI do terapeuta.
 *
 * @param {Object} [context] - { tenantId, ownerId }
 * @returns {Promise<Array>}
 */
export async function listTemplates(context = {}) {
    const globals = await _fetchAllGlobalTemplates();

    return Promise.all(
        globals.map(async (global) => {
            const resolved = await getEmailTemplate(global.key, context);
            return {
                key: global.key,
                domain: global.domain,
                channel: global.channel,
                version: global.version,
                is_active: global.is_active,
                variables: global.variables,
                has_override: resolved._source === 'tenant',
                needs_sync: resolved._needs_sync || false
            };
        })
    );
}
