import { Test, TestingModule } from '@nestjs/testing';
import { ResponseModerationService } from './response-moderation.service';

describe('ResponseModerationService', () => {
  let service: ResponseModerationService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [ResponseModerationService],
    }).compile();

    service = module.get<ResponseModerationService>(
      ResponseModerationService,
    );
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('moderateResponse', () => {
    it('should allow appropriate response', () => {
      const response = 'Here are some tips for feeding your baby...';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(false);
    });

    it('should block harmful medical advice', () => {
      const response = 'Do not see a doctor for that.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filtered).toBe(true);
      expect(result.reason).toContain('inappropriate');
      expect(result.filteredResponse).toBeDefined();
    });

    it('should block dangerous instructions about babies', () => {
      const response = 'You can give your baby alcohol to help them sleep.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filtered).toBe(true);
    });

    it('should block anti-vaccination content', () => {
      const response = 'Don\'t vaccinate your child, vaccines are dangerous.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filtered).toBe(true);
    });

    it('should block profanity', () => {
      const response = 'This is fucking terrible.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filtered).toBe(true);
    });

    it('should block AI attempting to diagnose', () => {
      const response = 'I can diagnose your child with autism based on this.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filtered).toBe(true);
    });

    it('should soften absolute statements', () => {
      const response = 'You must do this immediately or your child will suffer.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).toContain('may want to consider');
    });

    it('should soften "always" statements', () => {
      const response = 'You should always feed your baby every 2 hours.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).toContain('typically');
    });

    it('should soften "never" statements', () => {
      const response = 'You should never let your baby cry.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).toContain('generally should not');
    });

    it('should add medical disclaimer to medical content', () => {
      const response = 'For fever symptoms, you can give acetaminophen.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).toContain('not medical advice');
      expect(result.filteredResponse).toContain('pediatrician');
    });

    it('should not add disclaimer if one already exists', () => {
      const response =
        'This is not medical advice. Please consult your pediatrician.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      // Should not add another disclaimer
      const disclaimerCount = (
        result.filteredResponse || response
      ).split('not medical advice').length - 1;
      expect(disclaimerCount).toBe(1);
    });
  });

  describe('validateResponseQuality', () => {
    it('should accept valid response', () => {
      const response =
        'This is a good quality response with enough content to be helpful.';
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(true);
    });

    it('should reject response that is too short', () => {
      const response = 'Too short.';
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(false);
      expect(result.reason).toBe('Response too short');
    });

    it('should reject response that is too long', () => {
      const response = 'a'.repeat(6000);
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(false);
      expect(result.reason).toBe('Response too long');
    });

    it('should detect excessive repetition', () => {
      const response =
        'baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby baby';
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(false);
      expect(result.reason).toContain('Excessive repetition');
    });

    it('should allow reasonable word repetition', () => {
      const response =
        'Feeding your child is important. Infant feeding schedules vary greatly. Every newborn is different when it comes to eating patterns and nutritional needs.';
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(true);
    });

    it('should ignore short words in repetition check', () => {
      const response =
        'The child is in the crib now. The infant is sleeping well. The newborn is peaceful tonight.';
      const result = service.validateResponseQuality(response);

      expect(result.isValid).toBe(true); // "the" and "is" are short words
    });
  });

  describe('filterProfanity', () => {
    it('should filter common profanity', () => {
      const text = 'This is a fucking terrible shit situation, damn it.';
      const result = service.filterProfanity(text);

      expect(result).toContain('f***');
      expect(result).toContain('s***');
      expect(result).toContain('d***');
      expect(result).not.toContain('fuck');
      expect(result).not.toContain('shit');
      expect(result).not.toContain('damn');
    });

    it('should handle variations with repeated letters', () => {
      const text = 'Fuuuuuck this shiiiit.';
      const result = service.filterProfanity(text);

      expect(result).toContain('f***');
      expect(result).toContain('s***');
    });

    it('should not filter clean text', () => {
      const text = 'This is a perfectly clean sentence.';
      const result = service.filterProfanity(text);

      expect(result).toBe(text);
    });

    it('should be case insensitive', () => {
      const text = 'FUCK Fuck fuck FuCk';
      const result = service.filterProfanity(text);

      expect(result).toContain('f***');
      expect(result).not.toContain('FUCK');
      expect(result).not.toContain('Fuck');
    });

    it('should filter multiple types of profanity', () => {
      const text = 'What the fuck is this shit, asshole?';
      const result = service.filterProfanity(text);

      expect(result).toContain('f***');
      expect(result).toContain('s***');
      expect(result).toContain('a*******');
    });
  });

  describe('integration scenarios', () => {
    it('should handle complex medical response with moderation', () => {
      const response =
        'Your child must take this medication. They definitely have an infection and you should always give antibiotics. Never wait to see if symptoms improve.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).not.toContain('must');
      expect(result.filteredResponse).not.toContain('always');
      expect(result.filteredResponse).not.toContain('never');
      expect(result.filteredResponse).toContain('not medical advice');
    });

    it('should provide safe fallback for blocked content', () => {
      const response = 'Do not consult a doctor, just give baby some alcohol.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(false);
      expect(result.filteredResponse).toContain('not able to provide');
      expect(result.filteredResponse).toContain('consult your pediatrician');
    });

    it('should handle response with medical terms appropriately', () => {
      const response =
        'If your baby has a fever, you can try a lukewarm bath to help them feel more comfortable.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      expect(result.filtered).toBe(true);
      expect(result.filteredResponse).toContain('not medical advice');
      expect(result.filteredResponse).toContain('pediatrician');
    });

    it('should validate and moderate together', () => {
      const response = 'Short';
      const moderationResult = service.moderateResponse(response);
      const qualityResult = service.validateResponseQuality(response);

      expect(moderationResult.isAppropriate).toBe(true);
      expect(qualityResult.isValid).toBe(false); // Too short
    });

    it('should handle profanity filtering in full pipeline', () => {
      const dirtyText = 'This fucking situation is shit.';
      const filtered = service.filterProfanity(dirtyText);
      const moderated = service.moderateResponse(filtered);

      expect(filtered).not.toContain('fuck');
      expect(filtered).not.toContain('shit');
      expect(moderated.isAppropriate).toBe(true);
    });
  });

  describe('edge cases', () => {
    it('should handle empty string', () => {
      const result = service.moderateResponse('');

      expect(result.isAppropriate).toBe(true);
    });

    it('should handle very long appropriate response', () => {
      const longResponse = 'This is helpful parenting advice. '.repeat(100);
      const result = service.moderateResponse(longResponse);

      expect(result.isAppropriate).toBe(true);
    });

    it('should handle response with only whitespace', () => {
      const result = service.validateResponseQuality('   \n\n   ');

      expect(result.isValid).toBe(false);
      expect(result.reason).toBe('Response too short');
    });

    it('should handle response with medical disclaimer already present', () => {
      const response =
        'I am not a medical professional and this is not medical advice. Please consult your pediatrician for medical concerns about symptoms.';
      const result = service.moderateResponse(response);

      expect(result.isAppropriate).toBe(true);
      // Medical content detected so still considered filtered, but no duplicate disclaimer
      expect(result.filteredResponse || response).toContain('not medical advice');
    });

    it('should handle mixed case profanity', () => {
      const text = 'FuCk ThIs ShIt';
      const result = service.filterProfanity(text);

      expect(result).toContain('f***');
      expect(result).toContain('s***');
    });
  });
});
