/**
 * 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, property } from 'lit/decorators.js';
import {styles} from './nile-tab.css';

import '../nile-icon-button/nile-icon-button';
import { classMap } from 'lit/directives/class-map.js';
import { query } from 'lit/decorators.js';
import { watch } from '../internal/watch';
import NileElement from '../internal/nile-element';
import type { CSSResultGroup, PropertyValueMap } from 'lit';

let id = 0;

/**
 * Nile icon component.
 *
 * @tag nile-tab
 *
 *
 * @dependency nile-icon-button
 *
 * @slot - The tab's label.
 *
 * @event nile-close - Emitted when the tab is closable and the close button is activated.
 *
 * @csspart base - The component's base wrapper.
 * @csspart close-button - The close button, an `<nile-icon-button>`.
 * @csspart close-button__base - The close button's exported `base` part.
 */
@customElement('nile-tab')
export class NileTab extends NileElement {
  static styles: CSSResultGroup = styles;

  private readonly attrId = ++id;
  private readonly componentId = `nile-tab-${this.attrId}`;

  @query('.tab') tab: HTMLElement;

  /** The name of the tab panel this tab is associated with. The panel must be located in the same tab group. */
  @property({ reflect: true }) panel = '';

  /** Draws the tab in an active state. */
  @property({ type: Boolean, reflect: true }) active = false;

  /** Makes the tab closable and shows a close button. */
  @property({ type: Boolean }) closable = false;

  /** Disables the tab and prevents selection. */
  @property({ type: Boolean, reflect: true }) disabled = false;

  @property({ type: Boolean, reflect: true }) centered = false;

  connectedCallback() {
    super.connectedCallback();
    this.setAttribute('role', 'tab');
  }

  private handleCloseClick(event: Event) {
    event.stopPropagation();
    this.emit('nile-close');
  }

  @watch('active')
  handleActiveChange() {
    if(this.active) this.emit('nile-toggle-change',{ value: this.panel })
    this.setAttribute('aria-selected', this.active ? 'true' : 'false');
  }

  @watch('disabled')
  handleDisabledChange() {
    this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
  }

  /** Sets focus to the tab. */
  focus(options?: FocusOptions) {
    this.tab.focus(options);
  }

  /** Removes focus from the tab. */
  blur() {
    this.tab.blur();
  }

  render() {
    // If the user didn't provide an ID, we'll set one so we can link tabs and tab panels with aria labels
    this.id = this.id.length > 0 ? this.id : this.componentId;

    return html`
      <div
        part="base"
        class=${classMap({
          tab: true,
          'tab--centered': this.centered,
          'tab--active': this.active,
          'tab--closable': this.closable,
          'tab--disabled': this.disabled
        })}
        tabindex=${this.disabled ? '-1' : '0'}
      >
      <slot name="prefix"></slot>
        <slot></slot>
        ${this.closable
          ? html`
              <nile-icon-button
                part="close-button"
                exportparts="base:close-button__base"
                name="var(--nile-icon-close, var(--ng-icon-x-close))"
                library="system"
                label="close"
                class="tab__close-button"
                @click=${this.handleCloseClick}
                tabindex="-1"
              ></nile-icon-button>
            `
          : ''}
      </div>
    `;
  }
}

export default NileTab;

declare global {
  interface HTMLElementTagNameMap {
    'nile-tab': NileTab;
  }
}
