/**
 * Copyright Aquera Inc 2025
 *
 * 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 { html, CSSResultArray, TemplateResult } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { styles } from './nile-inline-sidebar-panel-group.css';
import NileElement from '../internal/nile-element';
import type { NileInlineSidebarPanel } from '../nile-inline-sidebar-panel/nile-inline-sidebar-panel';

/**
 * Layout container that positions a `nile-inline-sidebar` beside one or more
 * `nile-inline-sidebar-panel` elements. Handles panel switching when sidebar
 * items are clicked.
 *
 * @tag nile-inline-sidebar-panel-group
 *
 * @attr placement - Mirror of the sidebar's placement. Controls flex direction.
 *
 * @slot sidebar - Slot for the `nile-inline-sidebar` element.
 * @slot - Default slot for `nile-inline-sidebar-panel` elements.
 *
 * @csspart base - The outer flex container.
 * @csspart sidebar-container - Wrapper around the sidebar slot.
 * @csspart panel-container - Wrapper around the panel slot.
 */
@customElement('nile-inline-sidebar-panel-group')
export class NileInlineSidebarPanelGroup extends NileElement {
  /** Mirrors the sidebar's placement to control layout direction. */
  @property({ type: String, reflect: true }) placement: 'left' | 'right' = 'left';

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

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

  connectedCallback() {
    super.connectedCallback();
    this.addEventListener('nile-click', this.handleSidebarItemClick);
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    this.removeEventListener('nile-click', this.handleSidebarItemClick);
  }

  private get panels(): NileInlineSidebarPanel[] {
    if (!this.defaultSlot) return [];
    return this.defaultSlot
      .assignedElements({ flatten: true })
      .filter(
        (el): el is NileInlineSidebarPanel =>
          el.tagName.toLowerCase() === 'nile-inline-sidebar-panel'
      );
  }

  private handleSidebarItemClick = (event: Event) => {
    const detail = (event as CustomEvent).detail;
    const panelName: string | undefined = detail?.item?.panel;
    if (!panelName) return;

    this.activatePanel(panelName);
  };

  /** Activate a panel by name, deactivating all others. */
  public activatePanel(name: string) {
    const allPanels = this.panels;
    allPanels.forEach(panel => {
      panel.active = panel.name === name;
    });

    this.emit('nile-panel-change', { panel: name });
  }

  public render(): TemplateResult {
    return html`
      <div class="panel-group" part="base">
        <div class="sidebar-container" part="sidebar-container">
          <slot name="sidebar"></slot>
        </div>
        <div class="panel-container" part="panel-container">
          <slot
            @slotchange=${() => this.requestUpdate()}
          ></slot>
        </div>
      </div>
    `;
  }
}

export default NileInlineSidebarPanelGroup;

declare global {
  interface HTMLElementTagNameMap {
    'nile-inline-sidebar-panel-group': NileInlineSidebarPanelGroup;
  }
}
