import { expect, fixture, html, elementUpdated } from '@open-wc/testing';
import './nile-checkbox';
import NileCheckbox from './nile-checkbox';

describe('NileCheckbox', () => {
  // === RENDERING ===
  it('1. should render without errors', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el).to.exist;
  });

  it('2. should have a shadow root', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.shadowRoot).to.not.be.null;
  });

  it('3. should render an input of type checkbox', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input[type="checkbox"]');
    expect(input).to.exist;
  });

  it('4. should render a label element', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label).to.exist;
  });

  it('5. should render default slot for label content', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const slot = el.shadowRoot!.querySelector('slot:not([name])');
    expect(slot).to.exist;
  });

  it('6. should render slot content', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox>Check me</nile-checkbox>`);
    expect(el.textContent!.trim()).to.equal('Check me');
  });

  // === DEFAULT PROPERTIES ===
  it('7. should have checked default to false', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.checked).to.be.false;
  });

  it('8. should have disabled default to false', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.disabled).to.be.false;
  });

  it('9. should have indeterminate default to false', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.indeterminate).to.be.false;
  });

  it('10. should have size default to medium', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.size).to.equal('medium');
  });

  it('11. should have name default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.name).to.equal('');
  });

  it('12. should have label default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.label).to.equal('');
  });

  it('13. should have required default to false', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.required).to.be.false;
  });

  it('14. should have helpText default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.helpText).to.equal('');
  });

  it('15. should have errorMessage default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.errorMessage).to.equal('');
  });

  it('16. should have form default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.form).to.equal('');
  });

  it('17. should have title default to empty string', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.title).to.equal('');
  });

  it('18. should have showHelpText default to false', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.showHelpText).to.be.false;
  });

  // === CHECKED STATE ===
  it('19. should be checked when checked attribute is set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    expect(el.checked).to.be.true;
  });

  it('20. should apply checked class when checked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--checked')).to.be.true;
  });

  it('21. should reflect checked attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    expect(el.hasAttribute('checked')).to.be.true;
  });

  it('22. should set aria-checked to true when checked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.getAttribute('aria-checked')).to.equal('true');
  });

  it('23. should set aria-checked to false when unchecked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.getAttribute('aria-checked')).to.equal('false');
  });

  it('24. should show checked icon when checked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__checked-icon');
    expect(icon).to.exist;
  });

  it('25. should not show checked icon when unchecked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__checked-icon');
    expect(icon).to.be.null;
  });

  // === DISABLED STATE ===
  it('26. should be disabled when disabled attribute is set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox disabled></nile-checkbox>`);
    expect(el.disabled).to.be.true;
  });

  it('27. should apply disabled class', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox disabled></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--disabled')).to.be.true;
  });

  it('28. should disable the input when disabled', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox disabled></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.disabled).to.be.true;
  });

  it('29. should reflect disabled attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox disabled></nile-checkbox>`);
    expect(el.hasAttribute('disabled')).to.be.true;
  });

  // === INDETERMINATE STATE ===
  it('30. should be indeterminate when attribute is set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    expect(el.indeterminate).to.be.true;
  });

  it('31. should apply indeterminate class', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--indeterminate')).to.be.true;
  });

  it('32. should show indeterminate icon when indeterminate', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__indeterminate-icon');
    expect(icon).to.exist;
  });

  it('33. should not show indeterminate icon when checked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked indeterminate></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__indeterminate-icon');
    expect(icon).to.be.null;
  });

  it('34. should reflect indeterminate attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    expect(el.hasAttribute('indeterminate')).to.be.true;
  });

  // === SIZE ===
  it('35. should support small size', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox size="small"></nile-checkbox>`);
    expect(el.size).to.equal('small');
  });

  it('36. should support medium size', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox size="medium"></nile-checkbox>`);
    expect(el.size).to.equal('medium');
  });

  it('37. should support large size', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox size="large"></nile-checkbox>`);
    expect(el.size).to.equal('large');
  });

  it('38. should apply medium class by default', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--medium')).to.be.true;
  });

  it('39. should reflect size attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox size="large"></nile-checkbox>`);
    expect(el.getAttribute('size')).to.equal('large');
  });

  // === EVENTS ===
  it('40. should emit nile-change when clicked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let changeEmitted = false;
    el.addEventListener('nile-change', () => (changeEmitted = true));
    input!.click();
    expect(changeEmitted).to.be.true;
  });

  it('41. should emit nile-change with checked detail', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let detail: any = null;
    el.addEventListener('nile-change', (e: any) => (detail = e.detail));
    input!.click();
    expect(detail).to.exist;
    expect(detail.checked).to.be.true;
  });

  it('42. should emit valueChange when clicked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let changeEmitted = false;
    el.addEventListener('valueChange', () => (changeEmitted = true));
    input!.click();
    expect(changeEmitted).to.be.true;
  });

  it('43. should emit blur event on blur', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let blurEmitted = false;
    el.addEventListener('blur', () => (blurEmitted = true));
    input!.dispatchEvent(new FocusEvent('blur'));
    expect(blurEmitted).to.be.true;
  });

  it('44. should emit focus event on focus', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let focusEmitted = false;
    el.addEventListener('focus', () => (focusEmitted = true));
    input!.dispatchEvent(new FocusEvent('focus'));
    expect(focusEmitted).to.be.true;
  });

  it('45. should emit input event on input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let inputEmitted = false;
    el.addEventListener('input', () => (inputEmitted = true));
    input!.dispatchEvent(new Event('input'));
    expect(inputEmitted).to.be.true;
  });

  it('46. should emit nile-init on connected', async () => {
    let initEmitted = false;
    const container = await fixture(html`<div></div>`);
    const el = document.createElement('nile-checkbox') as NileCheckbox;
    el.addEventListener('nile-init', () => (initEmitted = true));
    container.appendChild(el);
    await el.updateComplete;
    expect(initEmitted).to.be.true;
  });

  it('47. should emit nile-destroy on disconnected', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    let destroyEmitted = false;
    el.addEventListener('nile-destroy', () => (destroyEmitted = true));
    el.remove();
    expect(destroyEmitted).to.be.true;
  });

  // === CLICK BEHAVIOR ===
  it('48. should toggle checked on click', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.click();
    expect(el.checked).to.be.true;
  });

  it('49. should toggle from checked to unchecked on click', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.click();
    expect(el.checked).to.be.false;
  });

  it('50. should clear indeterminate on click', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.click();
    expect(el.indeterminate).to.be.false;
  });

  // === FOCUS/BLUR METHODS ===
  it('51. should focus programmatically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.focus();
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--focused')).to.be.true;
  });

  it('52. should blur programmatically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.focus();
    await el.updateComplete;
    el.blur();
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--focused')).to.be.false;
  });

  it('53. should click programmatically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.click();
    await el.updateComplete;
    expect(el.checked).to.be.true;
  });

  // === LABEL PROPERTY ===
  it('54. should display label text', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox label="My Label"></nile-checkbox>`);
    const labelDiv = el.shadowRoot!.querySelector('.checkbox__label');
    expect(labelDiv!.textContent).to.contain('My Label');
  });

  it('55. should reflect label attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox label="Test"></nile-checkbox>`);
    expect(el.getAttribute('label')).to.equal('Test');
  });

  // === NAME ===
  it('56. should set name on input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox name="myCheckbox"></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.getAttribute('name')).to.equal('myCheckbox');
  });

  // === REQUIRED ===
  it('57. should set required on input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox required></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.required).to.be.true;
  });

  it('58. should reflect required attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox required></nile-checkbox>`);
    expect(el.hasAttribute('required')).to.be.true;
  });

  // === HELP TEXT ===
  it('59. should render help text when set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox help-text="Some help"></nile-checkbox>`);
    const helpText = el.shadowRoot!.querySelector('nile-form-help-text');
    expect(helpText).to.exist;
  });

  it('60. should not render help text when empty', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const helpText = el.shadowRoot!.querySelector('nile-form-help-text');
    expect(helpText).to.be.null;
  });

  it('61. should reflect help-text attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox help-text="Help"></nile-checkbox>`);
    expect(el.getAttribute('help-text')).to.equal('Help');
  });

  it('62. should add full-width class when helpText is set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox help-text="Help"></nile-checkbox>`);
    expect(el.classList.contains('full-width')).to.be.true;
  });

  it('63. should remove full-width class when helpText is empty', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.classList.contains('full-width')).to.be.false;
  });

  // === ERROR MESSAGE ===
  it('64. should render error message when set', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox error-message="Error!"></nile-checkbox>`);
    const errorMsg = el.shadowRoot!.querySelector('nile-form-error-message');
    expect(errorMsg).to.exist;
  });

  it('65. should not render error message when empty', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const errorMsg = el.shadowRoot!.querySelector('nile-form-error-message');
    expect(errorMsg).to.be.null;
  });

  it('66. should reflect error-message attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox error-message="Err"></nile-checkbox>`);
    expect(el.getAttribute('error-message')).to.equal('Err');
  });

  // === DYNAMIC PROPERTY CHANGES ===
  it('67. should update checked dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.checked = true;
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--checked')).to.be.true;
  });

  it('68. should update disabled dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.disabled = true;
    await el.updateComplete;
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.disabled).to.be.true;
  });

  it('69. should update indeterminate dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.indeterminate = true;
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--indeterminate')).to.be.true;
  });

  it('70. should update size dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.size = 'large';
    await el.updateComplete;
    expect(el.getAttribute('size')).to.equal('large');
  });

  it('71. should update label dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.label = 'New Label';
    await el.updateComplete;
    const labelDiv = el.shadowRoot!.querySelector('.checkbox__label');
    expect(labelDiv!.textContent).to.contain('New Label');
  });

  it('72. should update name dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.name = 'newName';
    await el.updateComplete;
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.getAttribute('name')).to.equal('newName');
  });

  it('73. should update helpText dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.helpText = 'New Help';
    await el.updateComplete;
    const helpText = el.shadowRoot!.querySelector('nile-form-help-text');
    expect(helpText).to.exist;
  });

  it('74. should update errorMessage dynamically', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.errorMessage = 'New Error';
    await el.updateComplete;
    const errorMsg = el.shadowRoot!.querySelector('nile-form-error-message');
    expect(errorMsg).to.exist;
  });

  // === CSS PARTS ===
  it('75. should have base part', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const base = el.shadowRoot!.querySelector('[part~="base"]');
    expect(base).to.exist;
  });

  it('76. should have control part', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const control = el.shadowRoot!.querySelector('[part~="control"]');
    expect(control).to.exist;
  });

  it('77. should have control--checked part when checked', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked></nile-checkbox>`);
    const control = el.shadowRoot!.querySelector('[part~="control--checked"]');
    expect(control).to.exist;
  });

  it('78. should have control--indeterminate part when indeterminate', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate></nile-checkbox>`);
    const control = el.shadowRoot!.querySelector('[part~="control--indeterminate"]');
    expect(control).to.exist;
  });

  it('79. should have label part', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('[part~="label"]');
    expect(label).to.exist;
  });

  // === COMBINED STATES ===
  it('80. should handle checked and disabled together', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked disabled></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--checked')).to.be.true;
    expect(label!.classList.contains('checkbox--disabled')).to.be.true;
  });

  it('81. should show checked icon with different color when checked and disabled', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked disabled></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__checked-icon');
    expect(icon).to.exist;
  });

  it('82. should show indeterminate icon when indeterminate and disabled', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox indeterminate disabled></nile-checkbox>`);
    const icon = el.shadowRoot!.querySelector('.checkbox__indeterminate-icon');
    expect(icon).to.exist;
  });

  it('83. should handle checked, disabled, and indeterminate together', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox checked disabled indeterminate></nile-checkbox>`);
    expect(el.checked).to.be.true;
    expect(el.disabled).to.be.true;
    expect(el.indeterminate).to.be.true;
  });

  it('84. should handle help text and error message together', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox help-text="Help" error-message="Error"></nile-checkbox>`);
    const helpText = el.shadowRoot!.querySelector('nile-form-help-text');
    const errorMsg = el.shadowRoot!.querySelector('nile-form-error-message');
    expect(helpText).to.exist;
    expect(errorMsg).to.exist;
  });

  // === TITLE ===
  it('85. should set title on internal input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox title="My Title"></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    expect(input!.getAttribute('title')).to.equal('My Title');
  });

  // === FORM ===
  it('86. should reflect form attribute', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox form="myForm"></nile-checkbox>`);
    expect(el.getAttribute('form')).to.equal('myForm');
  });

  // === FOCUSED STATE ===
  it('87. should apply focused class on focus', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.dispatchEvent(new FocusEvent('focus'));
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--focused')).to.be.true;
  });

  it('88. should remove focused class on blur', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.dispatchEvent(new FocusEvent('focus'));
    await el.updateComplete;
    input!.dispatchEvent(new FocusEvent('blur'));
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--focused')).to.be.false;
  });

  // === MULTIPLE CLICKS ===
  it('89. should toggle multiple times', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    input!.click();
    expect(el.checked).to.be.true;
    input!.click();
    expect(el.checked).to.be.false;
    input!.click();
    expect(el.checked).to.be.true;
  });

  it('90. should emit change event each toggle', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    let count = 0;
    el.addEventListener('nile-change', () => count++);
    input!.click();
    input!.click();
    input!.click();
    expect(count).to.equal(3);
  });

  // === CONTROL CLASS ===
  it('91. should have checkbox class on label', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox')).to.be.true;
  });

  it('92. should have checkbox__input class on input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('.checkbox__input');
    expect(input).to.exist;
  });

  it('93. should have checkbox__control class on span', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const control = el.shadowRoot!.querySelector('.checkbox__control');
    expect(control).to.exist;
  });

  it('94. should have checkbox__label class', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const labelDiv = el.shadowRoot!.querySelector('.checkbox__label');
    expect(labelDiv).to.exist;
  });

  // === VALUE ===
  it('95. should set value on input', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox .value=${true}></nile-checkbox>`);
    expect(el.value).to.be.true;
  });

  // === EDGE CASES ===
  it('96. should handle empty label (boolean false label)', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const labelDiv = el.shadowRoot!.querySelector('.checkbox__label');
    expect(labelDiv).to.exist;
  });

  it('97. should update full-width class when helpText changes from set to empty', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox help-text="Help"></nile-checkbox>`);
    expect(el.classList.contains('full-width')).to.be.true;
    el.helpText = '';
    await el.updateComplete;
    expect(el.classList.contains('full-width')).to.be.false;
  });

  it('98. should support setting checked via property after render', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    expect(el.checked).to.be.false;
    el.checked = true;
    await el.updateComplete;
    expect(el.checked).to.be.true;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--checked')).to.be.true;
  });

  it('99. should support setting indeterminate via property after render', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    el.indeterminate = true;
    await el.updateComplete;
    const label = el.shadowRoot!.querySelector('label');
    expect(label!.classList.contains('checkbox--indeterminate')).to.be.true;
  });

  it('100. should handle rapid toggling', async () => {
    const el = await fixture<NileCheckbox>(html`<nile-checkbox></nile-checkbox>`);
    const input = el.shadowRoot!.querySelector('input');
    for (let i = 0; i < 10; i++) {
      input!.click();
    }
    expect(el.checked).to.be.false; // even number of clicks
  });
});
