/* Report Builder — starter templates + fixed-slide skeleton ============
   Starter templates live in code (versioned); user-saved templates go to
   the `reports` table. Every reportDef enforces the locked skeleton:
   Cover → Agenda (auto) → Exec Summary → …content… → Thank You.
   Structures reverse-engineered from the user's two source decks
   (REPORT_BUILDER_SPEC.md → Starter templates).
======================================================================== */

let _rid = 0;
const rNewId = (p)=> (p||'el') + '_' + Date.now().toString(36) + '_' + (++_rid);

function rBlock(type, binding, options){
  return { id:rNewId('blk'), type, binding: binding||{}, options: options||{} };
}
function rSlide(type, title, blocks, extra){
  return Object.assign({ id:rNewId('sl'), type, title: title||'', blocks: blocks||[],
    locked: ['cover','agenda','exec_summary','thank_you'].includes(type) }, extra||{});
}

/* ---------- Fixed skeleton -------------------------------------------- */
function rCoverSlide(lang){
  return rSlide('cover', rStr('performance_report', lang), []);
}
function rAgendaSlide(lang){
  return rSlide('agenda', rStr('agenda', lang), []);   // content auto-generated at render
}
function rExecSlide(lang, opts){
  opts = opts || {};
  /* default scorecards: Reach, Impressions, Cost/Result, Clicks, CPC, CTR,
     Total Followers, Video views — minus the account's blocked metrics */
  const metrics = (opts.metrics || rDefaultExecMetrics(opts.accountId))
    .filter(k=>!rMetricBlockedFor(opts.accountId, k));
  const blocks = [ rBlock('scorecard', { metrics }) ];
  if (!opts.noDonut) blocks.push(rBlock('donut', { metric:'spend', dimension:'platform' }));
  if (!opts.noBrand) blocks.push(rBlock('brand', {}));
  return rSlide('exec_summary', rStr('exec_summary', lang), blocks);
}
function rThankYouSlide(lang){
  return rSlide('thank_you', rStr('thank_you', lang), []);
}
/* Per-platform analysis section: divider + overview + campaigns/adsets/ads */
function rPlatformSection(platform, lang, opts){
  opts = opts || {};
  const P = rPlatform(platform);
  const name = lang==='ar' ? P.ar : (lang==='both' ? P.ar + ' · ' + P.label : P.label);
  const mf = (arr)=>arr.filter(k=>!rMetricBlockedFor(opts.accountId, k));
  const tableMetrics = mf(opts.tableMetrics || ['spend','impressions','clicks','ctr','cpc','conversions','cpa']);
  const slides = [
    rSlide('divider', name, [], { platform }),
    rSlide('content', name + ' — ' + rStr('overview', lang), [
      rBlock('scorecard', { platform, metrics: mf(opts.kpis || ['spend','impressions','clicks','ctr','cpc','conversions','cpa','roas']) }),
      rBlock('trend', { platform, metrics:['spend','conversions'] }, { showCompare:true }),
    ], { platform }),
    rSlide('content', name + ' — ' + rStr('campaigns', lang), [
      rBlock('table', { platform, level:'campaign', metrics: tableMetrics,
        sortKey:'spend', sortDir:'desc', topN:10 }, { heatmap:['cpa'] }),
    ], { platform }),
    rSlide('content', name + ' — ' + rStr('adsets', lang), [
      rBlock('table', { platform, level:'adset', metrics: tableMetrics,
        sortKey:'spend', sortDir:'desc', topN:8 }, { heatmap:['cpa'] }),
      rBlock('perf_flags', { platform, level:'adset' }),
    ], { platform }),
    rSlide('content', name + ' — ' + rStr('ads', lang), [
      rBlock('table', { platform, level:'ad', metrics: tableMetrics,
        sortKey:'spend', sortDir:'desc', topN:8 }, { heatmap:['cpa'] }),
      rBlock('perf_flags', { platform, level:'ad' }),
    ], { platform }),
  ];
  return slides;
}
/* Assemble a full def with the skeleton enforced. */
function rAssembleDef(opts){
  const lang = opts.lang || 'en';
  const middle = opts.middle || [];
  return {
    id: null,
    name: opts.name || 'Untitled report',
    accountId: opts.accountId || null,
    brandName: opts.brandName || '',
    lang,
    brandKitId: opts.brandKitId || null,
    agency: opts.agency || null,   // { enabled, name, logo } — "Prepared by" credit
    scope: Object.assign({ source:'system' },   // 'system' | 'manual' — never both
      opts.scope || { platforms: [], start:null, end:null,
        compare:{ mode:'prev_period', start:null, end:null } }),
    slides: [
      rCoverSlide(lang),
      rAgendaSlide(lang),
      opts.exec || rExecSlide(lang, { accountId: opts.accountId }),
      ...middle,
      rThankYouSlide(lang),
    ],
  };
}

/* ---------- Starter templates ------------------------------------------ */
/* ctx: { accountId, brandName, scope:{platforms,start,end,compare}, brandKitId } */
const REPORT_TEMPLATES = [
  {
    id:'tpl_monthly',
    name:'Monthly Client Report', ar:'التقرير الشهري',
    desc:'Full monthly deck: exec summary, trends, and campaign/ad set/ad analysis per platform.',
    icon:'calendar', lang:'en',
    build(ctx){
      const lang = ctx.lang || 'en';
      const plats = rSortPlatforms(ctx.scope.platforms || []);
      const middle = [
        rSlide('content', rStr('trends', lang), [
          rBlock('trend', { metrics:['spend','conversions','ctr'] }, { showCompare:true }),
        ]),
        rSlide('content', rStr('top_campaigns', lang), [
          rBlock('table', { level:'campaign',
            metrics:['spend','impressions','clicks','ctr','conversions','cpa','roas'].filter(k=>!rMetricBlockedFor(ctx.accountId,k)),
            sortKey:'spend', sortDir:'desc', topN:10 },
            { heatmap:['cpa','roas'].filter(k=>!rMetricBlockedFor(ctx.accountId,k)) }),
        ]),
        ...plats.flatMap(p=> rPlatformSection(p, lang, { accountId: ctx.accountId })),
        rSlide('content', rStr('daily', lang), [
          rBlock('heatmap', { metric:'spend' }),
        ]),
        rSlide('content', rStr('next_steps', lang), [
          rBlock('priorities', {}, {}),
        ]),
      ];
      return rAssembleDef({ ...ctx, lang, name: (ctx.brandName||'Monthly') + ' — Monthly Report', middle });
    },
  },
  {
    id:'tpl_wrapup',
    name:'Campaign Wrap-Up', ar:'تقرير نهاية الحملة',
    desc:'Post-campaign results deck: what ran, what it delivered, what to do next.',
    icon:'zap', lang:'en',
    build(ctx){
      const lang = ctx.lang || 'en';
      const plats = rSortPlatforms(ctx.scope.platforms || []);
      const middle = [
        rSlide('content', rStr('trends', lang), [
          rBlock('trend', { metrics:['spend','conversions'] }, { showCompare:false }),
        ]),
        rSlide('content', rStr('campaigns', lang), [
          rBlock('table', { level:'campaign',
            metrics:['spend','impressions','clicks','ctr','conversions','cpa','roas'].filter(k=>!rMetricBlockedFor(ctx.accountId,k)),
            sortKey:'conversions', sortDir:'desc', topN:12 }, { heatmap:['cpa'] }),
        ]),
        rSlide('content', 'Top Ads', [
          rBlock('ranked_list', { level:'ad', metric:'conversions', secondary:'cpa', topN:5 }),
        ]),
        ...plats.flatMap(p=> rPlatformSection(p, lang, { accountId: ctx.accountId })),
        rSlide('content', rStr('next_steps', lang), [
          rBlock('priorities', {}, {}),
        ]),
      ];
      return rAssembleDef({ ...ctx, lang, name:(ctx.brandName||'Campaign') + ' — Wrap-Up', middle });
    },
  },
  {
    id:'tpl_weekly',
    name:'Weekly Pulse', ar:'التقرير الأسبوعي',
    desc:'Short weekly check-in: headline numbers, trend, and top movers.',
    icon:'sparkles', lang:'en',
    build(ctx){
      const lang = ctx.lang || 'en';
      const middle = [
        rSlide('content', rStr('trends', lang), [
          rBlock('trend', { metrics:['spend','conversions'] }, { showCompare:true }),
          rBlock('bar', { metric:'spend', dimension:'platform' }),
        ]),
        rSlide('content', rStr('top_campaigns', lang), [
          rBlock('table', { level:'campaign', metrics:['spend','clicks','ctr','conversions','cpa'],
            sortKey:'spend', sortDir:'desc', topN:8 }, {}),
        ]),
      ];
      return rAssembleDef({ ...ctx, lang,
        name:(ctx.brandName||'Weekly') + ' — Weekly Pulse',
        exec: rExecSlide(lang, { metrics:['spend','conversions','cpa','ctr'], noBrand:true }),
        middle });
    },
  },
  {
    id:'tpl_almunawarah',
    name:'Al Munawarah', ar:'المنوّرة',
    desc:'Arabic RTL client deck — branded covers, KPI scorecards, and ranked breakdowns (from the client\'s own template).',
    icon:'star', lang:'ar', brandKitId:'bk_almunawarah',
    clientAccounts:['acc_almunawarah'],   // client template → locked to its ad account(s)
    build(ctx){
      const lang = ctx.lang || 'ar';
      const plats = rSortPlatforms(ctx.scope.platforms || []);
      const middle = [
        rSlide('content', 'أبرز الحملات (مرتبة حسب الظهور)', [
          rBlock('ranked_list', { level:'campaign', metric:'impressions', secondary:'ctr', topN:5 }),
        ]),
        rSlide('content', rStr('trends', lang), [
          rBlock('trend', { metrics:['spend','clicks'] }, { showCompare:true }),
        ]),
        ...plats.flatMap(p=> rPlatformSection(p, lang, { accountId: ctx.accountId })),
      ];
      return rAssembleDef({ ...ctx, lang,
        brandKitId: ctx.brandKitId || 'bk_almunawarah',
        name:(ctx.brandName||'المنوّرة') + ' — ' + rStr('performance_report', lang),
        exec: rExecSlide(lang, { metrics:['spend','cpc','impressions','clicks'], noDonut:false }),
        middle });
    },
  },
  {
    id:'tpl_blank',
    name:'Blank', ar:'فارغ',
    desc:'Just the fixed skeleton — build every content slide yourself.',
    icon:'file', lang:'en',
    build(ctx){
      return rAssembleDef({ ...ctx, lang: ctx.lang||'en',
        name:(ctx.brandName||'New') + ' — Report', middle: [] });
    },
  },
];

/* ---------- Skeleton guards (used by the builder UI) ------------------- */
/* Slides that can be reordered/removed = the non-locked middle. */
function rSlideBounds(def){
  const first = def.slides.findIndex(s=>s.type==='exec_summary');
  const last  = def.slides.findIndex(s=>s.type==='thank_you');
  return { firstMovable: first+1, lastMovable: last-1 };
}
function rCanRemove(slide){ return !slide.locked; }
function rMoveSlide(def, from, to){
  const { firstMovable, lastMovable } = rSlideBounds(def);
  if (from < firstMovable || from > lastMovable) return def;
  const t = Math.max(firstMovable, Math.min(lastMovable, to));
  const slides = [...def.slides];
  const [s] = slides.splice(from, 1);
  slides.splice(t, 0, s);
  return { ...def, slides };
}

Object.assign(window, {
  REPORT_TEMPLATES, rNewId, rBlock, rSlide, rAssembleDef, rPlatformSection,
  rCoverSlide, rAgendaSlide, rExecSlide, rThankYouSlide,
  rSlideBounds, rCanRemove, rMoveSlide,
});
