import { describe, it, expect } from 'vitest';
import type { MessageTemplateModel } from '@zyphon/config-schema';
import {
  applyMessageTemplate,
  missingTemplateVariables,
  orderedTemplateVariableValues,
  renderTemplateString,
} from '../../apps/gateway/src/messaging/template-renderer.js';

const templates: MessageTemplateModel[] = [
  {
    id: 'tpl-login-code',
    name: 'Login code',
    channel: 'sms',
    body: 'Your code is {{code}}. It expires in 10 minutes.',
    dlt_id: '1107161234567890123',
    header: 'ACMEIN',
    category: 'otp',
    variables: ['code'],
  },
  {
    id: 'tpl-invoice-ready',
    name: 'Invoice ready',
    channel: 'email',
    subject: 'Invoice {{number}} is ready',
    body: 'Hi {{name}}, your invoice {{number}} for {{amount}} is ready.',
    variables: ['name', 'number', 'amount'],
  },
];

describe('template-renderer', () => {
  it('substitutes {{variables}}', () => {
    expect(renderTemplateString('Hi {{name}}', { name: 'Ada' })).toBe('Hi Ada');
  });

  it('reports missing variables', () => {
    expect(missingTemplateVariables(['code', 'name'], { code: '1' })).toEqual(['name']);
  });

  it('orders variable values for Fast2SMS-style pipes', () => {
    expect(
      orderedTemplateVariableValues(['name', 'amount'], { amount: '50', name: 'Ada' }),
    ).toEqual(['Ada', '50']);
  });

  it('renders SMS template and attaches DLT metadata', () => {
    const result = applyMessageTemplate(
      {
        type: 'template',
        body: '',
        template: 'tpl-login-code',
        variables: { code: '482913' },
      },
      'sms',
      templates,
    );
    expect(result.ok).toBe(true);
    if (!result.ok) return;
    expect(result.content.body).toContain('482913');
    expect(result.metadata.dlt_template_id).toBe('1107161234567890123');
    expect(result.metadata.template_variable_values).toEqual(['482913']);
  });

  it('renders email subject and body', () => {
    const result = applyMessageTemplate(
      {
        type: 'template',
        body: '',
        template: 'tpl-invoice-ready',
        variables: { name: 'Ada', number: '42', amount: '$10' },
      },
      'email',
      templates,
    );
    expect(result.ok).toBe(true);
    if (!result.ok) return;
    expect(result.content.subject).toBe('Invoice 42 is ready');
    expect(result.content.body).toContain('Ada');
  });

  it('rejects unknown template and channel mismatch', () => {
    expect(
      applyMessageTemplate(
        { type: 'template', body: '', template: 'missing', variables: {} },
        'sms',
        templates,
      ).ok,
    ).toBe(false);

    const mismatch = applyMessageTemplate(
      {
        type: 'template',
        body: '',
        template: 'tpl-login-code',
        variables: { code: '1' },
      },
      'email',
      templates,
    );
    expect(mismatch.ok).toBe(false);
    if (mismatch.ok) return;
    expect(mismatch.code).toBe('TEMPLATE_CHANNEL_MISMATCH');
  });
});
