/**
 * 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,
  PropertyValues,
} from 'lit';
import {
  customElement,
  query,
  state,
  queryAll,
  queryAssignedElements,
  queryAssignedNodes,
  property
} from 'lit/decorators.js';
import { styles } from './nile-table-body.css';
import NileElement from '../internal/nile-element';
import { getInnerHTML } from '../slot';
import { hasResizableColumns } from '../internal/resizable-table-helper';
import { ifDefined } from 'lit/directives/if-defined.js';

/**
 * nile-table-body component.
 *
 * @tag nile-table-body
 *
 */
@customElement('nile-table-body')
export class NileTableBody extends NileElement {
  /**
   * The styles for TableBody
   * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]`
   */

  @query('slot') defaultSlot: HTMLSlotElement;
  @queryAssignedNodes({ flatten: true }) _childNodes!: Array<HTMLElement>;
  @property() type: 'primary' | 'secondary' = 'primary';
  @property() bodyStyle: string;

  @state() private rows_data: any[] = [];
  @state() private header_rows_data: any[] = [];
  @state() private sort__index: number;
  @state() private search__index: number;
  @state() private hasResizableColumns = false;

  public static get styles(): CSSResultArray {
    return [styles];
  }

  protected firstUpdated(_changedProperties: PropertyValues): void {
    this.emit('nile-body-load', { value: this.type, comp:this },true,false)
  }

  /* #endregion */

  /* #region Methods */

  private getChildren(child: any, tagname: string) {
    return child.querySelectorAll(tagname);
  }

  private getIndexValue(index__value: string): number {
    return this.header_rows_data.indexOf(index__value);
  }

  private checkForResizableColumns() {
    this.hasResizableColumns = hasResizableColumns(this);
  }

  handleSlotchange(e: any) {
    let row_data: any = [];
    this._childNodes.forEach((child: any) => {
      if (child.tagName && child?.tagName?.toLowerCase() === 'nile-table-row') {
        let nilerows = this.getChildren(child, 'nile-table-cell-item');
        if (nilerows.length > 0) {
          nilerows.forEach((element: { innerHTML: any }) => {
            row_data.push(element.innerHTML);
          });
          this.rows_data.push(row_data);
        } else {
          let nileheaders = this.getChildren(child, 'nile-table-header-item');
          if (nileheaders.length > 0) {
            nileheaders.forEach((header: HTMLSlotElement, index: number) => {
              this.header_rows_data.push(header.innerHTML);
            });
          }
        }
        row_data = [];
      }
    });
    
    this.checkForResizableColumns();
  }

  private handleSort(e: any) {
    const { curr_sort_string, order } = e.detail.value;
    const header_index = this.getIndexValue(curr_sort_string);
    this.emit('nile-sort', {
      value: { header_index, curr_sort_string, order },
    });
  }

  private handleSearch(e: any) {
    const searchText = e.detail.value;
    this.search__index = this.getIndexValue(e.target.textContent);
    this.emit('nile-table-search', {
      index: this.search__index,
      value: searchText,
    });
  }

  public render(): TemplateResult {
    return html`
      <div class="base" part="base">
        <slot name="table__header" class="table__header"></slot>
        <slot
          @slotchange=${this.handleSlotchange}
          @nile-click-sort=${this.handleSort}
          class="nile__table__body"
          style=${ifDefined(this.bodyStyle ? `display: ${this.bodyStyle}` : undefined)}
          ?resizable=${this.hasResizableColumns}
          @nile-search=${this.handleSearch}
        ></slot>
      </div>
    `;
  }

  /* #endregion */
}

export default NileTableBody;

declare global {
  interface HTMLElementTagNameMap {
    'nile-table-body': NileTableBody;
  }
}
