import {CommonModule} from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  EventEmitter,
  Input,
  Output,
  ViewChild,
  ViewEncapsulation
} from '@angular/core';
import {SwitchValue, SwitchValues, SwitchVariant} from './switch.model';

@Component({
  selector: 'nj-switch',
  templateUrl: './switch.component.html',
  styleUrls: ['./switch.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  standalone: true,
  imports: [CommonModule]
})
export class SwitchComponent {

  /**
   * @ignore
   */
  private readonly switchClassName = 'nj-switch';

  /**
   * Switch variant theme
   */
  @Input() variant: SwitchVariant = 'primary';

  /**
   * Whether switch is disabled or not
   */
  @Input() isDisabled: boolean;

  /**
   * Values that will be emitted by the switch on toggle
   */
  @Input() values: SwitchValues;

  /**
   * Whether switch is checked or not
   */
  @Input() isChecked = false;

  /**
   * id of the input inside of the switch
   */
  @Input() id: string;

  /**
   * name of the input inside of the switch
   */
  @Input() name: string;

  /**
   * Aria label, for accessibility reasons
   */
  @Input() ariaLabel: string;

  /**
   * Aria labelled by, for accessibility reasons
   */
  @Input() ariaLabelledBy: string;

  /**
   * title of the input inside of the switch
   */
  @Input() title: string;

  /**
   * Output that emits a SwitchValue when switch value change occurs
   */
  @Output() valueChange: EventEmitter<SwitchValue> = new EventEmitter<SwitchValue>();

  /**
   * @ignore
   */
  @ViewChild('input')
  private _inputElement: ElementRef<HTMLInputElement>;

  constructor() {
  }

  /**
   * @ignore
   */
  getButtonMainClass(): string {
    if (!this.variant) {
      return '';
    }
    return `${this.switchClassName}--${this.variant}`;
  }

  /**
   * @ignore
   */
  _onChangeEvent(event: Event) {
    event.stopPropagation();
    if (this._inputElement?.nativeElement) {
      this.isChecked = this._inputElement.nativeElement.checked;
      if (this.values) {
        this.valueChange.emit(this.isChecked ? this.values.right : this.values.left);
      }
    }
  }

  /**
   * @ignore
   */
  _onInputClick(event: Event) {
    // We have to stop propagation for click events on the visually hidden input element.
    // By default, when a user clicks on a label element, a generated click event will be
    // dispatched on the associated input element. Since we are using a label element as our
    // root container, the click event on the `slide-toggle` will be executed twice.
    // The real click event will bubble up, and the generated click event also tries to bubble up.
    // This will lead to multiple click events.
    // Preventing bubbling for the second event will solve that issue.
    event.stopPropagation();
  }
}
