/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/features/financeiro/services/asaasGatewayService.js
|
| Cliente JS pra orquestrar cobranças Asaas via Edge Functions.
| Browser NUNCA fala direto com Asaas — API key não pode chegar aqui.
|
| Arquitetura: ver development/02-auditoria/DESIGN_ASAAS_GATEWAY.md
|
| ⚠️ FOUNDATION SKELETON. Edge Functions ainda são stubs — chamadas vão
| retornar erro até deploy real. Requer credenciais Asaas configuradas.
|
| Pré-requisitos (do user):
|   1. Migration 20260521000001_asaas_gateway_tables.sql aplicada
|   2. Migration 20260521000002_asaas_gateway_rls.sql aplicada
|   3. Edge Functions deployadas (asaas-create-payment-record, asaas-cancel-payment)
|   4. API key Asaas inserida em payment_settings (via UI futura ou SQL manual)
|   5. payment_settings.asaas_enabled = true
|--------------------------------------------------------------------------
*/
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';

// ─── Status mapping Asaas → financial_records.status ────────────────────────

const ASAAS_TO_STATUS = {
    PENDING: 'pending',
    RECEIVED: 'paid',
    CONFIRMED: 'paid',
    RECEIVED_IN_CASH: 'paid',
    OVERDUE: 'overdue',
    REFUNDED: 'refunded',
    CHARGEBACK_REQUESTED: 'refunded',
    CHARGEBACK_DISPUTE: 'cancelled',
    DELETED: 'cancelled'
};

export function mapAsaasStatus(asaasStatus) {
    return ASAAS_TO_STATUS[asaasStatus] || 'pending';
}

// ─── Validations ────────────────────────────────────────────────────────────

function assertTenantId(tenantId) {
    if (!tenantId || tenantId === 'null' || tenantId === 'undefined') {
        throw new Error('Tenant ativo inválido pra operar Asaas.');
    }
}

function resolveTenantId() {
    const tenantStore = useTenantStore();
    const tid = tenantStore.activeTenantId || tenantStore.tenantId;
    assertTenantId(tid);
    return tid;
}

// ─── Core API ───────────────────────────────────────────────────────────────

/**
 * Cria cobrança Asaas pra um financial_record existente.
 *
 * Invoca Edge Function `asaas-create-payment-record` que:
 *   1. Lê financial_record + patient
 *   2. Garante asaas_customer existe (cascade pra create-customer-patient)
 *   3. POST /payments no Asaas com externalReference=financial_record.id
 *   4. INSERT asaas_payments + UPDATE financial_records.payment_link
 *
 * @param {string} financialRecordId
 * @param {Object} opts
 * @param {'PIX'|'BOLETO'|'CREDIT_CARD'} [opts.method='PIX']
 * @param {string} [opts.dueDate]  - YYYY-MM-DD. Default = financial_record.due_date
 * @returns {Promise<{asaas_payment_id, payment_url, pix_qr_code?, pix_copy_paste?, bank_slip_url?}>}
 */
export async function createPaymentForRecord(financialRecordId, opts = {}) {
    if (!financialRecordId) throw new Error('financialRecordId obrigatório.');
    const tenantId = resolveTenantId();
    const method = opts.method || 'PIX';

    if (!['PIX', 'BOLETO', 'CREDIT_CARD'].includes(method)) {
        throw new Error(`Método inválido: ${method}. Aceitos: PIX, BOLETO, CREDIT_CARD.`);
    }

    const { data, error } = await supabase.functions.invoke('asaas-create-payment-record', {
        body: {
            tenant_id: tenantId,
            financial_record_id: financialRecordId,
            billing_type: method,
            due_date: opts.dueDate || null
        }
    });

    if (error) throw new Error(formatEdgeError(error));
    if (!data?.ok) throw new Error(data?.error || 'Falha ao criar cobrança Asaas.');

    return data.payment;
}

/**
 * Cancela cobrança Asaas. Não afeta o financial_record diretamente — webhook
 * processará PAYMENT_DELETED e fará o sync.
 *
 * @param {string} asaasPaymentId
 */
export async function cancelPayment(asaasPaymentId) {
    if (!asaasPaymentId) throw new Error('asaasPaymentId obrigatório.');
    const tenantId = resolveTenantId();

    const { data, error } = await supabase.functions.invoke('asaas-cancel-payment', {
        body: { tenant_id: tenantId, asaas_payment_id: asaasPaymentId }
    });

    if (error) throw new Error(formatEdgeError(error));
    if (!data?.ok) throw new Error(data?.error || 'Falha ao cancelar cobrança.');

    return data;
}

/**
 * Busca info de pagamento Asaas (PIX QR code, boleto URL, status atual).
 * Read-only: vai na tabela asaas_payments. Não chama API Asaas.
 *
 * @param {string} financialRecordId
 * @returns {Promise<Object|null>}
 */
export async function getPaymentForRecord(financialRecordId) {
    if (!financialRecordId) return null;
    const tenantId = resolveTenantId();

    const { data, error } = await tenantDb().from('asaas_payments')
        .select('id, asaas_payment_id, billing_type, status, value, due_date, payment_date, invoice_url, payment_url, bank_slip_url, pix_qr_code, pix_copy_paste, cancelled_at')
        
        .eq('financial_record_id', financialRecordId)
        .is('cancelled_at', null)
        .order('created_at', { ascending: false })
        .limit(1)
        .maybeSingle();

    if (error) throw error;
    return data || null;
}

/**
 * Sincroniza força um pagamento Asaas (consulta API Asaas + atualiza row local).
 * Use quando suspeitar que webhook falhou (record fica pending mas paciente diz que pagou).
 *
 * @param {string} asaasPaymentId
 */
export async function syncPayment(asaasPaymentId) {
    if (!asaasPaymentId) throw new Error('asaasPaymentId obrigatório.');
    const tenantId = resolveTenantId();

    const { data, error } = await supabase.functions.invoke('asaas-sync-payment', {
        body: { tenant_id: tenantId, asaas_payment_id: asaasPaymentId }
    });

    if (error) throw new Error(formatEdgeError(error));
    if (!data?.ok) throw new Error(data?.error || 'Falha ao sincronizar.');
    return data;
}

/**
 * Verifica se gateway Asaas está habilitado pro tenant ativo.
 * Usado pra mostrar/esconder botões de cobrança Asaas na UI.
 */
export async function isGatewayEnabled() {
    const tenantId = resolveTenantId();
    const { data, error } = await tenantDb().from('payment_settings').select('asaas_enabled, asaas_environment').maybeSingle();
    if (error) return false;
    return !!data?.asaas_enabled;
}

// ─── Helpers ────────────────────────────────────────────────────────────────

function formatEdgeError(err) {
    if (typeof err === 'string') return err;
    if (err?.message) return err.message;
    if (err?.error) return String(err.error);
    return 'Erro desconhecido na Edge Function.';
}
