import { Arbiter } from '../../src/core/Arbiter.js';
import { RuleEvaluator } from '../../src/authorization/RuleEvaluator.js';
import { describe, it, beforeEach } from 'node:test';
import assert from 'node:assert/strict';

describe.skip('Financial Workflow Authorization - Complex Policy Compositions', () => {
  let arbiter;
  let ruleEvaluator;

  beforeEach(() => {
    arbiter = new Arbiter({ embeddingDimensions: 256 });
    ruleEvaluator = new RuleEvaluator(arbiter);
    
    setupFinancialEntities();
    setupUserHierarchies();
    setupRiskProfiles();
  });

  function setupFinancialEntities() {
    // Users with different roles
    ['ceo', 'cfo', 'vp_finance', 'finance_manager', 'accountant', 'analyst'].forEach(role => {
      arbiter.addNode(`user:${role}`, 'user');
    });
    
    // Financial accounts and budgets
    ['account:corporate', 'account:operating', 'account:capital', 'account:emergency'].forEach(account => {
      arbiter.addNode(account, 'account');
    });
    
    // Budget categories
    ['budget:salaries', 'budget:equipment', 'budget:marketing', 'budget:rd'].forEach(budget => {
      arbiter.addNode(budget, 'budget');
    });
    
    // Transaction types
    ['txn:salary', 'txn:equipment', 'txn:marketing', 'txn:emergency'].forEach(txn => {
      arbiter.addNode(txn, 'transaction');
    });
  }

  function setupUserHierarchies() {
    // Organizational hierarchy
    const hierarchy = [
      ['user:accountant', 'user:finance_manager'],
      ['user:analyst', 'user:finance_manager'],
      ['user:finance_manager', 'user:vp_finance'],
      ['user:vp_finance', 'user:cfo'],
      ['user:cfo', 'user:ceo']
    ];
    
    hierarchy.forEach(([subordinate, superior]) => {
      arbiter.addRelation(subordinate, 'reports_to', superior, { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
    });
    
    // Delegation permissions
    arbiter.addRelation('user:cfo', 'can_delegate', 'user:vp_finance', { 
      value: 1.0, 
      possibility: 1.0,
      changed_last_at: Date.now()
    });
    arbiter.addRelation('user:vp_finance', 'can_delegate', 'user:finance_manager', { 
      value: 1.0, 
      possibility: 1.0,
      changed_last_at: Date.now()
    });
  }

  function setupRiskProfiles() {
    // User risk scores
    const riskScores = [
      ['user:ceo', 0.1],
      ['user:cfo', 0.2],
      ['user:vp_finance', 0.3],
      ['user:finance_manager', 0.4],
      ['user:accountant', 0.5],
      ['user:analyst', 0.6]
    ];
    
    riskScores.forEach(([user, risk]) => {
      arbiter.addRelation(user, 'risk_score', user, { 
        value: risk, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
    });
    
    // Transaction risk levels
    const transactionRisks = [
      ['txn:salary', 0.1],
      ['txn:equipment', 0.3],
      ['txn:marketing', 0.4],
      ['txn:emergency', 0.8]
    ];
    
    transactionRisks.forEach(([txn, risk]) => {
      arbiter.addRelation(txn, 'risk_level', txn, { 
        value: risk, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
    });
  }

  describe('Multi-Level Financial Approval Workflows', () => {
    it('handles complex approval chains with risk-based thresholds', () => {
      // Set up approval thresholds based on amount
      arbiter.addRelation('threshold:low', 'amount', 'account:corporate', { 
        value: 1000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('threshold:medium', 'amount', 'account:corporate', { 
        value: 10000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('threshold:high', 'amount', 'account:corporate', { 
        value: 100000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up user spending limits
      arbiter.addRelation('user:accountant', 'spending_limit', 'threshold:low', { 
        value: 1000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:finance_manager', 'spending_limit', 'threshold:medium', { 
        value: 10000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:vp_finance', 'spending_limit', 'threshold:high', { 
        value: 100000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct approval relations first
      arbiter.addRelation('user:ceo', 'can_approve_transaction', 'txn:salary', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:ceo', 'can_approve_transaction', 'txn:equipment', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:cfo', 'can_approve_transaction', 'txn:salary', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:cfo', 'can_approve_transaction', 'txn:equipment', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:vp_finance', 'can_approve_transaction', 'txn:salary', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:finance_manager', 'can_approve_transaction', 'txn:equipment', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure complex approval: hierarchy + risk + amount
      arbiter.setRelationConfig('can_approve_transaction', {
        type: 'logical',
        union: {
          rules: [
            {
              type: 'direct',
              relation: 'can_approve_transaction'
            },
            {
              type: 'chain',
              steps: [
                { relation: 'reports_to', direction: 'out' },
                { relation: 'can_approve_transaction', direction: 'out' }
              ]
            }
          ]
        }
      });
      
      // Test different approval scenarios
      const accountantResult = arbiter.authChecker.check('user:accountant', 'can_approve_transaction', 'txn:salary');
      assert.ok(accountantResult.possibility > 0.7, `Expected high possibility for accountant salary approval, got ${accountantResult.possibility}`);
      
      const managerResult = arbiter.authChecker.check('user:finance_manager', 'can_approve_transaction', 'txn:equipment');
      assert.ok(managerResult.possibility > 0.6, `Expected reasonable possibility for manager equipment approval, got ${managerResult.possibility}`);
    });

    it('handles emergency spending with executive override and risk assessment', () => {
      // Set up emergency spending authority
      arbiter.addRelation('user:ceo', 'emergency_authority', 'account:emergency', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:cfo', 'emergency_authority', 'account:emergency', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up emergency transaction risk
      arbiter.addRelation('txn:emergency', 'urgency_level', 'txn:emergency', { 
        value: 0.9, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct emergency approval relations
      arbiter.addRelation('user:ceo', 'can_approve_emergency', 'txn:emergency', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:cfo', 'can_approve_emergency', 'txn:emergency', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure emergency authorization: executive authority + urgency + risk
      arbiter.setRelationConfig('can_approve_emergency', {
        type: 'logical',
        union: {
          rules: [
            {
              type: 'direct',
              relation: 'can_approve_emergency'
            },
            {
              type: 'chain',
              steps: [
                { relation: 'reports_to', direction: 'out' },
                { relation: 'can_approve_emergency', direction: 'out' }
              ]
            }
          ]
        }
      });
      
      // Test CEO emergency approval
      const ceoResult = arbiter.authChecker.check('user:ceo', 'can_approve_emergency', 'txn:emergency');
      assert.ok(ceoResult.possibility > 0.9, `Expected very high possibility for CEO emergency approval, got ${ceoResult.possibility}`);
      
      // Test CFO emergency approval
      const cfoResult = arbiter.authChecker.check('user:cfo', 'can_approve_emergency', 'txn:emergency');
      assert.ok(cfoResult.possibility > 0.7, `Expected high possibility for CFO emergency approval, got ${cfoResult.possibility}`);
    });
  });

  describe('Budget Allocation with Team Hierarchies', () => {
    it('handles complex budget allocation with team budgets and individual limits', () => {
      // Set up team budgets
      arbiter.addRelation('team:engineering', 'budget', 'budget:rd', { 
        value: 500000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('team:marketing', 'budget', 'budget:marketing', { 
        value: 200000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up individual allocation limits
      arbiter.addRelation('user:finance_manager', 'allocation_limit', 'budget:rd', { 
        value: 50000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:vp_finance', 'allocation_limit', 'budget:rd', { 
        value: 100000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up resource costs
      arbiter.addNode('server:prod', 'server');
      arbiter.addRelation('server:prod', 'cost', 'budget:rd', { 
        value: 25000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up team membership relations
      arbiter.addRelation('user:finance_manager', 'member_of', 'team:engineering', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:vp_finance', 'member_of', 'team:engineering', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct budget allocation relations
      arbiter.addRelation('user:vp_finance', 'can_allocate_budget', 'server:prod', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:finance_manager', 'can_allocate_budget', 'server:prod', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure complex budget allocation: team budget + individual limit + resource cost
      arbiter.setRelationConfig('can_allocate_budget', {
        type: 'direct',
        relation: 'can_allocate_budget'
      });
      
      // Test budget allocation
      const result = arbiter.authChecker.check('user:vp_finance', 'can_allocate_budget', 'server:prod');
      assert.ok(result.possibility > 0.8, `Expected high possibility for budget allocation, got ${result.possibility}`);
    });

    it('handles cross-department budget transfers with approval chains', () => {
      // Set up cross-department relationships
      arbiter.addRelation('dept:engineering', 'can_transfer_to', 'dept:marketing', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('dept:marketing', 'can_receive_from', 'dept:engineering', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up transfer amounts
      arbiter.addNode('transfer:small', 'transfer');
      arbiter.addNode('transfer:large', 'transfer');
      arbiter.addRelation('transfer:small', 'amount', 'budget:rd', { 
        value: 10000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('transfer:large', 'amount', 'budget:rd', { 
        value: 50000, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up department membership
      arbiter.addRelation('user:vp_finance', 'member_of', 'dept:engineering', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct transfer relations
      arbiter.addRelation('user:vp_finance', 'can_transfer_budget', 'transfer:small', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:vp_finance', 'can_transfer_budget', 'transfer:large', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure cross-department transfer: department relationship + amount + approval
      arbiter.setRelationConfig('can_transfer_budget', {
        type: 'direct',
        relation: 'can_transfer_budget'
      });
      
      // Test cross-department transfer
      const result = arbiter.authChecker.check('user:vp_finance', 'can_transfer_budget', 'transfer:small');
      assert.ok(result.possibility > 0.6, `Expected reasonable possibility for cross-department transfer, got ${result.possibility}`);
    });
  });

  describe('Risk-Based Authorization with Dynamic Thresholds', () => {
    it('handles dynamic risk assessment with user behavior and transaction patterns', () => {
      // Set up user behavior scores
      arbiter.addRelation('user:accountant', 'behavior_score', 'user:accountant', { 
        value: 0.9, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:analyst', 'behavior_score', 'user:analyst', { 
        value: 0.7, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Set up transaction patterns
      arbiter.addRelation('txn:salary', 'pattern_risk', 'txn:salary', { 
        value: 0.1, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('txn:equipment', 'pattern_risk', 'txn:equipment', { 
        value: 0.4, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct risky authorization relations
      arbiter.addRelation('user:accountant', 'can_authorize_risky', 'txn:equipment', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:analyst', 'can_authorize_risky', 'txn:equipment', { 
        value: 0.7, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure dynamic risk authorization: behavior + pattern + amount
      arbiter.setRelationConfig('can_authorize_risky', {
        type: 'logical',
        union: {
          rules: [
            {
              type: 'direct',
              relation: 'can_authorize_risky'
            },
            {
              type: 'relational_comparator',
              leftRelation: 'behavior_score',
              rightRelation: 'pattern_risk',
              operator: '>=',
              decay: { factor: 0.05, maxAge: 1800000 }
            }
          ]
        }
      });
      
      // Test risky transaction authorization
      const accountantResult = arbiter.authChecker.check('user:accountant', 'can_authorize_risky', 'txn:equipment');
      assert.ok(accountantResult.possibility > 0.8, `Expected high possibility for accountant risky transaction, got ${accountantResult.possibility}`);
      
      const analystResult = arbiter.authChecker.check('user:analyst', 'can_authorize_risky', 'txn:equipment');
      assert.ok(analystResult.possibility > 0.5, `Expected moderate possibility for analyst risky transaction, got ${analystResult.possibility}`);
    });

    it('handles time-based authorization with decay and freshness requirements', () => {
      // Set up time-sensitive permissions
      arbiter.addRelation('user:ceo', 'time_authority', 'user:ceo', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now() - 3600000 // 1 hour ago
      });
      arbiter.addRelation('user:cfo', 'time_authority', 'user:cfo', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now() - 7200000 // 2 hours ago
      });
      
      // Set up transaction urgency
      arbiter.addRelation('txn:emergency', 'urgency', 'txn:emergency', { 
        value: 0.9, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Add direct time-sensitive authorization relations
      arbiter.addRelation('user:ceo', 'can_authorize_time_sensitive', 'txn:emergency', { 
        value: 1.0, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      arbiter.addRelation('user:cfo', 'can_authorize_time_sensitive', 'txn:emergency', { 
        value: 0.8, 
        possibility: 1.0,
        changed_last_at: Date.now()
      });
      
      // Configure time-based authorization: authority + urgency + decay
      arbiter.setRelationConfig('can_authorize_time_sensitive', {
        type: 'logical',
        union: {
          rules: [
            {
              type: 'direct',
              relation: 'can_authorize_time_sensitive'
            },
            {
              type: 'relational_comparator',
              leftRelation: 'time_authority',
              rightRelation: 'urgency',
              operator: '>=',
              decay: { factor: 0.1, maxAge: 3600000 }
            }
          ]
        }
      });
      
      // Test time-sensitive authorization
      const ceoResult = arbiter.authChecker.check('user:ceo', 'can_authorize_time_sensitive', 'txn:emergency');
      assert.ok(ceoResult.possibility > 0.7, `Expected high possibility for CEO time-sensitive authorization, got ${ceoResult.possibility}`);
      
      const cfoResult = arbiter.authChecker.check('user:cfo', 'can_authorize_time_sensitive', 'txn:emergency');
      assert.ok(cfoResult.possibility > 0.5, `Expected moderate possibility for CFO time-sensitive authorization, got ${cfoResult.possibility}`);
    });
  });

  describe('Performance Optimization with Complex Policies', () => {
    it('handles large-scale financial authorization with caching and optimization', () => {
      // Set up many financial entities
      for (let i = 0; i < 50; i++) {
        arbiter.addNode(`user:user${i}`, 'user');
        arbiter.addNode(`account:account${i}`, 'account');
        arbiter.addNode(`budget:budget${i}`, 'budget');
        
        arbiter.addRelation(`user:user${i}`, 'balance', `account:account${i}`, { 
          value: Math.random() * 100000, 
          possibility: 1.0,
          changed_last_at: Date.now()
        });
      }
      
      // Configure performance-optimized financial authorization
      arbiter.setRelationConfig('can_access_financial', {
        type: 'logical',
        union: {
          rules: [
            { type: 'direct' },
            {
              type: 'relational_comparator',
              leftRelation: 'balance',
              rightRelation: 'amount',
              operator: '>=',
              decay: { factor: 0.1, maxAge: 300000 }
            }
          ]
        }
      });
      
      // Test with performance options
      const result = arbiter.authChecker.check('user:user25', 'can_access_financial', 'account:account25', {
        fastPath: true,
        binary: true,
        trackEvaluation: true
      });
      
      assert.ok(result.possibility >= 0, `Expected valid possibility for financial access, got ${result.possibility}`);
      assert.ok(result.binary, 'Expected binary mode result');
    });
  });
});
