// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* eslint-disable @devtools/no-lit-render-outside-of-view, @devtools/enforce-custom-element-definitions-location */

import {html, nothing, render} from '../../lit/lit.js';
import * as VisualLogging from '../../visual_logging/visual_logging.js';

import switchStyles from './switch.css.js';

export class SwitchChangeEvent extends Event {
  static readonly eventName = 'switchchange';

  constructor(readonly checked: boolean) {
    super(SwitchChangeEvent.eventName);
  }
}

export class Switch extends HTMLElement {
  readonly #shadow = this.attachShadow({mode: 'open'});
  #checked = false;
  #disabled = false;
  #jslogContext = '';
  #label = '';

  connectedCallback(): void {
    this.#render();
  }

  set checked(isChecked: boolean) {
    this.#checked = isChecked;
    this.#render();
  }

  get checked(): boolean {
    return this.#checked;
  }

  set disabled(isDisabled: boolean) {
    this.#disabled = isDisabled;
    this.#render();
  }

  get disabled(): boolean {
    return this.#disabled;
  }

  get jslogContext(): string {
    return this.#jslogContext;
  }

  set jslogContext(jslogContext: string) {
    this.#jslogContext = jslogContext;
    this.#render();
  }

  get label(): string {
    return this.#label;
  }

  set label(label: string) {
    this.#label = label;
    this.#render();
  }

  #handleChange = (ev: Event): void => {
    this.#checked = (ev.target as HTMLInputElement).checked;
    this.dispatchEvent(new SwitchChangeEvent(this.#checked));
  };

  #render(): void {
    const jslog = this.#jslogContext && VisualLogging.toggle(this.#jslogContext).track({change: true});
    /* eslint-disable @devtools/inject-checkbox-styles */
    // clang-format off
    render(html`
    <style>${switchStyles}</style>
    <label jslog=${jslog || nothing}>
      <input type="checkbox"
        aria-label=${this.#label || nothing}
        @change=${this.#handleChange}
        ?disabled=${this.#disabled}
        .checked=${this.#checked}
      >
      <span class="slider" @click=${(ev: Event) => ev.stopPropagation()}></span>
    </label>
    `, this.#shadow, {host: this});
    // clang-format on
    /* eslint-enable @devtools/inject-checkbox-styles */
  }
}

customElements.define('devtools-switch', Switch);

declare global {
  interface HTMLElementTagNameMap {
    'devtools-switch': Switch;
  }
}

declare global {
  interface HTMLElementEventMap {
    [SwitchChangeEvent.eventName]: SwitchChangeEvent;
  }
}
