/* Metric catalog, column packs & ad-level data ======================
   Meta Ads Manager-style: a catalog of metrics grouped into packs the
   user can switch between or customize, plus derivation of the full
   metric set + the Ads level (one grain below ad sets).
=================================================================== */

/* ---------- Metric catalog ----------------------------------------- */
/* group: performance | delivery | engagement | video | funnel
   fmt: currency | currency2 | pct | x | int
   tone: spark / accent color */
const METRIC_CATALOG = [
  // Performance
  { id:'spend',     label:'Amount spent',   short:'Spend',     group:'performance', fmt:'currency',  align:'right', tone:'#2f7bff', w:128, spark:true },
  { id:'results',   label:'Results',        short:'Results',   group:'performance', fmt:'int',       align:'right', tone:'#10b981', w:104, spark:true },
  { id:'cpa',       label:'Cost / result',  short:'CPA',       group:'performance', fmt:'currency2', align:'right', tone:'#f59e0b', w:118, spark:true },
  { id:'roas',      label:'ROAS',           short:'ROAS',      group:'performance', fmt:'roasci',    align:'right', tone:'#8351ff', w:120 },
  { id:'revenue',   label:'Conv. value',    short:'Revenue',   group:'performance', fmt:'currency',  align:'right', tone:'#10b981', w:128 },
  // Delivery
  { id:'impressions',label:'Impressions',   short:'Impr.',     group:'delivery',    fmt:'int',       align:'right', tone:'#06b6d4', w:120 },
  { id:'reach',     label:'Reach',          short:'Reach',     group:'delivery',    fmt:'int',       align:'right', tone:'#06b6d4', w:112 },
  { id:'frequency', label:'Frequency',      short:'Freq.',     group:'delivery',    fmt:'freq',      align:'right', tone:'#ef4444', w:104 },
  { id:'cpm',       label:'CPM',            short:'CPM',       group:'delivery',    fmt:'currency2', align:'right', tone:'#8b8b80', w:104 },
  // Engagement
  { id:'clicks',    label:'Link clicks',    short:'Clicks',    group:'engagement',  fmt:'int',       align:'right', tone:'#2f7bff', w:108 },
  { id:'ctr',       label:'CTR (link)',     short:'CTR',       group:'engagement',  fmt:'pct',       align:'right', tone:'#ec4899', w:104, spark:true },
  { id:'cpc',       label:'CPC (link)',     short:'CPC',       group:'engagement',  fmt:'currency2', align:'right', tone:'#06b6d4', w:104, spark:true },
  { id:'engagement',label:'Engagements',    short:'Engmt.',    group:'engagement',  fmt:'int',       align:'right', tone:'#8351ff', w:112 },
  // Video
  { id:'video_views',label:'Video plays',   short:'Plays',     group:'video',       fmt:'int',       align:'right', tone:'#06b6d4', w:112 },
  { id:'hook_rate', label:'Hook rate (3s)', short:'Hook',      group:'video',       fmt:'pct',       align:'right', tone:'#10b981', w:108 },
  { id:'hold_rate', label:'Hold (complete)',short:'Hold',      group:'video',       fmt:'pct',       align:'right', tone:'#f59e0b', w:118 },
  { id:'thumb_stop',label:'Thumb-stop',     short:'T-stop',    group:'video',       fmt:'pct',       align:'right', tone:'#ec4899', w:108 },
  // Funnel
  { id:'atc',       label:'Adds to cart',   short:'ATC',       group:'funnel',      fmt:'int',       align:'right', tone:'#f59e0b', w:104 },
  { id:'checkout',  label:'Checkouts',      short:'IC',        group:'funnel',      fmt:'int',       align:'right', tone:'#06b6d4', w:104 },
  { id:'purchases', label:'Purchases',      short:'Purch.',    group:'funnel',      fmt:'int',       align:'right', tone:'#10b981', w:108 },
  { id:'conv_rate', label:'Conv. rate',     short:'CVR',       group:'funnel',      fmt:'pct',       align:'right', tone:'#8351ff', w:104 },
];
const METRIC_BY_ID = Object.fromEntries(METRIC_CATALOG.map(m=>[m.id,m]));

const METRIC_GROUPS = [
  { id:'performance', label:'Performance' },
  { id:'delivery',    label:'Delivery' },
  { id:'engagement',  label:'Engagement' },
  { id:'video',       label:'Video' },
  { id:'funnel',      label:'Funnel' },
];

/* Column packs — the preset views a buyer toggles between (Meta-style) */
const COLUMN_PACKS = {
  performance: { label:'Performance', cols:['spend','results','cpa','roas','revenue'] },
  delivery:    { label:'Delivery',    cols:['spend','impressions','reach','frequency','cpm'] },
  engagement:  { label:'Engagement',  cols:['spend','clicks','ctr','cpc','engagement'] },
  video:       { label:'Video',       cols:['spend','video_views','hook_rate','hold_rate','thumb_stop'] },
  funnel:      { label:'Funnel',      cols:['spend','atc','checkout','purchases','conv_rate'] },
};
const PACK_ORDER = ['performance','delivery','engagement','video','funnel'];

/* ---------- Derive the FULL metric set for any entity --------------- */
/* entity must carry: spend, cpc, ctr, cpa, roas, conv. Returns all metrics. */
function fullMetrics(e, platform){
  const seed = strSeed((e.id||'x') + ':' + (platform||'')) ;
  const r = mulberry(seed);
  const spend  = e.spend;
  const cpc    = e.cpc || 0.8;
  const ctr    = e.ctr || 1.5;
  const conv   = e.conv != null ? e.conv : Math.round(spend/(e.cpa||25));
  const roas   = e.roas || 2.5;
  const clicks = Math.round(spend / Math.max(cpc,0.05));
  const impressions = Math.round(clicks / Math.max(ctr/100, 0.002));
  const frequency = +(1.6 + r()*2.8).toFixed(2);
  const reach   = Math.round(impressions / frequency);
  const cpm     = +(spend / Math.max(impressions,1) * 1000).toFixed(2);
  const revenue = Math.round(spend * roas);
  // funnel
  const atcRate = ({ meta:0.22, facebook:0.21, instagram:0.20, google:0.18, tiktok:0.26, snapchat:0.14, x:0.12 })[platform] || 0.20;
  const atc      = Math.round(clicks * atcRate);
  const checkout = Math.round(atc * (0.45 + r()*0.2));
  const purchases= conv;
  const conv_rate= +(purchases / Math.max(clicks,1) * 100).toFixed(2);
  // video (meaningful on social/video platforms)
  const video_views = Math.round(impressions * (0.55 + r()*0.3));
  const hook_rate = +(18 + r()*22).toFixed(1);
  const hold_rate = +(6 + r()*12).toFixed(1);
  const thumb_stop= +(22 + r()*18).toFixed(1);
  const engagement= Math.round(clicks * (1.4 + r()*1.2));
  return {
    spend, results:conv, cpa:e.cpa, roas, revenue,
    impressions, reach, frequency, cpm,
    clicks, ctr, cpc, engagement,
    video_views, hook_rate, hold_rate, thumb_stop,
    atc, checkout, purchases, conv_rate,
  };
}

/* ---------- Ads level (one grain below ad sets) -------------------- */
const AD_ANGLES = [
  { angle:'UGC Testimonial',   format:'video',    headline:'“I haven’t stopped wearing these.”',     body:'Real customer review · 0:21' },
  { angle:'Founder Story',     format:'video',    headline:'Why we built this',                       body:'Brand POV · 0:34' },
  { angle:'Product Hero',      format:'image',     headline:'Engineered for the long run',             body:'Single image · static' },
  { angle:'Carousel — Range',  format:'carousel',  headline:'Find your fit',                           body:'5-card carousel' },
  { angle:'Before / After',    format:'image',     headline:'See the difference in 14 days',           body:'Split image · static' },
  { angle:'Offer / Promo',     format:'image',     headline:'48 hours only — 20% off',                 body:'Promo card · static' },
  { angle:'Creator Collab',    format:'video',     headline:'Trusted by the people you follow',        body:'Spark/UGC · 0:18' },
  { angle:'Demo / How-to',     format:'video',     headline:'Watch it work',                           body:'Tutorial · 0:27' },
];
const FORMAT_TONE = { video:'#ec4899', image:'#2f7bff', carousel:'#f59e0b' };

function buildAds(adset, platform){
  const r = mulberry(strSeed(adset.id + ':ads'));
  const n = 2 + Math.floor(r()*3); // 2-4 ads
  const out = [];
  for (let i=0;i<n;i++){
    const a = AD_ANGLES[Math.floor(r()*AD_ANGLES.length)];
    const share = 0.5 + r()*0.7;
    const spend = +(adset.spend / (n+0.4) * share).toFixed(0);
    const cpc   = +(adset.cpc * (0.8 + r()*0.5)).toFixed(2);
    const ctr   = +(adset.ctr * (0.7 + r()*0.7)).toFixed(2);
    const cpa   = +(adset.cpa * (0.8 + r()*0.5)).toFixed(2);
    const roas  = +(adset.roas * (0.8 + r()*0.5)).toFixed(2);
    const status= r() > 0.12 ? 'active' : 'paused';
    out.push({
      id:`ad_${adset.id}_${i}`,
      name:`${a.angle} · v${i+1}`,
      angle:a.angle, format:a.format, headline:a.headline, body:a.body,
      tone:FORMAT_TONE[a.format],
      platform,
      spend, cpc, ctr, cpa, roas,
      conv: Math.round(spend/Math.max(cpa,1)),
      status,
    });
  }
  return out;
}

/* Flatten a campaign list to the chosen level (campaign | adset | ad) */
function rowsForLevel(campaigns, level){
  if (level==='campaign') return campaigns;
  if (level==='adset')
    return campaigns.flatMap(c => c.adsets.map(as => ({ ...as, platform:c.platform, _parent:c.name })));
  // ad level
  return campaigns.flatMap(c => c.adsets.flatMap(as => buildAds(as, c.platform).map(ad => ({ ...ad, _parent:as.name, _grandparent:c.name }))));
}

/* ---------- Per-account metric blocklist ---------------------------- */
/* Product rule: some clients never see certain metrics ANYWHERE —
   dashboard KPIs, charts, tables, Report Builder, and all exports.
   Al Munawarah (city/brand account): ROAS is meaningless — no revenue. */
const ACCOUNT_METRIC_BLOCKLIST = { acc_almunawarah: ['roas'] };
function metricHiddenFor(accountId, metricId){
  const ids = ACCOUNT_METRIC_BLOCKLIST[accountId];
  return !!ids && ids.includes(String(metricId||'').toLowerCase());
}
/* Convenience for deep components that don't receive accountId props:
   uses the globally-selected account (set by GlobalProvider each render,
   same pattern as ACTIVE_CURRENCY). */
function metricHiddenHere(metricId){
  return metricHiddenFor(window.ACTIVE_ACCOUNT_ID || '', metricId);
}

Object.assign(window, {
  METRIC_CATALOG, METRIC_BY_ID, METRIC_GROUPS, COLUMN_PACKS, PACK_ORDER,
  fullMetrics, buildAds, rowsForLevel, AD_ANGLES, FORMAT_TONE,
  ACCOUNT_METRIC_BLOCKLIST, metricHiddenFor, metricHiddenHere,
});
