import { TestRunner } from './src/tools/autotest/test-runner.js';

function assert(condition, message) {
  if (!condition) throw new Error(message);
}

class FakeLocator {
  constructor(key, counts) {
    this.key = key;
    this.counts = counts;
  }

  first() {
    return this;
  }

  locator(childSelector) {
    return new FakeLocator(`${this.key} ${childSelector}`, this.counts);
  }

  filter({ hasText }) {
    return new FakeLocator(`${this.key}|text=${hasText}`, this.counts);
  }

  async count() {
    return this.counts[this.key] || 0;
  }

  async waitFor() {
    if (await this.count()) return;
    throw new Error('not attached');
  }
}

console.log('\n── AutoTest vlid Resolution ──');

const runner = new TestRunner({ baseUrl: 'https://example.test/app' });
runner.page = {
  locator(selector) {
    return new FakeLocator(selector, {
      '[data-vl-id="submitForm"] button': 1,
      '[data-vl-id="submitForm"]': 1,
      '[data-vl-id="navItem"]|text=课程管理': 1,
    });
  },
  getByRole() {
    return new FakeLocator('__missing__', {});
  },
  getByText() {
    return new FakeLocator('__missing__', {});
  },
  getByPlaceholder() {
    return new FakeLocator('__missing__', {});
  },
  getByLabel() {
    return new FakeLocator('__missing__', {});
  },
};

const submitLocator = await runner._resolveSelector('vlid:submitForm');
assert(submitLocator.key === '[data-vl-id="submitForm"] button', 'vlid button should resolve to the clickable button child before the wrapper');

const navLocator = await runner._resolveSelector('vlid:navItem[text="课程管理"]');
assert(navLocator.key === '[data-vl-id="navItem"]|text=课程管理', 'hybrid vlid selector should preserve text disambiguation for repeated ids');

const strictRunner = new TestRunner({ baseUrl: 'https://example.test/app' });
strictRunner.page = {
  locator(selector) {
    return new FakeLocator(selector, {
      'input:visible, textarea:visible': 1,
    });
  },
  getByRole() {
    return new FakeLocator('__missing__', {});
  },
  getByText() {
    return new FakeLocator('__missing__', {});
  },
  getByPlaceholder() {
    return new FakeLocator('__missing__', {});
  },
  getByLabel() {
    return new FakeLocator('__missing__', {});
  },
};

const strictInputLocator = await strictRunner._resolveSelector('vlid:formDescInput input');
assert(
  strictInputLocator.key === '[data-vl-id="formDescInput"] input, [data-vl-id="formDescInput"] textarea, [data-vl-id="formDescInput"] [contenteditable="true"]',
  'missing vlid input should stay strict on data-vl-id instead of degrading to a generic visible input'
);

const directInputRunner = new TestRunner({ baseUrl: 'https://example.test/app' });
directInputRunner.page = {
  locator(selector) {
    return new FakeLocator(selector, {
      '[data-vl-id="formTitleInput"]': 1,
    });
  },
  getByRole() {
    return new FakeLocator('__missing__', {});
  },
  getByText() {
    return new FakeLocator('__missing__', {});
  },
  getByPlaceholder() {
    return new FakeLocator('__missing__', {});
  },
  getByLabel() {
    return new FakeLocator('__missing__', {});
  },
};

const directInputLocator = await directInputRunner._resolveSelector('vlid:formTitleInput input');
assert(
  directInputLocator.key === '[data-vl-id="formTitleInput"]',
  'vlid input selector should fall back to the base element when the data-vl-id is attached directly to the fillable element'
);

console.log('PASS test-autotest-vlid-resolution.js');
