/**
 * Provider Performance Queries
 * Success rates, volumes, settlement analytics per payment provider
 */
const { pool, fmtDate } = require('./helpers');

// Provider performance: success rate, volume, avg ticket, spread, settlement per provider
async function fetchProviderPerformance(start, end) {
  const conn = await pool.getConnection();
  try {
    // BRL→USD providers (br_payment_methods)
    const [payinProviders] = await conn.execute(`
      SELECT
        COALESCE(pm.provider, 'N/A') as provider,
        'BRL→USD' as flow,
        COUNT(*) as total_tx,
        SUM(CASE WHEN t.status IN ('boleto_pago','finalizado') OR t.date_sent_usa <> '0000-00-00 00:00:00' THEN 1 ELSE 0 END) as success_tx,
        ROUND(COALESCE(SUM(t.amount_usd), 0), 2) as vol_usd,
        ROUND(COALESCE(AVG(t.amount_usd), 0), 2) as avg_ticket,
        ROUND(COALESCE(AVG((t.exchange_rate - t.ptax) / t.exchange_rate * 100), 0), 2) as avg_spread_pct,
        ROUND(COALESCE(AVG(
          CASE WHEN t.date_sent_usa <> '0000-00-00 00:00:00' AND t.created_at IS NOT NULL
          THEN TIMESTAMPDIFF(HOUR, t.created_at, t.date_sent_usa) END
        ), 0), 1) as avg_settlement_hours
      FROM br_transaction_to_usa t
      LEFT JOIN br_payment_methods pm ON t.payment_method_id = pm.id
      WHERE DATE(t.created_at) >= ? AND DATE(t.created_at) <= ?
      GROUP BY pm.provider
      ORDER BY vol_usd DESC
    `, [start, end]);

    // USD→BRL providers (tipo_envio)
    const [payoutProviders] = await conn.execute(`
      SELECT
        COALESCE(p.tipo_envio, 'N/A') as provider,
        'USD→BRL' as flow,
        COUNT(*) as total_tx,
        SUM(CASE WHEN p.data_cp IS NOT NULL AND p.data_cp <> '0000-00-00' THEN 1 ELSE 0 END) as success_tx,
        ROUND(COALESCE(SUM(p.valor), 0), 2) as vol_usd,
        ROUND(COALESCE(AVG(p.valor), 0), 2) as avg_ticket,
        ROUND(COALESCE(AVG(CASE WHEN p.cotacao > 0 THEN (p.ptax - p.cotacao) / p.ptax * 100 ELSE 0 END), 0), 2) as avg_spread_pct,
        ROUND(COALESCE(AVG(
          CASE WHEN p.data_cp IS NOT NULL AND p.data_cp <> '0000-00-00'
          THEN TIMESTAMPDIFF(HOUR, p.created_at, p.data_cp) END
        ), 0), 1) as avg_settlement_hours
      FROM pagamento_br p
      WHERE DATE(p.created_at) >= ? AND DATE(p.created_at) <= ?
        AND p.cotacao IS NOT NULL AND p.cotacao > 0
        AND (p.pgto IS NULL OR p.pgto != 'balance')
      GROUP BY p.tipo_envio
      ORDER BY vol_usd DESC
    `, [start, end]);

    const allProviders = [...payinProviders, ...payoutProviders].map(r => ({
      provider: r.provider,
      flow: r.flow,
      total_tx: Number(r.total_tx) || 0,
      success_tx: Number(r.success_tx) || 0,
      success_rate: Number(r.total_tx) > 0 ? Math.round(Number(r.success_tx) / Number(r.total_tx) * 10000) / 100 : 0,
      vol_usd: Number(r.vol_usd) || 0,
      avg_ticket: Number(r.avg_ticket) || 0,
      avg_spread_pct: Number(r.avg_spread_pct) || 0,
      avg_settlement_hours: Number(r.avg_settlement_hours) || 0
    }));

    // Summary KPIs
    const totalProviders = new Set(allProviders.map(p => p.provider)).size;
    const totalTx = allProviders.reduce((s, p) => s + p.total_tx, 0);
    const totalSuccess = allProviders.reduce((s, p) => s + p.success_tx, 0);
    const totalVol = allProviders.reduce((s, p) => s + p.vol_usd, 0);
    const avgSettlement = allProviders.length > 0
      ? Math.round(allProviders.reduce((s, p) => s + p.avg_settlement_hours, 0) / allProviders.length * 10) / 10
      : 0;

    return {
      providers: allProviders,
      summary: {
        total_providers: totalProviders,
        overall_success_rate: totalTx > 0 ? Math.round(totalSuccess / totalTx * 10000) / 100 : 0,
        total_volume: totalVol,
        avg_settlement_hours: avgSettlement
      }
    };
  } finally {
    conn.release();
  }
}

// Failed transactions breakdown by status, provider, date
async function fetchFailedTransactions(start, end) {
  const conn = await pool.getConnection();
  try {
    // BRL→USD failed
    const [payinFailed] = await conn.execute(`
      SELECT
        COALESCE(pm.provider, 'N/A') as provider,
        'BRL→USD' as flow,
        t.status,
        COUNT(*) as count,
        ROUND(COALESCE(SUM(t.amount_usd), 0), 2) as vol_usd,
        DATE(t.created_at) as date
      FROM br_transaction_to_usa t
      LEFT JOIN br_payment_methods pm ON t.payment_method_id = pm.id
      WHERE DATE(t.created_at) >= ? AND DATE(t.created_at) <= ?
        AND t.status NOT IN ('boleto_pago','finalizado')
        AND (t.date_sent_usa IS NULL OR t.date_sent_usa = '0000-00-00 00:00:00')
      GROUP BY pm.provider, t.status, DATE(t.created_at)
      ORDER BY count DESC
    `, [start, end]);

    // USD→BRL failed
    const [payoutFailed] = await conn.execute(`
      SELECT
        COALESCE(p.tipo_envio, 'N/A') as provider,
        'USD→BRL' as flow,
        COALESCE(p.pgto, 'pending') as status,
        COUNT(*) as count,
        ROUND(COALESCE(SUM(p.valor), 0), 2) as vol_usd,
        DATE(p.created_at) as date
      FROM pagamento_br p
      WHERE DATE(p.created_at) >= ? AND DATE(p.created_at) <= ?
        AND (p.data_cp IS NULL OR p.data_cp = '0000-00-00')
        AND p.cotacao IS NOT NULL AND p.cotacao > 0
        AND (p.pgto IS NULL OR p.pgto != 'balance')
      GROUP BY p.tipo_envio, p.pgto, DATE(p.created_at)
      ORDER BY count DESC
    `, [start, end]);

    const allFailed = [...payinFailed, ...payoutFailed].map(r => ({
      provider: r.provider,
      flow: r.flow,
      status: r.status,
      count: Number(r.count),
      vol_usd: Number(r.vol_usd),
      date: fmtDate(r.date)
    }));

    // Summary by provider
    const byProvider = {};
    allFailed.forEach(r => {
      if (!byProvider[r.provider]) byProvider[r.provider] = { provider: r.provider, count: 0, vol_usd: 0 };
      byProvider[r.provider].count += r.count;
      byProvider[r.provider].vol_usd += r.vol_usd;
    });

    // Summary by status
    const byStatus = {};
    allFailed.forEach(r => {
      if (!byStatus[r.status]) byStatus[r.status] = { status: r.status, count: 0, vol_usd: 0 };
      byStatus[r.status].count += r.count;
      byStatus[r.status].vol_usd += r.vol_usd;
    });

    return {
      details: allFailed,
      byProvider: Object.values(byProvider).sort((a, b) => b.count - a.count),
      byStatus: Object.values(byStatus).sort((a, b) => b.count - a.count),
      total_failed: allFailed.reduce((s, r) => s + r.count, 0),
      total_vol_failed: Math.round(allFailed.reduce((s, r) => s + r.vol_usd, 0) * 100) / 100
    };
  } finally {
    conn.release();
  }
}

// Provider trend: daily volume/count per provider
async function fetchProviderTrend(start, end) {
  const conn = await pool.getConnection();
  try {
    const [payinTrend] = await conn.execute(`
      SELECT
        DATE(t.created_at) as dia,
        COALESCE(pm.provider, 'N/A') as provider,
        COUNT(*) as qtd,
        ROUND(SUM(t.amount_usd), 2) as vol_usd
      FROM br_transaction_to_usa t
      LEFT JOIN br_payment_methods pm ON t.payment_method_id = pm.id
      WHERE DATE(t.created_at) >= ? AND DATE(t.created_at) <= ?
      GROUP BY DATE(t.created_at), pm.provider
      ORDER BY dia, provider
    `, [start, end]);

    return payinTrend.map(r => ({
      dia: fmtDate(r.dia),
      provider: r.provider,
      qtd: Number(r.qtd),
      vol_usd: Number(r.vol_usd)
    }));
  } finally {
    conn.release();
  }
}

module.exports = {
  fetchProviderPerformance,
  fetchFailedTransactions,
  fetchProviderTrend
};
