import { html, SVGTemplateResult, TemplateResult, nothing } from 'lit'
import { queryAsync, state } from 'lit/decorators.js'
import { classMap } from 'lit/directives/class-map.js'
import { when } from 'lit/directives/when.js'
import CheckedElement from './CheckedElement.js'
import { check, checkIndeterminate } from '../../icons/Icons.js'
import { ripple } from '../../effects/rippleDirective.js'
import UiRipple from '../../ripple/internals/ripple.js'
import '../../ripple/ui-ripple.js'

export default class CheckboxElement extends CheckedElement {
  protected get _icon(): SVGTemplateResult | typeof nothing {
    const { indeterminate, checked } = this
    if (indeterminate) {
      return checkIndeterminate
    }
    if (checked) {
      return check
    }
    return nothing
  }

  @queryAsync('ui-ripple') protected accessor ripple!: Promise<UiRipple | null>

  @state() protected accessor showRipple = false

  protected readonly getRipple = (): Promise<UiRipple | null> => {
    this.showRipple = true
    return this.ripple
  }

  protected override async handleFocus(): Promise<void> {
    const _ripple = await this.getRipple()
    _ripple?.beginFocus()
  }

  protected override async handleBlur(): Promise<void> {
    const _ripple = await this.getRipple()
    _ripple?.endFocus()
  }

  override async handleKeyDown(e: KeyboardEvent): Promise<void> {
    super.handleKeyDown(e)
    if (['Space'].includes(e.code)) {
      const _ripple = await this.getRipple()
      _ripple?.beginPress()
    }
  }

  override async handleKeyUp(e: KeyboardEvent): Promise<void> {
    super.handleKeyUp(e)
    if (['Space'].includes(e.code)) {
      const _ripple = await this.getRipple()
      _ripple?.endPress()
    }
  }

  protected override render(): TemplateResult {
    const { pressed = false } = this
    const containerClasses = classMap({
      surface: true,
      pressed,
    })
    return html`
      <div class="${containerClasses}" ${ripple(this.getRipple)}>
        <div class="container"></div>
        <div class="state"></div>
        ${when(this.showRipple, this.renderRipple)}
        <div class="icon">${this._icon}</div>
      </div>
    `
  }

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