/**
 * Tests for Enhanced Analytics Generator
 */

import { EnhancedAnalyticsGenerator } from './enhanced-analytics-generator';
import { Workflow } from '../../types/workflow';

describe('EnhancedAnalyticsGenerator', () => {
  let generator: EnhancedAnalyticsGenerator;

  beforeEach(() => {
    generator = new EnhancedAnalyticsGenerator();
  });

  it('should have correct metadata', () => {
    expect(generator.id).toBe('enhanced-analytics');
    expect(generator.name).toBe('Enhanced Analytics Configuration Generator');
    expect(generator.description).toContain('analytics');
  });

  it('should return empty result when no analytics config', () => {
    const workflow: Workflow = {
      workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
      stack: { api: { type: 'backend', technology: 'typescript/express' } },
      stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
    };

    const context = { workflow, outputDirectory: '/tmp/test',
      executionPlan: { workflow, componentPlans: new Map() },
    };

    const result = generator.generate(context);
    expect(result.files).toHaveLength(0);
  });

  describe('Analytics Providers', () => {
    it('should generate Mixpanel provider', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const mixpanel = result.files.find(f => f.path.includes('providers/mixpanel.ts'));

      expect(mixpanel).toBeDefined();
      expect(mixpanel!.content).toContain('MixpanelProvider');
      expect(mixpanel!.content).toContain('mixpanel.init');
      expect(mixpanel!.content).toContain('track_pageview: true');
    });

    it('should generate Amplitude provider', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'amplitude',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const amplitude = result.files.find(f => f.path.includes('providers/amplitude.ts'));

      expect(amplitude).toBeDefined();
      expect(amplitude!.content).toContain('AmplitudeProvider');
      expect(amplitude!.content).toContain('amplitude.init');
      expect(amplitude!.content).toContain('defaultTracking');
    });

    it('should generate Segment provider', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'segment',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const segment = result.files.find(f => f.path.includes('providers/segment.ts'));

      expect(segment).toBeDefined();
      expect(segment!.content).toContain('SegmentProvider');
      expect(segment!.content).toContain('AnalyticsBrowser.load');
    });

    it('should generate Google Analytics provider', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'google_analytics',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const ga = result.files.find(f => f.path.includes('providers/google-analytics.ts'));

      expect(ga).toBeDefined();
      expect(ga!.content).toContain('GoogleAnalyticsProvider');
      expect(ga!.content).toContain('ReactGA.initialize');
      expect(ga!.content).toContain('send_page_view:');
    });

    it('should generate unified analytics service', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const service = result.files.find(f => f.path.includes('services/analytics.ts'));

      expect(service).toBeDefined();
      expect(service!.content).toContain('AnalyticsService');
      expect(service!.content).toContain('MixpanelProvider');
      expect(service!.content).toContain('trackEvent');
      expect(service!.content).toContain('identify');
    });
  });

  describe('Event Tracking', () => {
    it('should generate event definitions', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          events: [
            {
              name: 'ButtonClicked',
              properties: { buttonId: 'string', label: 'string' },
            },
            {
              name: 'PageViewed',
              properties: { path: 'string', title: 'string' },
            },
          ],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const definitions = result.files.find(f => f.path.includes('events/definitions.ts'));

      expect(definitions).toBeDefined();
      expect(definitions!.content).toContain('ButtonClickedEventProperties');
      expect(definitions!.content).toContain('PageViewedEventProperties');
      expect(definitions!.content).toContain('EventName');
      expect(definitions!.content).toContain('buttonId: string');
    });

    it('should generate event tracker', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          events: [{ name: 'TestEvent', properties: {} }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const tracker = result.files.find(f => f.path.includes('events/tracker.ts'));

      expect(tracker).toBeDefined();
      expect(tracker!.content).toContain('EventTracker');
      expect(tracker!.content).toContain('track');
      expect(tracker!.content).toContain('trackWithContext');
    });
  });

  describe('Funnel Tracking', () => {
    it('should generate funnel definitions', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          funnels: [
            {
              name: 'SignupFlow',
              steps: [
                { event: 'signup_started' },
                { event: 'email_verified' },
                { event: 'profile_completed' },
              ],
            },
          ],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const definitions = result.files.find(f => f.path.includes('funnels/definitions.ts'));

      expect(definitions).toBeDefined();
      expect(definitions!.content).toContain('SignupFlowFunnel');
      expect(definitions!.content).toContain('signup_started');
      expect(definitions!.content).toContain('email_verified');
    });

    it('should generate funnel tracker', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          funnels: [{ name: 'TestFunnel', steps: [] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const tracker = result.files.find(f => f.path.includes('funnels/tracker.ts'));

      expect(tracker).toBeDefined();
      expect(tracker!.content).toContain('FunnelTracker');
      expect(tracker!.content).toContain('startFunnel');
      expect(tracker!.content).toContain('trackStep');
      expect(tracker!.content).toContain('completeFunnel');
      expect(tracker!.content).toContain('abandonFunnel');
    });
  });

  describe('Cohort Analysis', () => {
    it('should generate cohort definitions', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          cohorts: [
            {
              name: 'PowerUsers',
              criteria: JSON.stringify({ events_count: { $gt: 100 } }),
            },
          ],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const definitions = result.files.find(f => f.path.includes('cohorts/definitions.ts'));

      expect(definitions).toBeDefined();
      expect(definitions!.content).toContain('PowerUsersCohort');
      expect(definitions!.content).toContain('PowerUsers');
    });

    it('should generate cohort analyzer', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          cohorts: [{ name: 'TestCohort', criteria: JSON.stringify({}) }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const analyzer = result.files.find(f => f.path.includes('cohorts/analyzer.ts'));

      expect(analyzer).toBeDefined();
      expect(analyzer!.content).toContain('CohortAnalyzer');
      expect(analyzer!.content).toContain('addUserToCohort');
      expect(analyzer!.content).toContain('removeUserFromCohort');
      expect(analyzer!.content).toContain('isUserInCohort');
    });
  });

  describe('Privacy and Consent', () => {
    it('should generate consent manager when GDPR compliance enabled', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          privacy: {
            gdpr_compliance: true,
          },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const consent = result.files.find(f => f.path.includes('privacy/consent.ts'));

      expect(consent).toBeDefined();
      expect(consent!.content).toContain('ConsentManager');
      expect(consent!.content).toContain('grantConsent');
      expect(consent!.content).toContain('revokeConsent');
      expect(consent!.content).toContain('hasAnalyticsConsent');
    });

    it('should not generate consent manager when GDPR not enabled', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const consent = result.files.find(f => f.path.includes('privacy/consent.ts'));

      expect(consent).toBeUndefined();
    });
  });

  describe('Frontend Integration', () => {
    it('should generate analytics hook', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const hook = result.files.find(f => f.path.includes('hooks/useAnalytics.ts'));

      expect(hook).toBeDefined();
      expect(hook!.content).toContain('useAnalytics');
      expect(hook!.content).toContain('trackEvent');
      expect(hook!.content).toContain('identify');
      expect(hook!.content).toContain('setUserProperties');
    });

    it('should generate track event hook', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const hook = result.files.find(f => f.path.includes('hooks/useTrackEvent.ts'));

      expect(hook).toBeDefined();
      expect(hook!.content).toContain('useTrackEvent');
      expect(hook!.content).toContain('defaultProperties');
    });

    it('should generate track page hook', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const hook = result.files.find(f => f.path.includes('hooks/useTrackPage.ts'));

      expect(hook).toBeDefined();
      expect(hook!.content).toContain('useTrackPage');
      expect(hook!.content).toContain('usePathname');
    });

    it('should generate Analytics Provider component', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const component = result.files.find(f => f.path.includes('components/AnalyticsProvider.tsx'));

      expect(component).toBeDefined();
      expect(component!.content).toContain('AnalyticsProvider');
      expect(component!.content).toContain('AnalyticsContext');
      expect(component!.content).toContain('useAnalyticsContext');
    });
  });

  describe('Backend Integration', () => {
    it('should generate backend analytics service', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const service = result.files.find(f => f.path.includes('api/src/services/analytics.ts'));

      expect(service).toBeDefined();
      expect(service!.content).toContain('BackendAnalyticsService');
      expect(service!.content).toContain('trackEvent');
      expect(service!.content).toContain('identify');
    });

    it('should generate analytics middleware', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const middleware = result.files.find(f => f.path.includes('middleware/analytics.ts'));

      expect(middleware).toBeDefined();
      expect(middleware!.content).toContain('analyticsMiddleware');
      expect(middleware!.content).toContain('api_request');
    });
  });

  describe('Infrastructure Files', () => {
    it('should generate user properties service', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const service = result.files.find(f => f.path.includes('services/user-properties.ts'));

      expect(service).toBeDefined();
      expect(service!.content).toContain('UserPropertiesService');
      expect(service!.content).toContain('setProperty');
      expect(service!.content).toContain('incrementProperty');
    });

    it('should generate analytics types', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const types = result.files.find(f => f.path.includes('types/analytics.ts'));

      expect(types).toBeDefined();
      expect(types!.content).toContain('AnalyticsProvider');
      expect(types!.content).toContain('TrackEventParams');
      expect(types!.content).toContain('IdentifyParams');
    });

    it('should generate analytics configuration', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
          sampling: { rate: 0.5, enabled: true },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const config = result.files.find(f => f.path.includes('config/analytics.ts'));

      expect(config).toBeDefined();
      expect(config!.content).toContain('analyticsConfig');
      expect(config!.content).toContain('sampling');
    });

    it('should generate analytics documentation', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        analytics: {
          provider: 'mixpanel',
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const context = { workflow, outputDirectory: '/tmp/test', executionPlan: { workflow, componentPlans: new Map() } };
      const result = generator.generate(context);
      const docs = result.files.find(f => f.path.includes('README.md'));

      expect(docs).toBeDefined();
      expect(docs!.content).toContain('# Analytics Infrastructure');
      expect(docs!.content).toContain('## Providers');
    });
  });
});
