import { describe, it, expect } from 'vitest';
import { sanitizePrompt, checkPromptSafety, SAFE_OUTFIT_OPTIONS } from './prompt-safety.js';

describe('prompt-safety', () => {
  describe('sanitizePrompt', () => {
    it('should return unmodified prompt when it is already safe', () => {
      const safe = 'young woman wearing sports bra and leggings at the gym, natural lighting';
      const result = sanitizePrompt(safe);

      expect(result.wasModified).toBe(false);
      expect(result.sanitizedPrompt).toBe(safe);
      expect(result.originalPrompt).toBe(safe);
      expect(result.changes).toHaveLength(0);
    });

    it('should replace banned words with safe alternatives', () => {
      const unsafe = 'woman wearing string bikini on the beach';
      const result = sanitizePrompt(unsafe);

      expect(result.wasModified).toBe(true);
      expect(result.sanitizedPrompt).toContain('fitted swimwear');
      expect(result.sanitizedPrompt).not.toContain('string bikini');
      expect(result.changes.length).toBeGreaterThan(0);
    });

    it('should replace thong with fitted bottoms', () => {
      const result = sanitizePrompt('model wearing a thong on stage');
      expect(result.sanitizedPrompt).toContain('fitted bottoms');
      expect(result.wasModified).toBe(true);
    });

    it('should replace g-string with fitted bottoms', () => {
      const result = sanitizePrompt('wearing a g-string');
      expect(result.sanitizedPrompt).toContain('fitted bottoms');
    });

    it('should replace fishnet with patterned', () => {
      const result = sanitizePrompt('woman in fishnet stockings');
      expect(result.sanitizedPrompt).toContain('patterned');
      expect(result.sanitizedPrompt).not.toContain('fishnet');
    });

    it('should replace see-through with form-fitting', () => {
      const result = sanitizePrompt('wearing a see-through blouse');
      expect(result.sanitizedPrompt).toContain('form-fitting');
    });

    it('should replace transparent with lightweight', () => {
      const result = sanitizePrompt('transparent fabric flowing in the wind');
      expect(result.sanitizedPrompt).toContain('lightweight');
    });

    it('should replace sheer with delicate', () => {
      const result = sanitizePrompt('sheer curtain dress');
      expect(result.sanitizedPrompt).toContain('delicate');
    });

    it('should replace mesh with textured', () => {
      const result = sanitizePrompt('mesh top at the club');
      expect(result.sanitizedPrompt).toContain('textured');
    });

    it('should replace underwear with loungewear', () => {
      const result = sanitizePrompt('posing in underwear');
      expect(result.sanitizedPrompt).toContain('loungewear');
    });

    it('should replace panties with shorts', () => {
      const result = sanitizePrompt('wearing panties and a tank top');
      expect(result.sanitizedPrompt).toContain('shorts');
    });

    it('should allow lingerie in general descriptions (not banned)', () => {
      const result = sanitizePrompt('woman in lingerie on the bed');
      // lingerie genel tanımda çalışıyor, artık banned değil
      expect(result.sanitizedPrompt).toContain('lingerie');
      expect(result.wasModified).toBe(false);
    });

    it('should replace nude with neutral-toned', () => {
      const result = sanitizePrompt('nude colored dress');
      expect(result.sanitizedPrompt).toContain('neutral-toned');
    });

    it('should replace naked with minimal clothing', () => {
      const result = sanitizePrompt('almost naked look');
      expect(result.sanitizedPrompt).toContain('minimal clothing');
    });

    it('should replace topless with backless top', () => {
      const result = sanitizePrompt('topless model on the beach');
      expect(result.sanitizedPrompt).toContain('backless top');
    });

    it('should replace barely covering with form-fitting', () => {
      const result = sanitizePrompt('barely covering outfit');
      expect(result.sanitizedPrompt).toContain('form-fitting');
    });

    it('should replace riding up with fitted', () => {
      const result = sanitizePrompt('skirt riding up');
      expect(result.sanitizedPrompt).toContain('fitted');
    });

    it('should replace pulled down with low-rise', () => {
      const result = sanitizePrompt('jeans pulled down');
      expect(result.sanitizedPrompt).toContain('low-rise');
    });

    it('should replace visible cleavage with flattering neckline', () => {
      const result = sanitizePrompt('dress showing visible cleavage');
      expect(result.sanitizedPrompt).toContain('flattering neckline');
    });

    it('should replace deep plunge with low neckline', () => {
      const result = sanitizePrompt('deep plunge neckline gown');
      expect(result.sanitizedPrompt).toContain('low neckline');
    });

    it('should replace bare legs/thighs/etc with toned X', () => {
      const result = sanitizePrompt('showing bare legs and bare thighs');
      expect(result.sanitizedPrompt).toContain('toned legs');
      expect(result.sanitizedPrompt).toContain('toned thighs');
    });

    it('should replace clinging wet with damp', () => {
      const result = sanitizePrompt('clinging wet t-shirt');
      expect(result.sanitizedPrompt).toContain('damp');
    });

    it('should replace satin bra with satin halter top', () => {
      const result = sanitizePrompt('wearing a satin bra');
      expect(result.sanitizedPrompt).toContain('satin halter top');
    });

    it('should replace bra top with halter top', () => {
      const result = sanitizePrompt('woman in a bra top');
      expect(result.sanitizedPrompt).toContain('halter top');
    });

    it('should replace slip dress with mini dress', () => {
      const result = sanitizePrompt('silk slip dress at evening party');
      expect(result.sanitizedPrompt).toContain('mini dress');
    });

    it('should handle multiple banned words in a single prompt', () => {
      const result = sanitizePrompt('woman wearing thong and fishnet stockings with see-through blouse');
      expect(result.wasModified).toBe(true);
      expect(result.sanitizedPrompt).toContain('fitted bottoms');
      expect(result.sanitizedPrompt).toContain('patterned');
      expect(result.sanitizedPrompt).toContain('form-fitting');
      expect(result.changes.length).toBe(3);
    });

    it('should be case-insensitive', () => {
      const result = sanitizePrompt('wearing FISHNET stockings and THONG');
      expect(result.wasModified).toBe(true);
      expect(result.sanitizedPrompt).not.toMatch(/fishnet/i);
      expect(result.sanitizedPrompt).not.toMatch(/thong/i);
    });

    it('should detect wet+white+shirt dangerous combo', () => {
      const result = sanitizePrompt('woman in wet white shirt at the pool');
      expect(result.warnings.length).toBeGreaterThan(0);
      expect(result.warnings[0]).toContain('see-through');
    });

    it('should detect lace+bedroom dangerous combo', () => {
      const result = sanitizePrompt('lace dress in the bedroom near the bed');
      expect(result.warnings.length).toBeGreaterThan(0);
      expect(result.warnings[0]).toContain('lingerie');
    });

    it('should not warn for combos when only partial match', () => {
      const result = sanitizePrompt('woman in lace dress at the park');
      expect(result.warnings).toHaveLength(0);
    });

    it('should preserve the original prompt in result', () => {
      const original = 'model in fishnet stockings on the bed';
      const result = sanitizePrompt(original);
      expect(result.originalPrompt).toBe(original);
      expect(result.sanitizedPrompt).not.toBe(original);
    });
  });

  describe('checkPromptSafety', () => {
    it('should return safe=true for clean prompts', () => {
      const result = checkPromptSafety('woman wearing sports bra and leggings, gym workout');
      expect(result.safe).toBe(true);
      expect(result.issues).toHaveLength(0);
    });

    it('should return safe=false for prompts with banned words', () => {
      const result = checkPromptSafety('woman in thong and fishnet stockings');
      expect(result.safe).toBe(false);
      expect(result.issues.length).toBeGreaterThan(0);
    });

    it('should detect dangerous combos in safety check', () => {
      const result = checkPromptSafety('wet white shirt at the pool');
      expect(result.safe).toBe(false);
      expect(result.issues.length).toBeGreaterThan(0);
    });

    it('should list all issues found', () => {
      const result = checkPromptSafety('thong and fishnet with see-through top');
      expect(result.safe).toBe(false);
      expect(result.issues.length).toBe(3);
    });
  });

  describe('SAFE_OUTFIT_OPTIONS', () => {
    it('should have all outfit categories', () => {
      expect(SAFE_OUTFIT_OPTIONS.sexy_casual).toBeDefined();
      expect(SAFE_OUTFIT_OPTIONS.nightlife).toBeDefined();
      expect(SAFE_OUTFIT_OPTIONS.swimwear).toBeDefined();
      expect(SAFE_OUTFIT_OPTIONS.intimate_morning).toBeDefined();
      expect(SAFE_OUTFIT_OPTIONS.fashion_editorial).toBeDefined();
    });

    it('should have at least 5 options per category', () => {
      for (const [category, options] of Object.entries(SAFE_OUTFIT_OPTIONS)) {
        expect(options.length, `${category} should have >= 5 options`).toBeGreaterThanOrEqual(5);
      }
    });

    it('should produce safe results after sanitization', () => {
      for (const [category, options] of Object.entries(SAFE_OUTFIT_OPTIONS)) {
        for (const option of options) {
          // Some options like "sheer blouse" are intentionally included
          // but get auto-sanitized before image generation
          const sanitized = sanitizePrompt(option);
          const postCheck = checkPromptSafety(sanitized.sanitizedPrompt);
          expect(postCheck.safe, `"${option}" in ${category} should be safe after sanitization but has: ${postCheck.issues.join(', ')}`).toBe(true);
        }
      }
    });
  });
});
