/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/services/subscriptionIntents.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/
import { supabase } from '@/lib/supabase/client';

// --------------------------------------
// Helpers
// --------------------------------------
function applyFilters(query, { q, status, planKey, interval }) {
    if (q) query = query.ilike('email', `%${q}%`);
    if (status) query = query.eq('status', status);
    if (planKey) query = query.eq('plan_key', planKey);
    if (interval) query = query.eq('interval', interval);
    return query;
}

function getWriteTableByTarget(planTarget) {
    const t = String(planTarget || '').toLowerCase();
    if (t === 'clinic') return 'subscription_intents_tenant';
    if (t === 'therapist') return 'subscription_intents_personal';
    return null;
}

async function fetchIntentFromView(intentId) {
    const { data, error } = await supabase
        .from('subscription_intents') // ✅ VIEW (read)
        .select('*')
        .eq('id', intentId)
        .maybeSingle();

    if (error) throw error;
    if (!data) throw new Error('Intenção não encontrada.');
    return data;
}

// --------------------------------------
// Public API
// --------------------------------------
export async function listSubscriptionIntents(filters = {}) {
    let query = supabase
        .from('subscription_intents') // ✅ VIEW
        .select('*')
        .order('created_at', { ascending: false });

    query = applyFilters(query, filters);

    const { data, error } = await query;
    if (error) throw error;
    return data || [];
}

/**
 * Busca a assinatura mais recente coerente com a intenção.
 * Não depende de subscription_id existir.
 *
 * opts:
 *  - strictPlanKey (default true): filtra por plan_key (evita pegar plano errado)
 *  - onlyActive (default false): se true, busca somente status 'active'
 */
export async function findLatestSubscriptionForIntent(intentOrId, opts = {}) {
    const { strictPlanKey = true, onlyActive = false } = opts;

    const intent = typeof intentOrId === 'string' ? await fetchIntentFromView(intentOrId) : intentOrId;

    const target = String(intent?.plan_target || '').toLowerCase();
    const planKey = intent?.plan_key || null;
    const intentUserId = intent?.user_id || intent?.created_by_user_id || null;
    const tenantId = intent?.tenant_id || null;

    let query = supabase.from('subscriptions').select('*').order('created_at', { ascending: false }).limit(1);

    if (onlyActive) query = query.eq('status', 'active');

    if (target === 'clinic') {
        if (!tenantId) throw new Error('Intenção clinic sem tenant_id.');
        query = query.eq('tenant_id', tenantId);
        if (strictPlanKey && planKey) query = query.eq('plan_key', planKey);
    } else if (target === 'therapist') {
        if (!intentUserId) throw new Error('Intenção therapist sem user_id.');
        query = query.eq('user_id', intentUserId).is('tenant_id', null);
        if (strictPlanKey && planKey) query = query.eq('plan_key', planKey);
    } else {
        throw new Error('plan_target inválido na intenção (esperado clinic/therapist).');
    }

    const { data, error } = await query.maybeSingle();
    if (error) throw error;
    return data || null;
}

/**
 * Retorna a assinatura para uma intenção:
 * 1) se existir intent.subscription_id, tenta carregar ela
 * 2) fallback: busca a mais recente coerente com o target
 */
export async function getSubscriptionForIntent(intentOrId, opts = {}) {
    const intent = typeof intentOrId === 'string' ? await fetchIntentFromView(intentOrId) : intentOrId;

    const subId = intent?.subscription_id || null;
    if (subId) {
        const { data, error } = await supabase.from('subscriptions').select('*').eq('id', subId).maybeSingle();
        if (error) throw error;
        if (data?.id) return data;
    }

    return await findLatestSubscriptionForIntent(intent, opts);
}

export async function markIntentPaid(intentId, notes = '') {
    // 0) pega intenção na VIEW (pra descobrir plan_target e validar estado)
    const intent = await fetchIntentFromView(intentId);

    if (intent.status === 'paid') {
        // idempotente: ainda tenta ativar a subscription a partir do intent (caso tenha falhado antes)
        const { data: sub, error: rpcErr } = await supabase.rpc('activate_subscription_from_intent', {
            p_intent_id: intentId
        });
        if (rpcErr) throw rpcErr;

        const merged = await fetchIntentFromView(intentId);
        return { intent: merged || intent, subscription: sub || null };
    }

    if (intent.status === 'canceled') {
        throw new Error('Intenção cancelada não pode ser marcada como paga.');
    }

    const table = getWriteTableByTarget(intent.plan_target);
    if (!table) {
        throw new Error('plan_target inválido na intenção (esperado clinic/therapist).');
    }

    // 1) marca como pago na TABELA REAL (write)
    const patch = {
        status: 'paid',
        paid_at: new Date().toISOString(),
        notes: notes || null
    };

    const { data: updated, error: upErr } = await supabase.from(table).update(patch).eq('id', intentId).select('*').maybeSingle();

    if (upErr) throw upErr;

    // 2) ativa assinatura a partir da intenção
    const { data: sub, error: rpcErr } = await supabase.rpc('activate_subscription_from_intent', {
        p_intent_id: intentId
    });

    if (rpcErr) throw rpcErr;

    // 3) retorna visão unificada + assinatura
    const merged = await fetchIntentFromView(intentId);
    return { intent: merged || updated, subscription: sub || null };
}

export async function cancelIntent(intentId, notes = '') {
    // 0) pega intenção na VIEW (pra descobrir plan_target e validar estado)
    const intent = await fetchIntentFromView(intentId);

    if (intent.status === 'canceled') return intent;
    if (intent.status === 'paid') {
        // regra de negócio: se você quiser permitir cancelar paid, mude aqui.
        throw new Error('Intenção já paga não deve ser cancelada. Cancele a assinatura, não a intenção.');
    }

    const table = getWriteTableByTarget(intent.plan_target);
    if (!table) {
        throw new Error('plan_target inválido na intenção (esperado clinic/therapist).');
    }

    const { data, error } = await supabase
        .from(table)
        .update({
            status: 'canceled',
            notes: notes || null
        })
        .eq('id', intentId)
        .select('*')
        .maybeSingle();

    if (error) throw error;

    // devolve a visão unificada
    const merged = await fetchIntentFromView(intentId);
    return merged || data;
}
