import express from 'express';
const router = express.Router();

// Shared CTE fragment for the reference date.
// Uses MAX(last_calculated) from product_metrics so time-relative logic works
// correctly even when the local data snapshot is behind real-time.
const REF_DATE_CTE = `
  ref AS (SELECT COALESCE(MAX(last_calculated), NOW()) as d FROM product_metrics)
`;

// Category definitions matching production website logic:
//
// NEW:           date_online within 31 days (matches prod's date_ol), NOT preorder
// PRE-ORDER:     preorder_count > 0, NOT new
// CLEARANCE:     (regular_price - price) / regular_price >= 0.35 (matches prod's 35% clearance threshold)
// DAILY DEALS:   product_daily_deals table
// BACK IN STOCK: date_last_received > date_first_received, received within 14d,
//                first received > 30d ago, excludes new products (prod excludes datein < 30d)
// BESTSELLERS:   shop_score > 20 + in stock + recent sales (matches prod's /shop/hot page)
//
// Mutual exclusivity:
//   - New and Pre-order are exclusive: if preorder_count > 0, it's preorder not new
//   - Back in stock excludes new products and preorder products
//   - Clearance is independent (a bestseller can also be clearance)

const CATEGORY_FILTERS = {
  new:            "AND is_new = true",
  preorder:       "AND is_preorder = true",
  clearance:      "AND is_clearance = true",
  daily_deals:    "AND is_daily_deal = true",
  back_in_stock:  "AND is_back_in_stock = true",
  bestsellers:    "AND shop_score > 20 AND COALESCE(current_stock, 0) > 0 AND COALESCE(sales_30d, 0) > 0",
  never_featured: "AND times_featured IS NULL AND line_last_featured_at IS NULL",
  no_interest:    "AND COALESCE(total_sold, 0) = 0 AND COALESCE(current_stock, 0) > 0 AND COALESCE(date_online, product_created_at) <= CURRENT_DATE - INTERVAL '30 days'",
};

function buildScoredCTE({ forCount = false } = {}) {
  // forCount=true returns minimal columns for COUNT(*)
  const selectColumns = forCount ? `
          p.pid,
          p.created_at as product_created_at,
          p.date_online,
          p.shop_score,
          p.preorder_count,
          p.price,
          p.regular_price,
          p.total_sold,
          p.line,
          pm.current_stock,
          pm.on_order_qty,
          pm.sales_30d,
          pm.sales_7d,
          pm.date_last_received,
          pm.date_first_received,
          nh.times_featured,
          nh.last_featured_at,
          lh.line_last_featured_at,
          dd.deal_id,
          dd.deal_price
  ` : `
          p.pid,
          p.title,
          p.sku,
          p.brand,
          p.vendor,
          p.price,
          p.regular_price,
          p.shop_score,
          p.image_175 as image,
          p.permalink,
          p.stock_quantity,
          p.preorder_count,
          p.tags,
          p.categories,
          p.line,
          p.created_at as product_created_at,
          p.date_online,
          p.first_received,
          p.date_last_sold,
          p.total_sold,
          p.baskets,
          p.notifies,
          pm.sales_7d,
          pm.sales_30d,
          pm.revenue_30d,
          pm.current_stock,
          pm.on_order_qty,
          pm.abc_class,
          pm.date_first_received,
          pm.date_last_received,
          pm.sales_velocity_daily,
          pm.sells_out_in_days,
          pm.sales_growth_30d_vs_prev,
          pm.margin_30d,
          -- Direct product feature history
          nh.times_featured,
          nh.last_featured_at,
          EXTRACT(DAY FROM ref.d - nh.last_featured_at)::int as days_since_featured,
          -- Line-level feature history
          lh.line_products_featured,
          lh.line_total_features,
          lh.line_last_featured_at,
          lh.line_products_featured_30d,
          lh.line_products_featured_7d,
          ls.line_product_count,
          EXTRACT(DAY FROM ref.d - lh.line_last_featured_at)::int as line_days_since_featured,
          COALESCE(nh.last_featured_at, lh.line_last_featured_at) as effective_last_featured,
          EXTRACT(DAY FROM ref.d - COALESCE(nh.last_featured_at, lh.line_last_featured_at))::int as effective_days_since_featured,
          EXTRACT(DAY FROM ref.d - COALESCE(p.date_online, p.created_at))::int as age_days
  `;

  return `
      ${REF_DATE_CTE},
      newsletter_history AS (
        SELECT
          pid,
          COUNT(*) as times_featured,
          MAX(sent_at) as last_featured_at,
          MIN(sent_at) as first_featured_at
        FROM klaviyo_campaign_products
        GROUP BY pid
      ),
      line_history AS (
        SELECT
          p2.line,
          COUNT(DISTINCT kcp.pid) as line_products_featured,
          COUNT(*) as line_total_features,
          MAX(kcp.sent_at) as line_last_featured_at,
          COUNT(DISTINCT kcp.pid) FILTER (
            WHERE kcp.sent_at > (SELECT d FROM ref) - INTERVAL '30 days'
          ) as line_products_featured_30d,
          COUNT(DISTINCT kcp.pid) FILTER (
            WHERE kcp.sent_at > (SELECT d FROM ref) - INTERVAL '7 days'
          ) as line_products_featured_7d
        FROM products p2
        JOIN klaviyo_campaign_products kcp ON kcp.pid = p2.pid
        WHERE p2.line IS NOT NULL AND p2.line != ''
        GROUP BY p2.line
      ),
      line_sizes AS (
        SELECT line, COUNT(*) as line_product_count
        FROM products
        WHERE visible = true AND line IS NOT NULL AND line != ''
        GROUP BY line
      ),
      scored AS (
        SELECT
          ${selectColumns},

          -- === CATEGORY FLAGS (production-accurate, mutually exclusive where needed) ===

          -- NEW: date_online within 31 days of reference date, AND not on preorder
          -- Uses date_online (prod's date_ol) instead of created_at for accuracy
          CASE
            WHEN p.preorder_count > 0 THEN false
            WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '31 days' THEN true
            ELSE false
          END as is_new,

          -- PRE-ORDER: has preorder quantity
          CASE
            WHEN p.preorder_count > 0 THEN true
            ELSE false
          END as is_preorder,

          -- CLEARANCE: 35%+ discount off regular price (matches prod threshold), price must be > 0
          CASE
            WHEN p.price > 0 AND p.regular_price > 0 AND p.price < p.regular_price
              AND ((p.regular_price - p.price) / p.regular_price * 100) >= 35
            THEN true
            ELSE false
          END as is_clearance,

          -- DAILY DEALS: product has an active deal for today
          CASE WHEN dd.deal_id IS NOT NULL THEN true ELSE false END as is_daily_deal,
          dd.deal_price,

          -- DISCOUNT %
          CASE
            WHEN p.price > 0 AND p.regular_price > 0 AND p.price < p.regular_price
            THEN ROUND(((p.regular_price - p.price) / p.regular_price * 100)::numeric, 0)
            ELSE 0
          END as discount_pct,

          CASE WHEN pm.current_stock > 0 AND pm.current_stock <= 5 THEN true ELSE false END as is_low_stock,

          -- BACK IN STOCK: restocked product, not new, not preorder
          -- Matches prod: date_refill within X days, date_refill > datein,
          --   NOT datein within last 30 days (excludes new products)
          -- We use date_last_received/date_first_received as our equivalents
          CASE
            WHEN p.preorder_count > 0 THEN false
            WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '31 days' THEN false
            WHEN pm.date_last_received > ref.d - INTERVAL '14 days'
              AND pm.date_last_received > pm.date_first_received
              AND pm.date_first_received < ref.d - INTERVAL '30 days'
              AND pm.current_stock > 0
            THEN true
            ELSE false
          END as is_back_in_stock,

          -- === RECOMMENDATION SCORE ===
          (
            -- New product boost (first 31 days by date_online, not preorder)
            CASE
              WHEN p.preorder_count > 0 THEN 0
              WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '14 days' THEN 50
              WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '31 days' THEN 35
              ELSE 0
            END
            -- Pre-order boost
            + CASE WHEN p.preorder_count > 0 THEN 30 ELSE 0 END
            -- Clearance boost (scaled by discount depth)
            + CASE
                WHEN p.price > 0 AND p.regular_price > 0 AND p.price < p.regular_price
                  AND ((p.regular_price - p.price) / p.regular_price * 100) >= 35
                THEN LEAST(((p.regular_price - p.price) / p.regular_price * 50)::int, 25)
                ELSE 0
              END
            -- Sales velocity boost (prod's "hot" logic: recent purchase count)
            + CASE WHEN COALESCE(pm.sales_7d, 0) >= 5 THEN 15
                   WHEN COALESCE(pm.sales_7d, 0) >= 2 THEN 10
                   WHEN COALESCE(pm.sales_7d, 0) >= 1 THEN 5
                   ELSE 0 END
            -- Back in stock boost (only for actual restocks, not new arrivals)
            + CASE
                WHEN p.preorder_count = 0
                  AND COALESCE(p.date_online, p.created_at) <= ref.d - INTERVAL '31 days'
                  AND pm.date_last_received > ref.d - INTERVAL '14 days'
                  AND pm.date_last_received > pm.date_first_received
                  AND pm.date_first_received < ref.d - INTERVAL '30 days'
                  AND pm.current_stock > 0
                THEN 25
                ELSE 0
              END
            -- High interest (baskets + notifies)
            + LEAST((COALESCE(p.baskets, 0) + COALESCE(p.notifies, 0)) / 2, 15)
            -- Recency penalty: line-aware effective last featured (tuned for daily sends)
            + CASE
                WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) IS NULL THEN 10
                WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '2 days' THEN -30
                WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '5 days' THEN -15
                WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '10 days' THEN -5
                ELSE 5
              END
            -- Over-featured penalty (direct product only, tuned for daily sends)
            + CASE
                WHEN COALESCE(nh.times_featured, 0) > 15 THEN -10
                WHEN COALESCE(nh.times_featured, 0) > 8 THEN -5
                ELSE 0
              END
            -- Line saturation penalty (uses 7-day window for daily send cadence)
            + CASE
                WHEN lh.line_products_featured_7d IS NOT NULL
                  AND ls.line_product_count IS NOT NULL
                  AND ls.line_product_count > 0
                  AND (lh.line_products_featured_7d::float / ls.line_product_count) > 0.7
                THEN -10
                WHEN lh.line_products_featured_7d IS NOT NULL
                  AND lh.line_products_featured_7d >= 4
                THEN -5
                ELSE 0
              END
            -- Price tier adjustment (deprioritize very low-price items)
            + CASE
                WHEN COALESCE(p.price, 0) < 3 THEN -15
                WHEN COALESCE(p.price, 0) < 8 THEN -5
                WHEN COALESCE(p.price, 0) >= 25 THEN 5
                ELSE 0
              END
            -- ABC class boost
            + CASE WHEN pm.abc_class = 'A' THEN 10
                   WHEN pm.abc_class = 'B' THEN 5
                   ELSE 0 END
            -- Stock penalty
            + CASE
                WHEN COALESCE(pm.current_stock, 0) <= 0 AND COALESCE(p.preorder_count, 0) = 0 THEN -100
                WHEN COALESCE(pm.current_stock, 0) <= 2 AND COALESCE(p.preorder_count, 0) = 0 THEN -20
                ELSE 0
              END
          ) as score

        FROM ref, products p
        LEFT JOIN product_metrics pm ON pm.pid = p.pid
        LEFT JOIN newsletter_history nh ON nh.pid = p.pid
        LEFT JOIN line_history lh ON lh.line = p.line AND p.line IS NOT NULL AND p.line != ''
        LEFT JOIN line_sizes ls ON ls.line = p.line AND p.line IS NOT NULL AND p.line != ''
        LEFT JOIN product_daily_deals dd ON dd.pid = p.pid AND dd.deal_date = CURRENT_DATE
        WHERE p.visible = true
      )
  `;
}

// GET /api/newsletter/recommendations
router.get('/recommendations', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 50;
    const offset = (page - 1) * limit;
    const category = req.query.category || 'all';

    const categoryFilter = CATEGORY_FILTERS[category] || '';

    const query = `
      WITH ${buildScoredCTE()}
      SELECT *
      FROM scored
      WHERE score > -50
        ${categoryFilter}
      ORDER BY score DESC, COALESCE(sales_7d, 0) DESC
      LIMIT $1 OFFSET $2
    `;

    const countQuery = `
      WITH ${buildScoredCTE({ forCount: true })}
      SELECT COUNT(*) FROM scored
      WHERE score > -50
        ${categoryFilter}
    `;

    const [dataResult, countResult] = await Promise.all([
      pool.query(query, [limit, offset]),
      pool.query(countQuery)
    ]);

    res.json({
      products: dataResult.rows,
      pagination: {
        total: parseInt(countResult.rows[0].count),
        pages: Math.ceil(parseInt(countResult.rows[0].count) / limit),
        currentPage: page,
        limit
      }
    });
  } catch (error) {
    console.error('Error fetching newsletter recommendations:', error);
    res.status(500).json({ error: 'Failed to fetch newsletter recommendations' });
  }
});

// GET /api/newsletter/history/:pid
router.get('/history/:pid', async (req, res) => {
  const pool = req.app.locals.pool;
  const { pid } = req.params;

  try {
    const { rows } = await pool.query(`
      SELECT campaign_id, campaign_name, sent_at, product_url
      FROM klaviyo_campaign_products
      WHERE pid = $1
      ORDER BY sent_at DESC
    `, [pid]);

    res.json({ history: rows });
  } catch (error) {
    console.error('Error fetching newsletter history:', error);
    res.status(500).json({ error: 'Failed to fetch newsletter history' });
  }
});

// GET /api/newsletter/stats
router.get('/stats', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const { rows } = await pool.query(`
      WITH ref AS (SELECT COALESCE(MAX(last_calculated), NOW()) as d FROM product_metrics),
      featured_pids AS (
        SELECT DISTINCT pid FROM klaviyo_campaign_products
      ),
      recent_pids AS (
        SELECT DISTINCT pid FROM klaviyo_campaign_products
        WHERE sent_at > (SELECT d FROM ref) - INTERVAL '2 days'
      )
      SELECT
        -- Unfeatured new products
        (SELECT COUNT(*) FROM products p, ref
          WHERE p.visible = true AND p.preorder_count = 0
          AND COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '31 days'
          AND p.pid NOT IN (SELECT pid FROM featured_pids)
        ) as unfeatured_new,
        -- Back in stock, not yet featured since restock
        (SELECT COUNT(*) FROM products p
          JOIN product_metrics pm ON pm.pid = p.pid
          CROSS JOIN ref
          WHERE p.visible = true
          AND p.preorder_count = 0
          AND COALESCE(p.date_online, p.created_at) <= ref.d - INTERVAL '31 days'
          AND pm.date_last_received > ref.d - INTERVAL '14 days'
          AND pm.date_last_received > pm.date_first_received
          AND pm.date_first_received < ref.d - INTERVAL '30 days'
          AND pm.current_stock > 0
          AND p.pid NOT IN (
            SELECT pid FROM klaviyo_campaign_products
            WHERE sent_at > pm.date_last_received
          )
        ) as back_in_stock_ready,
        -- High score products available (score 40+, not featured in last 2 days)
        (SELECT COUNT(*) FROM (
          WITH ${buildScoredCTE({ forCount: true })}
          SELECT pid FROM scored
          WHERE score >= 40
            AND pid NOT IN (SELECT pid FROM recent_pids)
        ) hs) as high_score_available,
        -- Last campaign date
        (SELECT MAX(sent_at) FROM klaviyo_campaign_products) as last_campaign_date,
        -- Avg days since last featured (across visible in-stock catalog)
        (SELECT ROUND(AVG(days)::numeric, 1) FROM (
          SELECT EXTRACT(DAY FROM ref.d - MAX(kcp.sent_at))::int as days
          FROM products p
          CROSS JOIN ref
          JOIN klaviyo_campaign_products kcp ON kcp.pid = p.pid
          JOIN product_metrics pm ON pm.pid = p.pid
          WHERE p.visible = true AND COALESCE(pm.current_stock, 0) > 0
          GROUP BY p.pid, ref.d
        ) avg_calc) as avg_days_since_featured,
        -- Never featured (visible, in stock or preorder)
        (SELECT COUNT(*) FROM products p
          LEFT JOIN product_metrics pm ON pm.pid = p.pid
          WHERE p.visible = true
          AND (COALESCE(pm.current_stock, 0) > 0 OR p.preorder_count > 0)
          AND p.pid NOT IN (SELECT pid FROM featured_pids)
        ) as never_featured
    `);

    res.json(rows[0]);
  } catch (error) {
    console.error('Error fetching newsletter stats:', error);
    res.status(500).json({ error: 'Failed to fetch newsletter stats' });
  }
});

// GET /api/newsletter/score-breakdown/:pid
// Returns the individual scoring factors for a single product (debug endpoint)
router.get('/score-breakdown/:pid', async (req, res) => {
  const pool = req.app.locals.pool;
  const { pid } = req.params;

  try {
    const { rows } = await pool.query(`
      WITH ${REF_DATE_CTE},
      newsletter_history AS (
        SELECT pid, COUNT(*) as times_featured, MAX(sent_at) as last_featured_at
        FROM klaviyo_campaign_products GROUP BY pid
      ),
      line_history AS (
        SELECT p2.line,
          COUNT(DISTINCT kcp.pid) FILTER (WHERE kcp.sent_at > (SELECT d FROM ref) - INTERVAL '7 days') as line_products_featured_7d
        FROM products p2
        JOIN klaviyo_campaign_products kcp ON kcp.pid = p2.pid
        WHERE p2.line IS NOT NULL AND p2.line != ''
        GROUP BY p2.line
      ),
      line_sizes AS (
        SELECT line, COUNT(*) as line_product_count
        FROM products WHERE visible = true AND line IS NOT NULL AND line != '' GROUP BY line
      )
      SELECT
        -- New product boost
        CASE
          WHEN p.preorder_count > 0 THEN 0
          WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '14 days' THEN 50
          WHEN COALESCE(p.date_online, p.created_at) > ref.d - INTERVAL '31 days' THEN 35
          ELSE 0
        END as new_boost,
        -- Pre-order boost
        CASE WHEN p.preorder_count > 0 THEN 30 ELSE 0 END as preorder_boost,
        -- Clearance boost
        CASE
          WHEN p.price > 0 AND p.regular_price > 0 AND p.price < p.regular_price
            AND ((p.regular_price - p.price) / p.regular_price * 100) >= 35
          THEN LEAST(((p.regular_price - p.price) / p.regular_price * 50)::int, 25)
          ELSE 0
        END as clearance_boost,
        -- Sales velocity
        CASE WHEN COALESCE(pm.sales_7d, 0) >= 5 THEN 15
             WHEN COALESCE(pm.sales_7d, 0) >= 2 THEN 10
             WHEN COALESCE(pm.sales_7d, 0) >= 1 THEN 5
             ELSE 0 END as velocity_boost,
        -- Back in stock
        CASE
          WHEN p.preorder_count = 0
            AND COALESCE(p.date_online, p.created_at) <= ref.d - INTERVAL '31 days'
            AND pm.date_last_received > ref.d - INTERVAL '14 days'
            AND pm.date_last_received > pm.date_first_received
            AND pm.date_first_received < ref.d - INTERVAL '30 days'
            AND pm.current_stock > 0
          THEN 25 ELSE 0
        END as back_in_stock_boost,
        -- Interest
        LEAST((COALESCE(p.baskets, 0) + COALESCE(p.notifies, 0)) / 2, 15) as interest_boost,
        -- Recency
        CASE
          WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) IS NULL THEN 10
          WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '2 days' THEN -30
          WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '5 days' THEN -15
          WHEN COALESCE(nh.last_featured_at, lh.line_last_featured_at) > ref.d - INTERVAL '10 days' THEN -5
          ELSE 5
        END as recency_adj,
        -- Over-featured
        CASE
          WHEN COALESCE(nh.times_featured, 0) > 15 THEN -10
          WHEN COALESCE(nh.times_featured, 0) > 8 THEN -5
          ELSE 0
        END as over_featured_adj,
        -- Line saturation
        CASE
          WHEN lh2.line_products_featured_7d IS NOT NULL
            AND ls.line_product_count IS NOT NULL AND ls.line_product_count > 0
            AND (lh2.line_products_featured_7d::float / ls.line_product_count) > 0.7
          THEN -10
          WHEN lh2.line_products_featured_7d IS NOT NULL AND lh2.line_products_featured_7d >= 4
          THEN -5
          ELSE 0
        END as line_saturation_adj,
        -- Price tier
        CASE
          WHEN COALESCE(p.price, 0) < 3 THEN -15
          WHEN COALESCE(p.price, 0) < 8 THEN -5
          WHEN COALESCE(p.price, 0) >= 25 THEN 5
          ELSE 0
        END as price_tier_adj,
        -- ABC class
        CASE WHEN pm.abc_class = 'A' THEN 10 WHEN pm.abc_class = 'B' THEN 5 ELSE 0 END as abc_boost,
        -- Stock penalty
        CASE
          WHEN COALESCE(pm.current_stock, 0) <= 0 AND COALESCE(p.preorder_count, 0) = 0 THEN -100
          WHEN COALESCE(pm.current_stock, 0) <= 2 AND COALESCE(p.preorder_count, 0) = 0 THEN -20
          ELSE 0
        END as stock_penalty
      FROM ref, products p
      LEFT JOIN product_metrics pm ON pm.pid = p.pid
      LEFT JOIN newsletter_history nh ON nh.pid = p.pid
      LEFT JOIN LATERAL (
        SELECT MAX(kcp.sent_at) as line_last_featured_at
        FROM products p3
        JOIN klaviyo_campaign_products kcp ON kcp.pid = p3.pid
        WHERE p3.line = p.line AND p.line IS NOT NULL AND p.line != ''
      ) lh ON true
      LEFT JOIN line_history lh2 ON lh2.line = p.line AND p.line IS NOT NULL AND p.line != ''
      LEFT JOIN line_sizes ls ON ls.line = p.line AND p.line IS NOT NULL AND p.line != ''
      WHERE p.pid = $1
    `, [pid]);

    if (rows.length === 0) {
      return res.status(404).json({ error: 'Product not found' });
    }
    res.json(rows[0]);
  } catch (error) {
    console.error('Error fetching score breakdown:', error);
    res.status(500).json({ error: 'Failed to fetch score breakdown' });
  }
});

// GET /api/newsletter/campaigns
// Returns all campaigns with product counts and links
router.get('/campaigns', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const [campaignsResult, linksResult, summaryResult] = await Promise.all([
      pool.query(`
        SELECT
          kcp.campaign_id,
          kcp.campaign_name,
          kcp.sent_at,
          COUNT(*) as product_count,
          json_agg(json_build_object(
            'pid', kcp.pid,
            'title', p.title,
            'sku', p.sku,
            'brand', p.brand,
            'line', p.line,
            'image', p.image_175,
            'product_url', kcp.product_url
          ) ORDER BY p.brand, p.line, p.title) as products
        FROM klaviyo_campaign_products kcp
        LEFT JOIN products p ON p.pid = kcp.pid
        GROUP BY kcp.campaign_id, kcp.campaign_name, kcp.sent_at
        ORDER BY kcp.sent_at DESC
      `),
      pool.query(`
        SELECT campaign_id, campaign_name, sent_at, link_url, link_type
        FROM klaviyo_campaign_links
        ORDER BY sent_at DESC
      `),
      pool.query(`
        SELECT
          COUNT(DISTINCT campaign_id) as total_campaigns,
          COUNT(DISTINCT pid) as total_unique_products,
          ROUND(COUNT(*)::numeric / NULLIF(COUNT(DISTINCT campaign_id), 0), 1) as avg_products_per_campaign
        FROM klaviyo_campaign_products
      `)
    ]);

    // Group links by campaign_id
    const linksByCampaign = {};
    for (const link of linksResult.rows) {
      if (!linksByCampaign[link.campaign_id]) linksByCampaign[link.campaign_id] = [];
      linksByCampaign[link.campaign_id].push(link);
    }

    const campaigns = campaignsResult.rows.map(c => ({
      ...c,
      links: linksByCampaign[c.campaign_id] || []
    }));

    res.json({
      campaigns,
      summary: summaryResult.rows[0]
    });
  } catch (error) {
    console.error('Error fetching campaigns:', error);
    res.status(500).json({ error: 'Failed to fetch campaigns' });
  }
});

// GET /api/newsletter/campaigns/products
// Returns product-level aggregate stats across all campaigns
router.get('/campaigns/products', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const { rows } = await pool.query(`
      SELECT
        kcp.pid,
        p.title,
        p.sku,
        p.brand,
        p.image_175 as image,
        p.permalink,
        COUNT(*) as times_featured,
        MIN(kcp.sent_at) as first_featured_at,
        MAX(kcp.sent_at) as last_featured_at,
        EXTRACT(DAY FROM NOW() - MAX(kcp.sent_at))::int as days_since_featured,
        EXTRACT(DAY FROM MAX(kcp.sent_at) - MIN(kcp.sent_at))::int as featured_span_days,
        CASE WHEN COUNT(*) > 1
          THEN ROUND(EXTRACT(DAY FROM MAX(kcp.sent_at) - MIN(kcp.sent_at))::numeric / (COUNT(*) - 1), 1)
          ELSE NULL
        END as avg_days_between_features,
        json_agg(json_build_object(
          'campaign_id', kcp.campaign_id,
          'campaign_name', kcp.campaign_name,
          'sent_at', kcp.sent_at
        ) ORDER BY kcp.sent_at DESC) as campaigns
      FROM klaviyo_campaign_products kcp
      LEFT JOIN products p ON p.pid = kcp.pid
      GROUP BY kcp.pid, p.title, p.sku, p.brand, p.image_175, p.permalink
      ORDER BY COUNT(*) DESC, MAX(kcp.sent_at) DESC
    `);

    res.json({ products: rows });
  } catch (error) {
    console.error('Error fetching campaign products:', error);
    res.status(500).json({ error: 'Failed to fetch campaign products' });
  }
});

// GET /api/newsletter/campaigns/brands
// Returns brand-level aggregate stats across all campaigns
router.get('/campaigns/brands', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const { rows } = await pool.query(`
      SELECT
        COALESCE(p.brand, 'Unknown') as brand,
        COUNT(DISTINCT kcp.pid) as product_count,
        COUNT(*) as times_featured,
        MIN(kcp.sent_at) as first_featured_at,
        MAX(kcp.sent_at) as last_featured_at,
        EXTRACT(DAY FROM NOW() - MAX(kcp.sent_at))::int as days_since_featured,
        CASE WHEN COUNT(DISTINCT kcp.campaign_id) > 1
          THEN ROUND(EXTRACT(DAY FROM MAX(kcp.sent_at) - MIN(kcp.sent_at))::numeric / (COUNT(DISTINCT kcp.campaign_id) - 1), 1)
          ELSE NULL
        END as avg_days_between_features,
        json_agg(DISTINCT jsonb_build_object(
          'campaign_id', kcp.campaign_id,
          'campaign_name', kcp.campaign_name,
          'sent_at', kcp.sent_at
        )) as campaigns
      FROM klaviyo_campaign_products kcp
      LEFT JOIN products p ON p.pid = kcp.pid
      GROUP BY COALESCE(p.brand, 'Unknown')
      ORDER BY COUNT(*) DESC, MAX(kcp.sent_at) DESC
    `);

    res.json({ brands: rows });
  } catch (error) {
    console.error('Error fetching campaign brands:', error);
    res.status(500).json({ error: 'Failed to fetch campaign brands' });
  }
});

// GET /api/newsletter/campaigns/links
// Returns link-level aggregate stats across all campaigns
router.get('/campaigns/links', async (req, res) => {
  const pool = req.app.locals.pool;

  try {
    const { rows } = await pool.query(`
      SELECT
        link_url,
        link_type,
        COUNT(*) as times_used,
        MIN(sent_at) as first_used_at,
        MAX(sent_at) as last_used_at,
        EXTRACT(DAY FROM NOW() - MAX(sent_at))::int as days_since_used,
        json_agg(DISTINCT campaign_name ORDER BY campaign_name) as campaign_names
      FROM klaviyo_campaign_links
      GROUP BY link_url, link_type
      ORDER BY COUNT(*) DESC, MAX(sent_at) DESC
    `);

    res.json({ links: rows });
  } catch (error) {
    console.error('Error fetching campaign links:', error);
    res.status(500).json({ error: 'Failed to fetch campaign links' });
  }
});

export default router;
