import { describe, it, expect } from 'vitest';
import { EditorState } from '@codemirror/state';
import { CompletionContext } from '@codemirror/autocomplete';
import { mustacheCompletionSource } from './mustache-completion';
import { availableVariables } from './alert-variables';

function makeContext(doc: string, pos: number): CompletionContext {
  const state = EditorState.create({ doc });
  return new CompletionContext(state, pos, true);
}

describe('mustacheCompletionSource', () => {
  const source = mustacheCompletionSource(availableVariables('ROUTE_METRIC'));

  it('returns null outside a Mustache tag', () => {
    const ctx = makeContext('Hello world', 5);
    expect(source(ctx)).toBeNull();
  });

  it('offers completions right after {{', () => {
    const ctx = makeContext('Hello {{', 8);
    const result = source(ctx)!;
    expect(result).not.toBeNull();
    const paths = result.options.map((o) => o.label);
    expect(paths).toContain('env.slug');
    expect(paths).toContain('alert.firedAt');
  });

  it('narrows as user types', () => {
    const ctx = makeContext('{{ale', 5);
    const result = source(ctx)!;
    const paths = result.options.map((o) => o.label);
    expect(paths.every((p) => p.startsWith('ale'))).toBe(true);
    expect(paths).toContain('alert.firedAt');
    expect(paths).not.toContain('env.slug');
  });

  it('does not offer out-of-kind vars', () => {
    const ctx = makeContext('{{exchange', 10);
    const result = source(ctx)!;
    // ROUTE_METRIC does not include exchange.* — expect no exchange. completions
    expect(result.options).toHaveLength(0);
  });
});
