/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {LitElement, html, CSSResultArray, TemplateResult} from 'lit';
import { customElement, query, queryAll, property } from 'lit/decorators.js';
import {styles} from './nile-button-toggle-group.css';
import NileButtonToggle from '../nile-button-toggle/nile-button-toggle';
import NileElement from '../internal/nile-element';
/**
 * Nile icon component.
 *
 * @tag nile-button-toggle-group
 *
 */
@customElement('nile-button-toggle-group')
export class NileButtonToggleGroup extends NileElement {
  /**
   * The styles for ButtonToggleGroup
   * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]`
   */
  public static get styles(): CSSResultArray {
    return [styles];
  }

  @queryAll('nile-button-toggle') private toggles!: NodeListOf<NileButtonToggle>;

  @query('slot:not([name])') private defaultSlot!: HTMLSlotElement;

  @property({ type: Boolean, reflect: true }) public disabled: boolean = false;

  @property() value:String[]|String='';

  @property({type:Boolean}) multiple:boolean=false;

  @property({type: Boolean}) disableUserInput: Boolean = false;

  @property({type:Boolean}) emptyDefault:boolean=false;

  firstUpdated() {
    this.defaultSlot.addEventListener('slotchange', () =>
      this.updateTogglePositions()
    );
    this.addEventListener('nile-toggle-change', this.handleToggle);
    this.updateTogglePositions();
    if (!this.value) {
      if (!this.multiple) {
        const toggles = Array.from(this.querySelectorAll<NileButtonToggle>('nile-button-toggle'));
        const activeToggle = toggles.find(e => e.active && !e.disabled);
        if (activeToggle) this.value = activeToggle.value;
        else if(toggles.length && !this.emptyDefault && !this.disabled) this.value = toggles[0].value;
        else this.value = '';
      }
      else this.value = [];
    }
    this.setBtnState()
  }

  updated(changedProperties: Map<string | number | symbol, unknown>) {
    super.updated(changedProperties);
    if (changedProperties.has('disabled')) {
      this.updateDisabledState();
    }
    if(changedProperties.has('multiple')){
      if(!this.value) this.value=this.multiple?[]:''
      this.setBtnState()
    }
    if(changedProperties.has('value')){
      this.setBtnState()
    }
  }

  private updateDisabledState() {
    const assignedNodes = this.defaultSlot.assignedNodes({ flatten: true });
    const toggles = assignedNodes.filter(
      node => node instanceof NileButtonToggle
    ) as NileButtonToggle[];

    toggles.forEach(toggle => {
      if (!toggle.disabled) {
        toggle.disabled = this.disabled;
      }
    });
  }

  updateTogglePositions() {
    const assignedNodes = this.defaultSlot.assignedNodes({ flatten: true });
    const toggles = assignedNodes.filter(
      node => node instanceof NileButtonToggle
    ) as NileButtonToggle[];

    toggles.forEach((toggle, index) => {
      toggle.initial = index === 0;
      toggle.middle = index > 0 && index < toggles.length - 1;
      toggle.end = index === toggles.length - 1;
    });
  }

  handleToggle(event: CustomEvent) {
    event.stopPropagation()
    if (this.disabled) return;
    if(!this.multiple && event.detail.value == this.value) return;
    if(this.disableUserInput) return;
    this.setValue(event.detail.value);
    this.emit('nile-change', { value: this.value });
  }

  setValue(btnValue:string){
    if(this.multiple && btnValue){
      // @ts-ignore
      if(this.value.includes(btnValue)) this.value=this.value.filter(e=>e!=btnValue)
      else this.value=[...this.value,btnValue]
    }
    else{
      this.value=btnValue;
    }
    this.setBtnState()
  }

  setBtnState(){
    const toggles = Array.from(this.querySelectorAll<NileButtonToggle>('nile-button-toggle'));
    if(this.multiple){
      toggles.forEach(btn=>{
      if(this.value.includes(btn.value)) btn.active=true;
      else btn.active=false;
    })
    }
    else toggles.forEach(btn=>{
      if(btn.value==this.value) btn.active=true;
      else btn.active=false;
    })
  }

  /**
   * Render method
   * @slot This is a slot test
   */
  public render(): TemplateResult {
    return html`<slot> </slot>`;
  }

  /* #endregion */
}

export default NileButtonToggleGroup;

declare global {
  interface HTMLElementTagNameMap {
    'nile-button-toggle-group': NileButtonToggleGroup;
  }
}
