import { describe, it, expect } from 'vitest';
import {
  getTemplate,
  renderTemplate,
  validateTemplateVariables,
  getAllTemplates,
  getTemplatesByCategory,
  DEFAULT_TEMPLATES,
} from './_core/emailTemplates.ts';

describe('Email Templates', () => {
  it('should get template by ID', () => {
    const template = getTemplate('welcome_campaign');
    expect(template).toBeDefined();
    expect(template?.name).toBe('Welcome Campaign');
    expect(template?.category).toBe('campaign');
  });

  it('should render template with variables', () => {
    const template = getTemplate('welcome_campaign');
    expect(template).toBeDefined();

    const rendered = renderTemplate(template!, {
      firstName: 'John',
      loginUrl: 'https://playcoinkrazy.com/login',
    });

    expect(rendered.htmlContent).toContain('Hi John,');
    expect(rendered.htmlContent).toContain('https://playcoinkrazy.com/login');
  });

  it('should validate template variables', () => {
    const template = getTemplate('password_reset');
    expect(template).toBeDefined();

    // Valid variables
    const validResult = validateTemplateVariables(template!, {
      firstName: 'John',
      resetLink: 'https://example.com/reset',
    });
    expect(validResult.valid).toBe(true);
    expect(validResult.missing).toHaveLength(0);

    // Missing variables
    const invalidResult = validateTemplateVariables(template!, {
      firstName: 'John',
    });
    expect(invalidResult.valid).toBe(false);
    expect(invalidResult.missing).toContain('resetLink');
  });

  it('should get all templates', () => {
    const templates = getAllTemplates();
    expect(templates.length).toBeGreaterThan(0);
    expect(templates.some((t) => t.id === 'welcome_campaign')).toBe(true);
  });

  it('should get templates by category', () => {
    const campaigns = getTemplatesByCategory('campaign');
    expect(campaigns.length).toBeGreaterThan(0);
    expect(campaigns.every((t) => t.category === 'campaign')).toBe(true);

    const transactional = getTemplatesByCategory('transactional');
    expect(transactional.length).toBeGreaterThan(0);
    expect(transactional.every((t) => t.category === 'transactional')).toBe(true);
  });

  it('should render promotional template', () => {
    const template = getTemplate('promotional_offer');
    expect(template).toBeDefined();

    const rendered = renderTemplate(template!, {
      firstName: 'Jane',
      offerTitle: 'Limited Time Offer',
      offerDescription: 'Get 50% bonus on your next deposit!',
      offerAmount: '$50 Bonus',
      promoCode: 'SAVE50',
      claimUrl: 'https://playcoinkrazy.com/claim',
      expiryDate: '2026-05-01',
    });

    expect(rendered.subject).toContain('Special Offer');
    expect(rendered.htmlContent).toContain('Jane');
    expect(rendered.htmlContent).toContain('SAVE50');
    expect(rendered.htmlContent).toContain('2026-05-01');
  });

  it('should render email verification template', () => {
    const template = getTemplate('email_verification');
    expect(template).toBeDefined();

    const rendered = renderTemplate(template!, {
      firstName: 'Bob',
      verificationLink: 'https://playcoinkrazy.com/verify?token=abc123',
      verificationCode: '123456',
    });

    expect(rendered.subject).toContain('Verify Your CoinKrazy Email');
    expect(rendered.htmlContent).toContain('Bob');
    expect(rendered.htmlContent).toContain('123456');
  });

  it('should have all required template fields', () => {
    const templates = getAllTemplates();

    templates.forEach((template) => {
      expect(template.id).toBeDefined();
      expect(template.name).toBeDefined();
      expect(template.subject).toBeDefined();
      expect(template.htmlContent).toBeDefined();
      expect(template.variables).toBeDefined();
      expect(Array.isArray(template.variables)).toBe(true);
      expect(template.category).toMatch(/campaign|transactional|promotional/);
    });
  });
});
