import { describe, it, expect } from 'vitest';
import {
  SendEmailSchema,
  SendPushSchema,
  SendSlackSchema,
  SendTelegramSchema,
  SendTestEmailSchema,
} from './types.js';
import { BUILT_IN_TEMPLATES, getTemplate, listTemplateIds } from './templates.js';
import { renderTemplate, interpolate } from './renderer.js';

// ── Schema Tests ─────────────────────────────────────────────

describe('SendEmailSchema', () => {
  it('accepts valid email send request', () => {
    const result = SendEmailSchema.safeParse({
      to: 'user@example.com',
      templateId: 'welcome',
      variables: { displayName: 'Alice', productName: 'LysnrAI' },
      productId: 'lysnrai',
    });
    expect(result.success).toBe(true);
  });

  it('defaults variables to empty object', () => {
    const result = SendEmailSchema.safeParse({
      to: 'user@example.com',
      templateId: 'welcome',
      productId: 'lysnrai',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.variables).toEqual({});
    }
  });

  it('rejects invalid email', () => {
    const result = SendEmailSchema.safeParse({
      to: 'not-an-email',
      templateId: 'welcome',
      productId: 'lysnrai',
    });
    expect(result.success).toBe(false);
  });

  it('rejects empty templateId', () => {
    const result = SendEmailSchema.safeParse({
      to: 'user@example.com',
      templateId: '',
      productId: 'lysnrai',
    });
    expect(result.success).toBe(false);
  });
});

describe('SendPushSchema', () => {
  it('accepts valid push notification request', () => {
    const result = SendPushSchema.safeParse({
      userId: 'usr_123',
      title: 'New Feature',
      body: 'Check out the new dashboard!',
      productId: 'lysnrai',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing title', () => {
    const result = SendPushSchema.safeParse({
      userId: 'usr_123',
      body: 'Check it out',
      productId: 'lysnrai',
    });
    expect(result.success).toBe(false);
  });
});

describe('SendTestEmailSchema', () => {
  it('accepts valid test email request', () => {
    const result = SendTestEmailSchema.safeParse({
      to: 'admin@example.com',
      templateId: 'password-reset',
    });
    expect(result.success).toBe(true);
  });
});

describe('SendTelegramSchema', () => {
  it('accepts valid telegram send request', () => {
    const result = SendTelegramSchema.safeParse({
      text: 'Build succeeded',
      productId: 'lysnrai',
      chatId: '-1001234567890',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing text', () => {
    const result = SendTelegramSchema.safeParse({
      productId: 'lysnrai',
    });
    expect(result.success).toBe(false);
  });
});

describe('SendSlackSchema', () => {
  it('accepts valid slack send request', () => {
    const result = SendSlackSchema.safeParse({
      text: 'Build succeeded',
      productId: 'lysnrai',
      channel: '#ops-alerts',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing text', () => {
    const result = SendSlackSchema.safeParse({
      productId: 'lysnrai',
    });
    expect(result.success).toBe(false);
  });
});

// ── Template Tests ───────────────────────────────────────────

describe('templates', () => {
  it('should have 13 built-in templates', () => {
    expect(BUILT_IN_TEMPLATES.length).toBe(13);
  });

  it('should find template by ID', () => {
    const template = getTemplate('welcome');
    expect(template).toBeDefined();
    expect(template!.name).toBe('Welcome Email');
  });

  it('should return undefined for unknown template', () => {
    expect(getTemplate('nonexistent')).toBeUndefined();
  });

  it('should list all template IDs', () => {
    const ids = listTemplateIds();
    expect(ids).toContain('welcome');
    expect(ids).toContain('password-reset');
    expect(ids).toContain('email-verification');
    expect(ids).toContain('trial-expiring');
    expect(ids).toContain('trial-expired');
    expect(ids).toContain('invitation');
    expect(ids).toContain('payment-failed');
    expect(ids).toContain('license-expiring');
    // Diagnostics templates (Phase 1.5)
    expect(ids).toContain('diagnostics-session-created');
    expect(ids).toContain('diagnostics-session-cancelled');
    expect(ids).toContain('diagnostics-session-completed');
    expect(ids).toContain('diagnostics-fatal-alert');
  });

  it('each template should have required fields', () => {
    for (const template of BUILT_IN_TEMPLATES) {
      expect(template.id).toBeTruthy();
      expect(template.name).toBeTruthy();
      expect(template.subject).toBeTruthy();
      expect(template.bodyHtml).toBeTruthy();
      expect(template.bodyText).toBeTruthy();
      expect(Array.isArray(template.variables)).toBe(true);
    }
  });

  it('each template subject should contain at least one variable placeholder', () => {
    for (const template of BUILT_IN_TEMPLATES) {
      expect(template.subject).toMatch(/\{\{\w+\}\}/);
    }
  });
});

// ── Renderer Tests ───────────────────────────────────────────

describe('interpolate', () => {
  it('should replace simple variables', () => {
    expect(interpolate('Hello, {{name}}!', { name: 'Alice' })).toBe('Hello, Alice!');
  });

  it('should replace multiple variables', () => {
    const result = interpolate('{{greeting}}, {{name}}! Welcome to {{product}}.', {
      greeting: 'Hi',
      name: 'Bob',
      product: 'LysnrAI',
    });
    expect(result).toBe('Hi, Bob! Welcome to LysnrAI.');
  });

  it('should leave unresolved variables as-is', () => {
    expect(interpolate('Hello, {{name}}! Your {{plan}} is active.', { name: 'Alice' })).toBe(
      'Hello, Alice! Your {{plan}} is active.'
    );
  });

  it('should handle empty variables', () => {
    expect(interpolate('No vars here.', {})).toBe('No vars here.');
  });

  it('should handle text with no placeholders', () => {
    expect(interpolate('Plain text', { name: 'Alice' })).toBe('Plain text');
  });
});

describe('renderTemplate', () => {
  it('should render welcome template', () => {
    const rendered = renderTemplate('welcome', {
      displayName: 'Alice',
      productName: 'LysnrAI',
      dashboardUrl: 'https://app.lysnrai.com',
    });
    expect(rendered.subject).toBe('Welcome to LysnrAI!');
    expect(rendered.bodyHtml).toContain('Alice');
    expect(rendered.bodyHtml).toContain('https://app.lysnrai.com');
    expect(rendered.bodyText).toContain('Alice');
  });

  it('should render password-reset template', () => {
    const rendered = renderTemplate('password-reset', {
      displayName: 'Bob',
      productName: 'ChronoMind',
      resetUrl: 'https://chronomind.app/reset?token=abc',
    });
    expect(rendered.subject).toContain('ChronoMind');
    expect(rendered.bodyHtml).toContain('https://chronomind.app/reset?token=abc');
  });

  it('should throw for unknown template', () => {
    expect(() => renderTemplate('nonexistent', {})).toThrow('not found');
  });
});
