'use strict';

/**
 * Partner attribution report (A1 Session 3).
 *
 * GET /api/partners/report/:code — internal-only (requireInternalAuth,
 * same key as the snapshot pipeline; never browser-reachable, no Next
 * proxy on purpose). Returns per-partner attribution:
 *
 *   { ok, code, signups, conversions, mrr_attributed, note? }
 *
 * Data source: public.user_profiles filtered by `partner_ref` — the
 * code a signup carried in its metadata (set by the web PartnerRefCapture
 * → AuthContext.signUp flow).
 *
 * IMPORTANT — the `partner_ref` column does NOT exist on user_profiles
 * yet. Signup metadata lands in auth.users.raw_user_meta_data, which
 * PostgREST can't query. Until the TODO migration in docs/PARTNERS.md
 * is applied (adds the column + copies it from the signup metadata in
 * handle_new_user), the select errors and this endpoint HONESTLY
 * degrades to zeros with a `note` — it never fabricates attribution.
 * Once the migration runs, real numbers flow with no code change here.
 *
 * MRR attribution uses the REAL tier prices (founder_pricing-aware) on
 * currently-active paid profiles. It is monthly recurring revenue at
 * today's price book — not lifetime value, not a projection.
 */

const express = require('express');
const { requireInternalAuth } = require('../middleware/internalAuth');
const { getSupabaseServiceClient } = require('../utils/supabase');

const router = express.Router();

router.use(requireInternalAuth({ loopbackOnly: false }));

// Tier price book (matches stripeService / pricing page).
const TIER_MRR = {
  analyst: { standard: 19.99, founder: 14.99 },
  desk: { standard: 49.99, founder: 34.99 },
};

/** Same convention as web/src/lib/partnerRef.js — A-Z 0-9 - _, ≤32, uppercase. */
function sanitizePartnerCode(raw) {
  const s = String(raw == null ? '' : raw).trim().toUpperCase();
  if (!s || s.length > 32) return null;
  return /^[A-Z0-9_-]+$/.test(s) ? s : null;
}

/**
 * Pure report math over user_profiles rows
 * ({ tier, subscription_status, founder_pricing }).
 *   signups        — every profile attributed to the code
 *   conversions    — profiles currently on an active paid tier
 *   mrr_attributed — sum of those profiles' monthly price (founder-aware)
 */
function buildPartnerReport(rows) {
  const list = Array.isArray(rows) ? rows : [];
  let conversions = 0;
  let mrr = 0;
  for (const r of list) {
    if (!r) continue;
    const tier = String(r.tier || 'free').toLowerCase();
    const active = String(r.subscription_status || '') === 'active';
    const prices = TIER_MRR[tier];
    if (!prices || !active) continue;
    conversions += 1;
    mrr += r.founder_pricing === true ? prices.founder : prices.standard;
  }
  return {
    signups: list.length,
    conversions,
    mrr_attributed: Math.round(mrr * 100) / 100,
  };
}

// Injectable for tests (no network / no Supabase env needed).
let _getClient = getSupabaseServiceClient;
function _setClientForTests(fn) {
  _getClient = typeof fn === 'function' ? fn : getSupabaseServiceClient;
}

router.get('/report/:code', async (req, res) => {
  const code = sanitizePartnerCode(req.params.code);
  if (!code) {
    return res.status(400).json({ ok: false, error: 'invalid partner code' });
  }
  try {
    const supabase = _getClient();
    const { data, error } = await supabase
      .from('user_profiles')
      .select('tier, subscription_status, founder_pricing')
      .eq('partner_ref', code);

    if (error) {
      // Column not migrated yet (docs/PARTNERS.md TODO) — zeros, never invented.
      return res.json({
        ok: true,
        code,
        signups: 0,
        conversions: 0,
        mrr_attributed: 0,
        note: 'partner_ref is not queryable yet — apply the TODO migration in docs/PARTNERS.md to activate attribution',
      });
    }
    return res.json({ ok: true, code, ...buildPartnerReport(data) });
  } catch (err) {
    const message = err && err.message ? err.message : String(err);
    console.error('[partners/report] failed:', message);
    return res.status(500).json({ ok: false, error: message });
  }
});

module.exports = router;
module.exports.sanitizePartnerCode = sanitizePartnerCode;
module.exports.buildPartnerReport = buildPartnerReport;
module.exports._setClientForTests = _setClientForTests;
