/**
 * Corporate Dashboard Queries
 * Daily stats, KPIs, trends, top agents — used by /corporate routes
 */
const { pool, fmtDate } = require('./helpers');

// Fast daily stats for admin home (today and yesterday only)
async function fetchDailyStats() {
  const conn = await pool.getConnection();
  try {
    const [brlUsdStats] = await conn.execute(`
      SELECT
        DATE(created_at) as dia,
        COUNT(*) as qtd,
        ROUND(SUM(amount_brl), 2) as total_brl,
        ROUND(SUM(amount_usd), 2) as total_usd
      FROM br_transaction_to_usa
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
      GROUP BY DATE(created_at)
      ORDER BY dia DESC
    `);

    const [usdBrlStats] = await conn.execute(`
      SELECT
        DATE(created_at) as dia,
        COUNT(*) as qtd,
        ROUND(SUM(valor_sol), 2) as total_brl,
        ROUND(SUM(valor), 2) as total_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
        AND cotacao IS NOT NULL AND cotacao > 0
        AND (pgto IS NULL OR pgto != 'balance')
      GROUP BY DATE(created_at)
      ORDER BY dia DESC
    `);

    const [usdUsdStats] = await conn.execute(`
      SELECT
        DATE(created_at) as dia,
        COUNT(*) as qtd,
        ROUND(SUM(valor), 2) as total_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
        AND (cotacao IS NULL OR cotacao = 0 OR pgto = 'balance')
      GROUP BY DATE(created_at)
      ORDER BY dia DESC
    `);

    const today = new Date().toISOString().slice(0, 10);
    const yesterday = new Date(Date.now() - 86400000).toISOString().slice(0, 10);

    const formatDay = (stats, targetDate) => {
      const row = stats.find(r => {
        const d = r.dia instanceof Date ? r.dia.toISOString().slice(0, 10) : String(r.dia).slice(0, 10);
        return d === targetDate;
      });
      return row ? {
        qtd: Number(row.qtd),
        total_brl: Number(row.total_brl) || 0,
        total_usd: Number(row.total_usd) || 0
      } : { qtd: 0, total_brl: 0, total_usd: 0 };
    };

    return {
      brlUsd: {
        hoje: formatDay(brlUsdStats, today),
        ontem: formatDay(brlUsdStats, yesterday)
      },
      usdBrl: {
        hoje: formatDay(usdBrlStats, today),
        ontem: formatDay(usdBrlStats, yesterday)
      },
      usdUsd: {
        hoje: formatDay(usdUsdStats, today),
        ontem: formatDay(usdUsdStats, yesterday)
      }
    };
  } finally {
    conn.release();
  }
}

// KPIs: hoje vs média 30 dias
async function fetchKPIs() {
  const conn = await pool.getConnection();
  try {
    const [brlUsd] = await conn.execute(`
      SELECT
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN 1 ELSE 0 END) as hoje_qtd,
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN amount_usd ELSE 0 END) as hoje_usd,
        COUNT(*) / 30.0 as media_qtd,
        SUM(amount_usd) / 30.0 as media_usd
      FROM br_transaction_to_usa
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
    `);

    const [usdBrl] = await conn.execute(`
      SELECT
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN 1 ELSE 0 END) as hoje_qtd,
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN valor ELSE 0 END) as hoje_usd,
        COUNT(*) / 30.0 as media_qtd,
        SUM(valor) / 30.0 as media_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        AND cotacao IS NOT NULL AND cotacao > 0
        AND (pgto IS NULL OR pgto != 'balance')
    `);

    const [usdUsd] = await conn.execute(`
      SELECT
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN 1 ELSE 0 END) as hoje_qtd,
        SUM(CASE WHEN DATE(created_at) = CURDATE() THEN valor ELSE 0 END) as hoje_usd,
        COUNT(*) / 30.0 as media_qtd,
        SUM(valor) / 30.0 as media_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        AND (cotacao IS NULL OR cotacao = 0 OR pgto = 'balance')
    `);

    const format = (row) => ({
      hoje_qtd: Number(row[0]?.hoje_qtd) || 0,
      hoje_usd: Number(row[0]?.hoje_usd) || 0,
      media_qtd: Math.round(Number(row[0]?.media_qtd) || 0),
      media_usd: Math.round(Number(row[0]?.media_usd) || 0)
    });

    const brlUsdData = format(brlUsd);
    const usdBrlData = format(usdBrl);
    const usdUsdData = format(usdUsd);

    return {
      brlUsd: brlUsdData,
      usdBrl: usdBrlData,
      usdUsd: usdUsdData,
      total: {
        hoje_qtd: brlUsdData.hoje_qtd + usdBrlData.hoje_qtd + usdUsdData.hoje_qtd,
        hoje_usd: brlUsdData.hoje_usd + usdBrlData.hoje_usd + usdUsdData.hoje_usd,
        media_qtd: brlUsdData.media_qtd + usdBrlData.media_qtd + usdUsdData.media_qtd,
        media_usd: brlUsdData.media_usd + usdBrlData.media_usd + usdUsdData.media_usd
      }
    };
  } finally {
    conn.release();
  }
}

// Tendência 30 dias
async function fetchTrend30Days() {
  const conn = await pool.getConnection();
  try {
    const [brlUsd] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd, ROUND(SUM(amount_usd), 2) as vol_usd
      FROM br_transaction_to_usa
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
      GROUP BY DATE(created_at) ORDER BY dia
    `);

    const [usdBrl] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd, ROUND(SUM(valor), 2) as vol_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        AND cotacao IS NOT NULL AND cotacao > 0
        AND (pgto IS NULL OR pgto != 'balance')
      GROUP BY DATE(created_at) ORDER BY dia
    `);

    const [usdUsd] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd, ROUND(SUM(valor), 2) as vol_usd
      FROM pagamento_br
      WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        AND (cotacao IS NULL OR cotacao = 0 OR pgto = 'balance')
      GROUP BY DATE(created_at) ORDER BY dia
    `);

    const formatRows = (rows) => rows.map(r => ({
      dia: fmtDate(r.dia),
      qtd: Number(r.qtd),
      vol_usd: Number(r.vol_usd)
    }));

    return {
      brlUsd: formatRows(brlUsd),
      usdBrl: formatRows(usdBrl),
      usdUsd: formatRows(usdUsd)
    };
  } finally {
    conn.release();
  }
}

// Tendência por período customizado
async function fetchTrendByPeriod(dataInicio, dataFim) {
  const conn = await pool.getConnection();
  try {
    const [brlUsd] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd,
             ROUND(SUM(amount_usd), 2) as vol_usd,
             ROUND(SUM(amount_brl), 2) as vol_brl
      FROM br_transaction_to_usa
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
      GROUP BY DATE(created_at) ORDER BY dia
    `, [dataInicio, dataFim]);

    const [usdBrl] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd,
             ROUND(SUM(valor), 2) as vol_usd,
             ROUND(SUM(valor_sol), 2) as vol_brl
      FROM pagamento_br
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
        AND cotacao IS NOT NULL AND cotacao > 0
        AND (pgto IS NULL OR pgto != 'balance')
      GROUP BY DATE(created_at) ORDER BY dia
    `, [dataInicio, dataFim]);

    const [usdUsd] = await conn.execute(`
      SELECT DATE(created_at) as dia, COUNT(*) as qtd,
             ROUND(SUM(valor), 2) as vol_usd
      FROM pagamento_br
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
        AND (cotacao IS NULL OR cotacao = 0 OR pgto = 'balance')
      GROUP BY DATE(created_at) ORDER BY dia
    `, [dataInicio, dataFim]);

    const formatRows = (rows) => rows.map(r => ({
      dia: fmtDate(r.dia),
      qtd: Number(r.qtd),
      vol_usd: Number(r.vol_usd),
      vol_brl: Number(r.vol_brl) || 0
    }));

    return {
      brlUsd: formatRows(brlUsd),
      usdBrl: formatRows(usdBrl),
      usdUsd: formatRows(usdUsd)
    };
  } finally {
    conn.release();
  }
}

// KPIs por período customizado
async function fetchKPIsByPeriod(dataInicio, dataFim) {
  const conn = await pool.getConnection();
  try {
    const [brlUsd] = await conn.execute(`
      SELECT
        COUNT(*) as qtd,
        ROUND(SUM(amount_usd), 2) as vol_usd,
        ROUND(SUM(amount_brl), 2) as vol_brl,
        ROUND(AVG(amount_usd), 2) as ticket_medio
      FROM br_transaction_to_usa
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
    `, [dataInicio, dataFim]);

    const [usdBrl] = await conn.execute(`
      SELECT
        COUNT(*) as qtd,
        ROUND(SUM(valor), 2) as vol_usd,
        ROUND(SUM(valor_sol), 2) as vol_brl,
        ROUND(AVG(valor), 2) as ticket_medio
      FROM pagamento_br
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
        AND cotacao IS NOT NULL AND cotacao > 0
        AND (pgto IS NULL OR pgto != 'balance')
    `, [dataInicio, dataFim]);

    const [usdUsd] = await conn.execute(`
      SELECT
        COUNT(*) as qtd,
        ROUND(SUM(valor), 2) as vol_usd,
        ROUND(AVG(valor), 2) as ticket_medio
      FROM pagamento_br
      WHERE DATE(created_at) >= ? AND DATE(created_at) <= ?
        AND (cotacao IS NULL OR cotacao = 0 OR pgto = 'balance')
    `, [dataInicio, dataFim]);

    const format = (row) => ({
      qtd: Number(row[0]?.qtd) || 0,
      vol_usd: Number(row[0]?.vol_usd) || 0,
      vol_brl: Number(row[0]?.vol_brl) || 0,
      ticket_medio: Number(row[0]?.ticket_medio) || 0
    });

    const brlUsdData = format(brlUsd);
    const usdBrlData = format(usdBrl);
    const usdUsdData = format(usdUsd);

    return {
      brlUsd: brlUsdData,
      usdBrl: usdBrlData,
      usdUsd: usdUsdData,
      total: {
        qtd: brlUsdData.qtd + usdBrlData.qtd + usdUsdData.qtd,
        vol_usd: brlUsdData.vol_usd + usdBrlData.vol_usd + usdUsdData.vol_usd,
        vol_brl: brlUsdData.vol_brl + usdBrlData.vol_brl,
        ticket_medio: Math.round((brlUsdData.vol_usd + usdBrlData.vol_usd + usdUsdData.vol_usd) /
          (brlUsdData.qtd + usdBrlData.qtd + usdUsdData.qtd) || 0)
      },
      periodo: { inicio: dataInicio, fim: dataFim }
    };
  } finally {
    conn.release();
  }
}

// Top 5 agentes por período
async function fetchTopAgentes(dias = 30) {
  const conn = await pool.getConnection();
  try {
    const [rows] = await conn.execute(`
      SELECT
        agente_id,
        SUM(qtd) as total_qtd,
        ROUND(SUM(vol_usd), 2) as total_usd
      FROM (
        SELECT ac.agente_id, COUNT(*) as qtd, SUM(t.amount_usd) as vol_usd
        FROM br_transaction_to_usa t
        INNER JOIN ag_contas ac ON ac.conta_id = t.id_conta
        WHERE t.created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
        GROUP BY ac.agente_id
        UNION ALL
        SELECT ac.agente_id, COUNT(*) as qtd, SUM(p.valor) as vol_usd
        FROM pagamento_br p
        INNER JOIN ag_contas ac ON ac.conta_id = p.id_conta
        WHERE p.created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
        GROUP BY ac.agente_id
      ) combined
      GROUP BY agente_id
      ORDER BY total_usd DESC
      LIMIT 5
    `, [dias, dias]);

    return rows.map((r, i) => ({
      rank: i + 1,
      agente_id: r.agente_id,
      qtd: Number(r.total_qtd),
      vol_usd: Number(r.total_usd)
    }));
  } finally {
    conn.release();
  }
}

module.exports = {
  fetchDailyStats,
  fetchKPIs,
  fetchTrend30Days,
  fetchTrendByPeriod,
  fetchKPIsByPeriod,
  fetchTopAgentes
};
