import { html, TemplateResult } from "lit";
import { property, query, queryAssignedElements } from "lit/decorators.js";
import { ClassInfo, classMap } from "lit/directives/class-map.js";
import { Button } from "./Button.js";
import UiRipple from "../effects/ripple.js";
import { BeginPressConfig, EndPressConfig } from "../controllers/ActionController.js";
import { ripple } from "../effects/rippleDirective.js";
import '../../define/ui/ui-ripple.js';
import { check } from "../icons/Icons.js";

/**
 * @fires trigger - When a button is triggered.
 * @slot - Default slot for the label
 * @slot icon - A slot to render an icon.
 */
export default class SegmentedButton extends Button {
  @query('ui-ripple') ripple!: UiRipple;

  /**
   * Whether the button is selected.
   * @attribute
   */
  @property({ type: Boolean }) selected = false;

  @queryAssignedElements({ flatten: true, slot: 'icon' }) protected leadingIcons!: HTMLElement[];

  constructor() {
    super();
    this.addEventListener('pointerenter', this.handlePointerEnter.bind(this));
  }

  override beginPress(options: BeginPressConfig): void {
    super.beginPress(options);
    this.ripple.beginPress(options.positionEvent);
  }

  override endPress(options: EndPressConfig): void {
    super.endPress(options);
    this.ripple.endPress();

    if (!options.cancelled) {
      this.dispatchEvent(new Event('trigger', { bubbles: true, composed: true }));
    }
  }

  protected handlePointerEnter(e: PointerEvent): void {
    this.ripple.beginHover(e);
  }

  override handlePointerLeave(e: PointerEvent): void {
    super.handlePointerLeave(e);
    this.ripple.endHover();
  }

  protected handleIconSlotChange(): void {
    this.requestUpdate();
  }

  protected override render(): TemplateResult {
    const { pressed = false, selected = false } = this;
    const surfaceClasses = classMap({
      surface: true,
      pressed,
      selected,
    });

    return html`
    <div class="${surfaceClasses}" ${ripple(() => this.ripple)}>
      ${this.renderRipple()}
      <div class="content">
        ${this.leadingContent()}  
        <slot></slot>
      </div>
    </div>
    `;
  }

  protected leadingContent(): TemplateResult {
    const { leadingIcons } = this;
    const classes: ClassInfo = {
      'leading': true,
      visible: !!this.selected || !!leadingIcons.length,
    }
    return html`
    <div class="${classMap(classes)}">
      ${this.renderLeadingIcon()}
      ${this.renderChecked()}
    </div>
    `;
  }

  protected renderLeadingIcon(): TemplateResult {
    const { leadingIcons } = this;
    const classes: ClassInfo = {
      'leading-icon': true,
      'with-icon': !!leadingIcons.length,
      hidden: !!this.selected,
    }
    return html`
    <div class="${classMap(classes)}"><slot name="icon" @slotchange="${this.handleIconSlotChange}"></slot></div>
    `;
  }

  protected renderChecked(): TemplateResult {
    const iconClasses = classMap({
      'check-mark': true,
      checked: !!this.selected,
    });
    return html`<span class="${iconClasses}" role="presentation">${check}</span>`;
  }

  protected renderRipple = (): TemplateResult => {
    const { disabled } = this;
    return html`<ui-ripple class="ripple" ?disabled="${disabled}"></ui-ripple>`;
  };
}
