// Billing — Asaas (PIX/Boleto/Cartão) pra licenciar Pro/Captain
// Docs: https://docs.asaas.com/reference/

const ASAAS_URL = process.env.ASAAS_API_URL || 'https://api.asaas.com/v3';
const ASAAS_KEY = process.env.ASAAS_API_KEY;
const ASAAS_WEBHOOK_TOKEN = process.env.ASAAS_WEBHOOK_TOKEN; // shared secret pro webhook

export function isAsaasConfigured() {
  return !!ASAAS_KEY;
}

async function asaasRequest(path, method = 'GET', body = null) {
  if (!ASAAS_KEY) throw new Error('Asaas não configurado (env ASAAS_API_KEY ausente)');
  const url = ASAAS_URL.replace(/\/$/, '') + path;
  const r = await fetch(url, {
    method,
    headers: {
      'access_token': ASAAS_KEY,
      'Content-Type': 'application/json',
      'User-Agent': 'Shivao-SaaS/1.0',
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const text = await r.text();
  let json;
  try { json = JSON.parse(text); } catch { json = { raw: text }; }
  if (!r.ok) {
    const msg = json.errors?.[0]?.description || json.message || `HTTP ${r.status}`;
    throw new Error(`Asaas: ${msg}`);
  }
  return json;
}

// Cria customer (idempotente — Asaas dedup por externalReference)
export async function getOrCreateCustomer(user) {
  // Busca por externalReference primeiro
  try {
    const search = await asaasRequest(`/customers?externalReference=user_${user.id}`);
    if (search.data && search.data.length > 0) return search.data[0].id;
  } catch (e) { /* ignore search errors, fallback create */ }

  const created = await asaasRequest('/customers', 'POST', {
    name: user.name || user.email.split('@')[0],
    email: user.email,
    externalReference: `user_${user.id}`,
    notificationDisabled: false,
  });
  return created.id;
}

// Cria cobrança avulsa (1 pagamento). PIX/CREDIT_CARD/BOLETO.
// dueDays: até quantos dias da hoje vence (PIX padrão 3 dias, boleto 7)
export async function createPayment({ customerId, plan, cycle, value, billingType, description, dueDays = 3 }) {
  const due = new Date();
  due.setDate(due.getDate() + dueDays);
  const dueStr = due.toISOString().slice(0, 10); // YYYY-MM-DD

  const body = {
    customer: customerId,
    billingType, // 'PIX' | 'CREDIT_CARD' | 'BOLETO' | 'UNDEFINED' (deixa cliente escolher)
    value,
    dueDate: dueStr,
    description: description || `Shivao ${plan} (${cycle})`,
    externalReference: `plan_${plan}_${cycle}_${Date.now()}`,
  };
  return asaasRequest('/payments', 'POST', body);
}

// Pega QR Code PIX do payment (se billingType=PIX)
export async function getPixQrCode(paymentId) {
  return asaasRequest(`/payments/${paymentId}/pixQrCode`);
}

// Verifica status atual do payment (pra reconciliação se webhook falhar)
export async function getPaymentStatus(paymentId) {
  return asaasRequest(`/payments/${paymentId}`);
}

// Mapeia status Asaas → ações na licença
// PENDING/AWAITING_RISK_ANALYSIS: aguardar
// CONFIRMED: pré-confirmado (cartão capturado, ainda não creditado)
// RECEIVED: dinheiro caiu, ATIVAR licença
// OVERDUE/REFUNDED/RECEIVED_IN_CASH/CHARGEBACK_REQUESTED/REFUND_REQUESTED: handle apropriado
export function isPaidStatus(status) {
  return ['RECEIVED', 'CONFIRMED', 'RECEIVED_IN_CASH'].includes(status);
}

export function isFailedStatus(status) {
  return ['REFUNDED', 'CHARGEBACK_REQUESTED', 'CHARGEBACK_DISPUTE', 'AWAITING_CHARGEBACK_REVERSAL'].includes(status);
}

// Validação básica de webhook: se ASAAS_WEBHOOK_TOKEN setado, verifica header.
// Asaas v3 envia o token no header `asaas-access-token`.
export function verifyWebhookToken(headerToken) {
  if (!ASAAS_WEBHOOK_TOKEN) {
    console.warn('[billing] ASAAS_WEBHOOK_TOKEN não configurado — webhook aceita sem verificação');
    return true;
  }
  return headerToken === ASAAS_WEBHOOK_TOKEN;
}

// Calcula expiração baseada em ciclo + plano
export function computeExpiresAt(cycle) {
  const now = Date.now();
  const oneDay = 24 * 3600 * 1000;
  if (cycle === 'monthly') return now + 30 * oneDay;
  if (cycle === 'yearly') return now + 365 * oneDay;
  return now + 30 * oneDay; // default mensal
}

// Preço por plano + ciclo
import { PLANS } from './auth.js';
export function priceFor(plan, cycle) {
  const p = PLANS[plan];
  if (!p) throw new Error('Plano inválido');
  if (cycle === 'monthly') return p.price_brl_monthly;
  if (cycle === 'yearly') return p.price_brl_yearly;
  throw new Error('Ciclo inválido');
}
