// auto-recipes.jsx — Library of pre-built rule templates
// ─────────────────────────────────────────────────────────────────
// Each recipe is a ready-to-clone Rule. Categories drawn from the
// real catalog of ASTRO concerns: leak handling, BB-rank claims,
// CWR fixes, statement variance, agreement lifecycle, etc.
// ─────────────────────────────────────────────────────────────────
(function () {
  if (typeof window === 'undefined') return;

  const RECIPES = [
    // ── ML signals → action
    {
      id: 'recipe-leak-high',
      category: 'Leak detection',
      icon: '◇',
      name: 'Auto-claim high-severity royalty leaks',
      description: 'When the leak engine flags a HIGH-severity finding with > $500 impact, file a claim and notify ops.',
      rule: {
        name: 'Auto-claim high leaks',
        description: 'Catches under-report and missing-territory leaks with material impact.',
        trigger: 'leak.detected',
        conditions: [
          { field: 'severity', op: 'eq',  value: 'high' },
          { field: 'impact',   op: 'gte', value: 500 },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'claim.file',   params: { society: 'auto' } },
          { action: 'notify.inbox', params: { priority: 'high' } },
        ],
      },
    },
    {
      id: 'recipe-bbrank-likely',
      category: 'Black-Box',
      icon: '▣',
      name: 'File BB claims above 80% confidence',
      description: 'When BB-rank scores a black-box entry above 80%, automatically file the claim.',
      rule: {
        name: 'BB > 80% → file claim',
        description: 'Anything with high P(yours) ranking goes straight into the queue.',
        trigger: 'bbrank.high',
        conditions: [
          { field: 'score',    op: 'gte', value: 80 },
          { field: 'recovery', op: 'gte', value: 100 },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'claim.file',   params: { society: 'auto' } },
          { action: 'notify.slack', params: { channel: 'royalties' } },
        ],
      },
    },
    {
      id: 'recipe-cover-takedown',
      category: 'Covers / Samples',
      icon: '⌬',
      name: 'Takedown unregistered covers on YouTube',
      description: 'When a cover is detected on YouTube without a registered claim, auto-send a DMCA notice.',
      rule: {
        name: 'YouTube cover → takedown',
        description: 'Unregistered covers on YouTube cost more than they earn.',
        trigger: 'cover.detected',
        conditions: [
          { field: 'platform', op: 'eq', value: 'YouTube' },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'takedown.send', params: { platform: 'YouTube' } },
          { action: 'notify.inbox',  params: { priority: 'normal' } },
        ],
      },
    },

    // ── CWR / Registrations
    {
      id: 'recipe-cwr-reject',
      category: 'CWR / Registrations',
      icon: '◣',
      name: 'CWR rejection → flag for review',
      description: 'When a society rejects a CWR submission, flag the work and email the registration team.',
      rule: {
        name: 'CWR reject handler',
        description: 'Routes rejected ack files into the registrations queue with reason attached.',
        trigger: 'cwr.ack.rejected',
        conditions: [],
        conditionMode: 'all',
        actions: [
          { action: 'catalog.flag',   params: { queue: 'cwr-rejections', reason: 'Society rejected CWR' } },
          { action: 'notify.email',   params: { to: 'reg@astro', subject: 'CWR rejected — needs review' } },
        ],
      },
    },
    {
      id: 'recipe-cwr-timeout',
      category: 'CWR / Registrations',
      icon: '⏲',
      name: 'CWR timeout → resubmit',
      description: 'When a registration has been open for more than 90 days, regenerate and resubmit.',
      rule: {
        name: 'CWR 90-day timeout',
        description: 'Auto-retry stuck registrations.',
        trigger: 'cwr.timeout',
        conditions: [
          { field: 'daysOpen', op: 'gte', value: 90 },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'cwr.regenerate', params: { version: 'v3.1' } },
          { action: 'cwr.resubmit',   params: { society: 'auto' } },
          { action: 'notify.inbox',   params: { priority: 'normal' } },
        ],
      },
    },

    // ── Statements
    {
      id: 'recipe-stmt-variance',
      category: 'Royalties / Statements',
      icon: '△',
      name: 'Variance > 10% → hold and review',
      description: 'When a DSP statement comes in more than 10% off projection, hold the payout and flag it.',
      rule: {
        name: 'Statement variance hold',
        description: 'Catches under-payments and over-payments before they propagate.',
        trigger: 'statement.variance',
        conditions: [
          { field: 'varPct', op: 'lte', value: -10 },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'royalty.hold',     params: { until: 'review' } },
          { action: 'catalog.flag',     params: { queue: 'statements-review', reason: 'Material variance vs projection' } },
          { action: 'notify.email',     params: { to: 'finance@astro', subject: 'Statement variance flagged' } },
        ],
      },
    },
    {
      id: 'recipe-stmt-import',
      category: 'Royalties / Statements',
      icon: '▤',
      name: 'On statement import → run matcher',
      description: 'Every imported statement gets the learning matcher run automatically.',
      rule: {
        name: 'Auto-match new statements',
        description: 'Keeps reconciliation queue continuously processed.',
        trigger: 'statement.imported',
        conditions: [],
        conditionMode: 'all',
        actions: [
          { action: 'statement.match', params: {} },
        ],
      },
    },

    // ── Agreements
    {
      id: 'recipe-agreement-expiring',
      category: 'Agreements',
      icon: '◷',
      name: 'Agreement nearing expiry → notify',
      description: 'When an agreement is within 30 days of expiry, drop into inbox and email counsel.',
      rule: {
        name: 'Agreement expiry warning',
        description: '30-day window to renegotiate or accept reversion.',
        trigger: 'agreement.expiring',
        conditions: [
          { field: 'daysLeft', op: 'lte', value: 30 },
        ],
        conditionMode: 'all',
        actions: [
          { action: 'notify.inbox', params: { priority: 'high' } },
          { action: 'notify.email', params: { to: 'legal@astro', subject: 'Agreement expiring soon' } },
        ],
      },
    },
    {
      id: 'recipe-reversion',
      category: 'Agreements',
      icon: '↺',
      name: 'On reversion → assign for re-registration',
      description: 'When rights revert, queue work for new registration and notify catalog ops.',
      rule: {
        name: 'Reversion handler',
        description: 'Closes the loop on reversion → updated CWR.',
        trigger: 'reversion.due',
        conditions: [],
        conditionMode: 'all',
        actions: [
          { action: 'catalog.assign', params: { assignee: 'catalog-ops' } },
          { action: 'cwr.regenerate', params: { version: 'v3.1' } },
        ],
      },
    },

    // ── Catalog / intake
    {
      id: 'recipe-audio-uploaded',
      category: 'Catalog / Intake',
      icon: '⌗',
      name: 'On audio upload → fingerprint',
      description: 'Every uploaded audio asset gets fingerprinted automatically.',
      rule: {
        name: 'Auto-fingerprint uploads',
        description: 'Foundation for cover/sample detection.',
        trigger: 'audio.uploaded',
        conditions: [],
        conditionMode: 'all',
        actions: [
          { action: 'fingerprint.run', params: {} },
        ],
      },
    },

    // ── DSP
    {
      id: 'recipe-dsp-failed',
      category: 'DSP delivery',
      icon: '✕',
      name: 'DSP delivery failed → retry & notify',
      description: 'When a delivery fails, regenerate the package and post to ops Slack.',
      rule: {
        name: 'DSP failure handler',
        description: 'Avoids silent delivery failures slipping past.',
        trigger: 'dsp.delivery.failed',
        conditions: [],
        conditionMode: 'all',
        actions: [
          { action: 'notify.slack', params: { channel: 'dsp-ops' } },
          { action: 'catalog.flag', params: { queue: 'dsp-failures', reason: 'Delivery failed' } },
        ],
      },
    },
  ];

  window.AUTO_RECIPES = RECIPES;
  console.log('[AutoRecipes] loaded · ' + RECIPES.length + ' recipes');
})();
