import { mdiChevronUp } from "@mdi/js";
import type { TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import "../ha-icon-button";

@customElement("ha-automation-row")
export class HaAutomationRow extends LitElement {
  @property({ attribute: "left-chevron", type: Boolean })
  public leftChevron = false;

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

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

  @property({ type: Boolean, reflect: true, attribute: "sort-selected" })
  public sortSelected = false;

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

  @property({ type: Boolean, reflect: true, attribute: "building-block" })
  public buildingBlock = false;

  @property({ type: Boolean, reflect: true }) public highlight?: boolean;

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

  @query(".row")
  private _rowElement?: HTMLDivElement;

  protected render(): TemplateResult {
    return html`
      <div
        class="row"
        tabindex="0"
        role="button"
        @keydown=${this._handleKeydown}
      >
        ${
          this.leftChevron
            ? html`
                <ha-icon-button
                  class="expand-button"
                  .path=${mdiChevronUp}
                  @click=${this._handleExpand}
                  @keydown=${this._handleExpand}
                ></ha-icon-button>
              `
            : nothing
        }
        <div class="leading-icon-wrapper">
          <slot name="leading-icon"></slot>
        </div>
        <div class="header">
          <slot name="header"></slot>
          <slot name="event"></slot>
        </div>

        <div class="icons">
          <slot name="icons"></slot>
        </div>
      </div>
    `;
  }

  private async _handleExpand(ev) {
    if (ev.defaultPrevented) {
      return;
    }
    if (ev.type === "keydown" && ev.key !== "Enter" && ev.key !== " ") {
      return;
    }
    ev.stopPropagation();
    ev.preventDefault();

    fireEvent(this, "toggle-collapsed");
  }

  private async _handleKeydown(ev: KeyboardEvent): Promise<void> {
    if (ev.defaultPrevented) {
      return;
    }

    if (
      ev.key !== "Enter" &&
      ev.key !== " " &&
      !(
        (this.sortSelected || ev.altKey) &&
        !(ev.ctrlKey || ev.metaKey) &&
        !ev.shiftKey &&
        (ev.key === "ArrowUp" || ev.key === "ArrowDown")
      )
    ) {
      return;
    }
    ev.preventDefault();
    ev.stopPropagation();

    if (ev.key === "ArrowUp" || ev.key === "ArrowDown") {
      if (ev.key === "ArrowUp") {
        fireEvent(this, "move-up");
        return;
      }
      fireEvent(this, "move-down");
      return;
    }
    if (this.sortSelected && (ev.key === "Enter" || ev.key === " ")) {
      fireEvent(this, "stop-sort-selection");
      return;
    }

    this.click();
  }

  public focus() {
    requestAnimationFrame(() => {
      this._rowElement?.focus();
    });
  }

  static styles = css`
    :host {
      display: block;
      position: relative;
    }
    .row {
      display: flex;
      padding-left: var(--ha-space-3);
      padding-inline-start: var(--ha-space-3);
      padding-inline-end: initial;
      min-height: 48px;
      align-items: flex-start;
      cursor: pointer;
      overflow: hidden;
      outline: none;
      border-radius: var(--ha-card-border-radius, var(--ha-border-radius-lg));
    }
    .row:focus {
      outline: var(--wa-focus-ring);
      outline-offset: -2px;
    }
    .expand-button {
      transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
      color: var(--ha-color-on-neutral-quiet);
      margin-left: calc(var(--ha-space-2) * -1);
      margin-inline-start: calc(var(--ha-space-2) * -1);
      margin-inline-end: initial;
    }
    :host([building-block]) .leading-icon-wrapper {
      background-color: var(--ha-color-fill-neutral-loud-resting);
      border-radius: var(--ha-border-radius-md);
      padding: var(--ha-space-1);
      margin-top: 10px;
      display: flex;
      justify-content: center;
      align-items: center;
      transform: rotate(45deg);
    }
    .leading-icon-wrapper {
      padding-top: var(--ha-space-3);
      position: relative;
      z-index: 1;
    }
    ::slotted([slot="leading-icon"]) {
      color: var(--ha-color-on-neutral-quiet);
    }
    :host([building-block]) ::slotted([slot="leading-icon"].action-icon),
    :host([building-block]) ::slotted(#condition-icon) {
      --mdc-icon-size: var(--ha-space-5);
      color: var(--white-color);
      transform: rotate(-45deg);
    }
    :host([collapsed]) .expand-button {
      transform: rotate(180deg);
    }
    :host([selected]) .row,
    :host([selected]) .row:focus {
      outline: solid;
      outline-color: var(--primary-color);
      outline-offset: -2px;
      outline-width: 2px;
    }
    :host([disabled]) .row {
      border-top-right-radius: var(--ha-border-radius-square);
      border-top-left-radius: var(--ha-border-radius-square);
    }
    .header {
      position: relative;
      display: flex;
      align-items: center;
      flex: 1;
      min-width: 0;
      overflow-wrap: anywhere;
    }
    ::slotted([slot="header"]) {
      overflow-wrap: anywhere;
      margin: 0 var(--ha-space-3);
    }
    ::slotted([slot="event"]) {
      position: absolute;
      inset-inline-end: 0;
    }
    .icons {
      display: flex;
      align-items: center;
      flex-shrink: 0;
    }
    :host([sort-selected]) .row {
      outline: solid;
      outline-color: rgba(var(--rgb-accent-color), 0.6);
      outline-offset: -2px;
      outline-width: 2px;
      background-color: rgba(var(--rgb-accent-color), 0.08);
    }
    .row:hover {
      background-color: rgba(var(--rgb-primary-text-color), 0.04);
    }
    :host([highlight]) .row {
      background-color: rgba(var(--rgb-primary-color), 0.08);
    }
    :host([highlight]) .row:hover {
      background-color: rgba(var(--rgb-primary-color), 0.16);
    }

    .icons,
    .leading-icon-wrapper,
    ::slotted([slot="header"]) {
      transition: opacity var(--ha-animation-duration-normal);
      opacity: 1;
    }

    :host([dim]) .icons,
    :host([dim]) .leading-icon-wrapper,
    :host([dim]) ::slotted([slot="header"]) {
      opacity: 0.5;
    }
  `;
}

declare global {
  interface HTMLElementTagNameMap {
    "ha-automation-row": HaAutomationRow;
  }

  interface HASSDomEvents {
    "toggle-collapsed": undefined;
    "stop-sort-selection": undefined;
    "copy-row": undefined;
    "cut-row": undefined;
    "delete-row": undefined;
  }
}
