import { consume, type ContextType } from "@lit/context";
import {
  mdiBrightness6,
  mdiCreation,
  mdiFileWordBox,
  mdiLightbulbOff,
  mdiLightbulbOn,
  mdiPower,
} from "@mdi/js";
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { consumeLocalize } from "../../../common/decorators/consume-context-entry";
import { supportsFeature } from "../../../common/entity/supports-feature";
import type { LocalizeFunc } from "../../../common/translations/localize";
import "../../../components/ha-attribute-icon";
import "../../../components/ha-control-select-menu";
import "../../../components/ha-icon-button-group";
import "../../../components/ha-icon-button-toggle";
import "../../../components/ha-list-item";
import { UNAVAILABLE } from "../../../data/entity/entity";
import {
  shouldShowFavoriteOptions,
  type ExtEntityRegistryEntry,
} from "../../../data/entity/entity_registry";
import { forwardHaptic } from "../../../data/haptics";
import type { LightEntity } from "../../../data/light";
import {
  LightColorMode,
  LightEntityFeature,
  lightSupportsBrightness,
  lightSupportsColor,
  lightSupportsColorMode,
  lightSupportsFavoriteColors,
} from "../../../data/light";
import "../../../state-control/ha-state-control-toggle";
import "../../../state-control/light/ha-state-control-light-brightness";
import { apiContext, formattersContext } from "../../../data/context";
import "../components/ha-more-info-control-select-container";
import "../components/ha-more-info-state-header";
import "../components/lights/ha-favorite-color-button";
import "../components/lights/ha-more-info-light-favorite-colors";
import "../components/lights/light-color-rgb-picker";
import "../components/lights/light-color-temp-picker";
import { moreInfoControlStyle } from "../components/more-info-control-style";
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";

type MainControl = "brightness" | "color_temp" | "color";

@customElement("more-info-light")
class MoreInfoLight extends LitElement {
  @state()
  @consumeLocalize()
  private _localize!: LocalizeFunc;

  @state()
  @consume({ context: formattersContext, subscribe: true })
  private _formatters!: ContextType<typeof formattersContext>;

  @state()
  @consume({ context: apiContext, subscribe: true })
  private _api!: ContextType<typeof apiContext>;

  @property({ attribute: false }) public stateObj?: LightEntity;

  @property({ attribute: false }) public entry?: ExtEntityRegistryEntry | null;

  @property({ attribute: false }) public editMode?: boolean;

  @state() private _effect?: string;

  @state() private _mainControl: MainControl = "brightness";

  private _renderEffectIcon = (value: string) =>
    html`<ha-attribute-icon
      .stateObj=${this.stateObj}
      attribute="effect"
      .attributeValue=${value}
    ></ha-attribute-icon>`;

  protected updated(changedProps: PropertyValues<this>): void {
    if (changedProps.has("stateObj")) {
      this._effect = this.stateObj?.attributes.effect;
    }
  }

  private _setMainControl(ev: any) {
    ev.stopPropagation();
    this._mainControl = ev.currentTarget.control;
  }

  private _resetMainControl(ev: any) {
    ev.stopPropagation();
    this._mainControl = "brightness";
  }

  private get _stateOverride() {
    if (this.stateObj?.attributes.brightness) {
      return this._formatters.formatEntityAttributeValue(
        this.stateObj!,
        "brightness"
      );
    }
    return undefined;
  }

  protected render() {
    if (!this.stateObj) {
      return nothing;
    }

    const supportsColorTemp = lightSupportsColorMode(
      this.stateObj,
      LightColorMode.COLOR_TEMP
    );

    const supportsColor = lightSupportsColor(this.stateObj);

    const supportsBrightness = lightSupportsBrightness(this.stateObj);

    const supportsWhite = lightSupportsColorMode(
      this.stateObj,
      LightColorMode.WHITE
    );

    const supportsEffects = supportsFeature(
      this.stateObj,
      LightEntityFeature.EFFECT
    );

    const showFavoriteColors = Boolean(
      this.entry &&
      (this.editMode ||
        (lightSupportsFavoriteColors(this.stateObj) &&
          shouldShowFavoriteOptions(
            this.entry.options?.light?.favorite_colors
          )))
    );

    return html`
      <ha-more-info-state-header
        .stateObj=${this.stateObj}
        .stateOverride=${this._stateOverride}
      ></ha-more-info-state-header>
      <div class="controls">
        ${
          !supportsBrightness
            ? html`
                <ha-state-control-toggle
                  .stateObj=${this.stateObj}
                  .iconPathOn=${mdiLightbulbOn}
                  .iconPathOff=${mdiLightbulbOff}
                ></ha-state-control-toggle>
              `
            : nothing
        }
        ${
          supportsColorTemp || supportsColor || supportsBrightness
            ? html`
                ${
                  supportsBrightness && this._mainControl === "brightness"
                    ? html`
                        <ha-state-control-light-brightness
                          .stateObj=${this.stateObj}
                        >
                        </ha-state-control-light-brightness>
                      `
                    : nothing
                }
                ${
                  supportsColor && this._mainControl === "color"
                    ? html`
                        <light-color-rgb-picker .stateObj=${this.stateObj}>
                        </light-color-rgb-picker>
                      `
                    : nothing
                }
                ${
                  supportsColorTemp && this._mainControl === "color_temp"
                    ? html`
                        <light-color-temp-picker .stateObj=${this.stateObj}>
                        </light-color-temp-picker>
                      `
                    : nothing
                }
                <ha-icon-button-group>
                  ${
                    supportsBrightness
                      ? html`
                          <ha-icon-button
                            .disabled=${this.stateObj!.state === UNAVAILABLE}
                            .label=${this._localize(
                              "ui.dialogs.more_info_control.light.toggle"
                            )}
                            @click=${this._toggle}
                          >
                            <ha-svg-icon .path=${mdiPower}></ha-svg-icon>
                          </ha-icon-button>
                        `
                      : nothing
                  }
                  ${
                    supportsColor || supportsColorTemp
                      ? html`
                          <div class="separator"></div>
                          <ha-icon-button-toggle
                            .selected=${this._mainControl === "brightness"}
                            .disabled=${this.stateObj!.state === UNAVAILABLE}
                            .label=${this._formatters.formatEntityAttributeName(
                              this.stateObj,
                              "brightness"
                            )}
                            .control=${"brightness"}
                            @click=${this._setMainControl}
                          >
                            <ha-svg-icon .path=${mdiBrightness6}></ha-svg-icon>
                          </ha-icon-button-toggle>
                        `
                      : nothing
                  }
                  ${
                    supportsColor
                      ? html`
                          <ha-icon-button-toggle
                            border-only
                            .selected=${this._mainControl === "color"}
                            .disabled=${this.stateObj!.state === UNAVAILABLE}
                            .label=${this._localize(
                              "ui.dialogs.more_info_control.light.color"
                            )}
                            .control=${"color"}
                            @click=${this._setMainControl}
                          >
                            <span class="wheel color"></span>
                          </ha-icon-button-toggle>
                        `
                      : nothing
                  }
                  ${
                    supportsColorTemp
                      ? html`
                          <ha-icon-button-toggle
                            border-only
                            .selected=${this._mainControl === "color_temp"}
                            .disabled=${this.stateObj!.state === UNAVAILABLE}
                            .label=${this._localize(
                              "ui.dialogs.more_info_control.light.color_temp"
                            )}
                            .control=${"color_temp"}
                            @click=${this._setMainControl}
                          >
                            <span class="wheel color-temp"></span>
                          </ha-icon-button-toggle>
                        `
                      : nothing
                  }
                  ${
                    supportsWhite
                      ? html`
                          <div class="separator"></div>
                          <ha-icon-button
                            .disabled=${this.stateObj!.state === UNAVAILABLE}
                            .label=${this._localize(
                              "ui.dialogs.more_info_control.light.set_white"
                            )}
                            @click=${this._setWhite}
                          >
                            <ha-svg-icon .path=${mdiFileWordBox}></ha-svg-icon>
                          </ha-icon-button>
                        `
                      : nothing
                  }
                </ha-icon-button-group>
                ${
                  showFavoriteColors
                    ? html`
                        <ha-more-info-light-favorite-colors
                          .stateObj=${this.stateObj}
                          .entry=${this.entry}
                          .editMode=${this.editMode}
                          @favorite-color-edit-started=${this._resetMainControl}
                        >
                        </ha-more-info-light-favorite-colors>
                      `
                    : nothing
                }
              `
            : nothing
        }
      </div>
      <div>
        <ha-more-info-control-select-container>
          ${
            supportsEffects && this.stateObj.attributes.effect_list
              ? html`
                  <ha-control-select-menu
                    .label=${this._formatters.formatEntityAttributeName(
                      this.stateObj,
                      "effect"
                    )}
                    .value=${this.stateObj.attributes.effect}
                    .disabled=${this.stateObj.state === UNAVAILABLE}
                    @wa-select=${this._handleEffect}
                    .options=${this.stateObj.attributes.effect_list.map(
                      (effect) => ({
                        value: effect,
                        label: this.stateObj
                          ? this._formatters.formatEntityAttributeValue(
                              this.stateObj,
                              "effect",
                              effect
                            )
                          : effect,
                      })
                    )}
                    .renderIcon=${this._renderEffectIcon}
                  >
                    <ha-svg-icon slot="icon" .path=${mdiCreation}></ha-svg-icon>
                  </ha-control-select-menu>
                `
              : nothing
          }
        </ha-more-info-control-select-container>
      </div>
    `;
  }

  private _toggle = () => {
    const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on";
    forwardHaptic(this, "light");
    this._api.callService("light", service, {
      entity_id: this.stateObj!.entity_id,
    });
  };

  private _setWhite = () => {
    this._api.callService("light", "turn_on", {
      entity_id: this.stateObj!.entity_id,
      white: true,
    });
  };

  private _handleEffect(ev: HaDropdownSelectEvent) {
    const newVal = ev.detail.item.value;
    const oldVal = this._effect;

    if (!newVal || oldVal === newVal) return;

    this._api.callService("light", "turn_on", {
      entity_id: this.stateObj!.entity_id,
      effect: newVal,
    });
  }

  static get styles(): CSSResultGroup {
    return [
      moreInfoControlStyle,
      css`
        .button-bar {
          display: flex;
          flex-direction: row;
          align-items: center;
          height: 48px;
          border-radius: var(--ha-border-radius-3xl);
          background-color: rgba(139, 145, 151, 0.1);
          box-sizing: border-box;
          width: auto;
        }
        .wheel {
          width: 30px;
          height: 30px;
          flex: none;
          border-radius: var(--ha-border-radius-xl);
        }
        .wheel.color {
          background-image: url("/static/images/color_wheel.png");
          background-size: cover;
        }
        .wheel.color-temp {
          background: linear-gradient(
            0,
            rgb(166, 209, 255) 0%,
            white 50%,
            rgb(255, 160, 0) 100%
          );
        }
        *[disabled] .wheel {
          filter: grayscale(1) opacity(0.5);
        }
        .buttons {
          flex-wrap: wrap;
          max-width: 250px;
        }
      `,
    ];
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "more-info-light": MoreInfoLight;
  }
}
