import { mdiPlay, mdiStop } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import type { CSSResultGroup } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import { supportsFeature } from "../../../../common/entity/supports-feature";
import "../../../../components/ha-button";
import "../../../../components/ha-control-button";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-list-item";
import "../../../../components/ha-select";
import type { HaSelectSelectEvent } from "../../../../components/ha-select";
import "../../../../components/input/ha-input";
import { SirenEntityFeature } from "../../../../data/siren";
import { haStyle } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";

@customElement("ha-more-info-siren-advanced-controls")
class MoreInfoSirenAdvancedControls extends LitElement {
  @property({ attribute: false }) public hass!: HomeAssistant;

  @state() _stateObj?: HassEntity;

  @state() private _open = false;

  @state() _tone?: string;

  @state() _volume?: number;

  @state() _duration?: number;

  public showDialog({ stateObj }: { stateObj: HassEntity }) {
    this._stateObj = stateObj;
    this._open = true;
  }

  public closeDialog(): void {
    this._open = false;
  }

  private _dialogClosed(): void {
    this._open = false;
    this._stateObj = undefined;
    fireEvent(this, "dialog-closed", { dialog: this.localName });
  }

  render() {
    if (!this._stateObj) {
      return nothing;
    }
    const supportsTones =
      supportsFeature(this._stateObj, SirenEntityFeature.TONES) &&
      this._stateObj.attributes.available_tones;
    const supportsVolume = supportsFeature(
      this._stateObj,
      SirenEntityFeature.VOLUME_SET
    );
    const supportsDuration = supportsFeature(
      this._stateObj,
      SirenEntityFeature.DURATION
    );
    return html`
      <ha-dialog
        .open=${this._open}
        header-title=${this.hass.localize("ui.components.siren.more_controls")}
        @closed=${this._dialogClosed}
      >
        <div>
          <div class="options">
            ${supportsTones
              ? html`
                  <ha-select
                    .label=${this.hass.localize("ui.components.siren.tone")}
                    @selected=${this._handleToneChange}
                    .value=${this._tone}
                    .options=${Object.entries(
                      this._stateObj!.attributes.available_tones
                    ).map(([toneId, toneName]) => ({
                      value: Array.isArray(
                        this._stateObj!.attributes.available_tones
                      )
                        ? toneName
                        : toneId,
                      label: toneName,
                    }))}
                  >
                  </ha-select>
                `
              : nothing}
            ${supportsVolume
              ? html`
                  <ha-input
                    type="number"
                    .label=${this.hass.localize("ui.components.siren.volume")}
                    .value=${this._volume ? `${this._volume * 100}` : undefined}
                    @change=${this._handleVolumeChange}
                    .min=${0}
                    .max=${100}
                    .step=${1}
                  >
                    <span slot="end">%</span>
                  </ha-input>
                `
              : nothing}
            ${supportsDuration
              ? html`
                  <ha-input
                    type="number"
                    .label=${this.hass.localize("ui.components.siren.duration")}
                    .value=${this._duration !== undefined
                      ? this._duration.toString()
                      : undefined}
                    @change=${this._handleDurationChange}
                  >
                    <span slot="end">s</span>
                  </ha-input>
                `
              : nothing}
          </div>
          <div class="controls">
            <ha-control-button
              .label=${this.hass.localize("ui.card.common.turn_on")}
              @click=${this._turnOn}
            >
              <ha-svg-icon .path=${mdiPlay}></ha-svg-icon>
            </ha-control-button>
            <ha-control-button
              .label=${this.hass.localize("ui.card.common.turn_off")}
              @click=${this._turnOff}
            >
              <ha-svg-icon .path=${mdiStop}></ha-svg-icon>
            </ha-control-button>
          </div>
        </div>
        <ha-dialog-footer slot="footer">
          <ha-button
            slot="secondaryAction"
            appearance="plain"
            @click=${this.closeDialog}
          >
            ${this.hass.localize("ui.common.close")}
          </ha-button>
        </ha-dialog-footer>
      </ha-dialog>
    `;
  }

  private _handleToneChange(ev: HaSelectSelectEvent) {
    this._tone = ev.detail.value;
  }

  private _handleVolumeChange(ev) {
    this._volume = parseFloat(ev.target.value) / 100;
    if (isNaN(this._volume)) {
      this._volume = undefined;
    }
  }

  private _handleDurationChange(ev) {
    this._duration = parseInt(ev.target.value);
    if (isNaN(this._duration)) {
      this._duration = undefined;
    }
  }

  private async _turnOn() {
    await this.hass.callService("siren", "turn_on", {
      entity_id: this._stateObj!.entity_id,
      tone: this._tone,
      volume_level: this._volume,
      duration: this._duration,
    });
  }

  private async _turnOff() {
    await this.hass.callService("siren", "turn_off", {
      entity_id: this._stateObj!.entity_id,
    });
  }

  static get styles(): CSSResultGroup {
    return [
      haStyle,
      css`
        .options {
          display: flex;
          flex-direction: column;
          gap: var(--ha-space-4);
        }
        .controls {
          display: flex;
          flex-direction: row;
          justify-content: center;
          gap: var(--ha-space-4);
          margin-top: var(--ha-space-4);
        }
        ha-control-button {
          --control-button-border-radius: var(--ha-border-radius-xl);
          --mdc-icon-size: 24px;
          width: 64px;
          height: 64px;
        }
      `,
    ];
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "ha-more-info-siren-advanced-controls": MoreInfoSirenAdvancedControls;
  }
}
